From dc4541b9a3954e71c8b619f28dd896214a03731f Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 3 Oct 2026 17:02:54 +0000 Subject: [PATCH] Publish Homebrew formula updates automatically on release Replace the manual Homebrew instructions step with a `homebrew` job that, after a successful release, opens a `brew bump-formula-pr` PR in Homebrew/homebrew-core (like apify-cli does) and dispatches the apify/homebrew-tap update workflow. Refs https://github.com/apify/homebrew-tap/pull/55#issuecomment-5202806509 Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0135Q44n1nwgbLtDHnERNHDr --- .github/workflows/release.yml | 77 +++++++++++++++++++++++------------ CLAUDE.md | 5 ++- 2 files changed, 55 insertions(+), 27 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5a92a489..9656c619 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -63,6 +63,8 @@ jobs: name: Publish ${{ inputs.type }} runs-on: ubuntu-latest needs: [e2e-windows, e2e-macos, e2e-linux, conformance] + outputs: + version: ${{ steps.release.outputs.version }} # Release must be from main; pre-release can be from any branch. # Allow the e2e-windows and e2e-macos dependencies to be either successful # or skipped (when the user opts out via skip-windows-e2e / skip-macos-e2e). @@ -340,30 +342,55 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} - # ── Homebrew tap ─────────────────────────────────────────────── - - name: Homebrew formula update instructions - if: inputs.type == 'release' - # The formula bump in apify/homebrew-tap is started by hand for now, so - # this step only prints the command — it deliberately does not dispatch - # anything. To automate it later, run the printed command in this step - # (with GH_TOKEN: secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN) and keep it - # last and continue-on-error, so a Homebrew hiccup can never fail a - # release that is already tagged, published to npm and announced. - # - # The dispatched workflow points Formula/mcpc.rb at the new npm tarball, - # installs and `brew test`s it on Linux and macOS, then merges the bump. - # It polls the registry itself, so it tolerates publish propagation. - continue-on-error: true + homebrew: + name: Update Homebrew formulae + # Runs as its own job after the release is tagged, published to npm and + # announced, so a Homebrew hiccup can never fail or roll back the release. + needs: release + if: inputs.type == 'release' && needs.release.result == 'success' + runs-on: ubuntu-latest + env: + VERSION: ${{ needs.release.outputs.version }} + steps: + - name: Wait for the version to be available on npm + id: wait + # The registry can lag a few minutes behind `pnpm publish`. + run: | + for _i in {1..30}; do + curl -sf "https://registry.npmjs.org/@apify/mcpc/${VERSION}" > /dev/null && exit 0 + echo "@apify/mcpc@${VERSION} is not available on npm yet, retrying in 10 seconds." + sleep 10 + done + curl -sf "https://registry.npmjs.org/@apify/mcpc/${VERSION}" > /dev/null + + - name: Set git identity + run: | + git config --global user.name 'Apify Service Account' + git config --global user.email 'apify-service-account@users.noreply.github.com' + + - name: Set up Homebrew + uses: Homebrew/actions/setup-homebrew@f8d4222eb633e65c2a0157383cf80861fc7fae7f # master + + - name: Open formula bump PR in Homebrew/homebrew-core + # `brew install mcpc`. Forks homebrew-core under the service account and + # opens a PR pointing Formula/m/mcpc.rb at the new npm tarball; Homebrew's + # CI builds, tests and bottles it, and a Homebrew maintainer merges it. + run: | + brew tap --force homebrew/core + brew bump-formula-pr homebrew/core/mcpc \ + --version "${VERSION}" \ + --no-browse \ + --message "Automatic update of the \`mcpc\` formula. CC @jancurn" env: - VERSION: ${{ steps.release.outputs.version }} + HOMEBREW_GITHUB_API_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} + + - name: Update formula in apify/homebrew-tap + # `brew install apify/tap/mcpc`. The dispatched workflow points + # Formula/mcpc.rb at the new npm tarball, installs and `brew test`s it on + # Linux and macOS, then merges the bump. + if: ${{ !cancelled() && steps.wait.outcome == 'success' }} run: | - { - echo "### Homebrew" - echo "" - echo "The formula bump is manual for now. To ship \`${VERSION}\` to \`brew\`, run:" - echo "" - echo '```bash' - echo "gh workflow run update_formula.yaml --repo apify/homebrew-tap \\" - echo " --field package=mcpc --field npm_package=@apify/mcpc --field version=${VERSION}" - echo '```' - } | tee -a "$GITHUB_STEP_SUMMARY" + gh workflow run update_formula.yaml --repo apify/homebrew-tap \ + --field package=mcpc --field npm_package=@apify/mcpc --field version="${VERSION}" + env: + GH_TOKEN: ${{ secrets.APIFY_SERVICE_ACCOUNT_GITHUB_TOKEN }} diff --git a/CLAUDE.md b/CLAUDE.md index 60c1a19b..1e757847 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -819,14 +819,15 @@ The script validates preconditions locally (including `pnpm run check:deps-age`, `pnpm-workspace.yaml` sets `minimumReleaseAge` to keep freshly-published (potentially compromised) packages out of the tree, but pnpm applies it only when *resolving* new versions — pnpm 10 does not re-check an existing lockfile on a `--frozen-lockfile` install (that landed in pnpm 11). `scripts/check-dependency-age.mjs` closes that gap: it reads the publish time of every version pinned in `pnpm-lock.yaml` and fails the release if anything is too young. Packages listed in `minimumReleaseAgeExclude` get a shorter 48-hour floor instead of a free pass. The check fails closed — a registry error is a failure, never a skip. Remove the script once the repo moves to pnpm ≥ 11 and native lockfile age verification covers it. -The Homebrew formula lives in [apify/homebrew-tap](https://github.com/apify/homebrew-tap), not here, and its bump is **started manually for now** — the release workflow only prints the command in its run summary: +Homebrew formulae live outside this repo, in [Homebrew/homebrew-core](https://github.com/Homebrew/homebrew-core/blob/main/Formula/m/mcpc.rb) (`brew install mcpc`) and [apify/homebrew-tap](https://github.com/apify/homebrew-tap) (`brew install apify/tap/mcpc`). After a release, the `homebrew` job in `release.yml` updates both: it runs `brew bump-formula-pr` to open a version-bump PR in homebrew-core (merged by Homebrew maintainers once their CI passes) and dispatches the tap's `update_formula.yaml`. It runs as a separate job, so a failure there never affects the npm release; to retry by hand: ```bash +brew bump-formula-pr mcpc --version gh workflow run update_formula.yaml --repo apify/homebrew-tap \ --field package=mcpc --field npm_package=@apify/mcpc --field version= ``` -That workflow points `Formula/mcpc.rb` at the new npm tarball, installs and `brew test`s it on Linux and macOS, and merges the bump. Skipping it only leaves Homebrew users on the previous version; npm and Bun installs are unaffected. +Skipping it only leaves Homebrew users on the previous version; npm and Bun installs are unaffected. For pre-releases: `pnpm run release:pre` (or `pnpm run release:pre -- minor`)