Skip to content

WIP - tightening homebrew process#17405

Draft
radical wants to merge 4 commits into
microsoft:mainfrom
radical:homebrew-pipeline-hardening
Draft

WIP - tightening homebrew process#17405
radical wants to merge 4 commits into
microsoft:mainfrom
radical:homebrew-pipeline-hardening

Conversation

@radical
Copy link
Copy Markdown
Member

@radical radical commented May 23, 2026

WIP - tightening homebrew process

radical and others added 4 commits May 22, 2026 23:14
PR #265387 to Homebrew/homebrew-cask failed the `syntax (macos-26)`
upstream CI job with:

  Invalid cask (Linux on Intel x86_64): Casks/a/aspire.rb
  Invalid cask (Linux on ARM64):       Casks/a/aspire.rb

That job runs `brew test-bot --only-tap-syntax`, which evaluates every
cask in the tap on every supported platform. The cask's `arch` hash
only contains keys for macOS architectures (`arm: "arm64"`,
`intel: "x64"`), so when the validator tried to load it on Linux there
was no value for `arch` and the load failed.

Aspire CLI is only published for macOS via Homebrew cask (Linux
distribution does not go through Homebrew), so declare the constraint
explicitly with `depends_on :macos`. This is the symbol form documented
in the Cask Cookbook for macOS-only casks with no minimum version
requirement, and it is what binary-only casks like `p4` and `truetree`
use upstream.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three related changes to validate-cask-artifact.sh so the prepare-stage
validation matches the checks that Homebrew/homebrew-cask CI actually
runs on a PR:

1. Add `brew test-bot --tap local/aspire --only-tap-syntax` after the
   `brew style` step. This is the upstream check that fired on
   PR #265387 with "Invalid cask (Linux on ...)" — the same command,
   run locally before submission, catches that class of cross-platform
   cask-load failure before it reaches an upstream PR.

2. Drop the new-cask flow. The pipeline only submits version bumps for
   an already-merged upstream cask; first-time submissions are handled
   manually. Remove the `detect_upstream_cask_is_new` function (which
   probed api.github.com/.../contents and was rate-limit-prone), the
   `IS_NEW_CASK` variable, the conditional `--new` audit arg, and the
   `isNewCask` field in validation-summary.json. Bump the summary
   schemaVersion to 2 so any stale `schemaVersion: 1` artifact carrying
   the old shape will be rejected by the publish stage.

3. Tighten audit flags to match what upstream's
   `brew generate-cask-ci-matrix` produces for an existing-cask audit:
   `brew audit --cask --online --signing`. Verified by inspecting the
   actual `Run brew audit ...` log line from
   Homebrew/homebrew-cask:.github/workflows/ci.yml on PR #265387's
   `test aspire (macos-N, arch)` jobs. Offline mode keeps the existing
   `--no-signing` so it can audit against the local archive HTTP server
   without failing the macOS notarization check.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the ~400-line hand-built REST submission flow in
publish-homebrew.yml with `brew bump-cask-pr`, the canonical Homebrew
tool for cask version bumps. The bumper handles fork creation, branch
naming, the conventional `<cask> <version>` commit message, the
conventional PR title and body, and upstream rate limiting — none of
which the previous hand-built code did correctly, and some of which it
got wrong in ways that contributed to the PR #265387 maintainer
response.

Three coordinated changes are in this commit because they share the
same submit-step script:

1. **Switch to `brew bump-cask-pr`.** The previous PowerShell flow did
   its own fork detection, branch creation via `PUT /contents`,
   PR-already-open detection, draft-conversion via GraphQL, and
   superseded-PR tracking — all of which are duplicating logic the
   bumper already handles. It also emitted a templated PR body with
   a "Validation performed by Aspire CI before submission" checklist
   whose top item ("stable version or documented exception") rendered
   as unchecked on prerelease submissions; that body shape was visible
   on PR #265387 immediately before closure. The bumper produces the
   normal Homebrew PR shape that maintainers expect to see from any
   contributor. The hand-built `Get-HomebrewPullRequestBody` function
   is removed entirely.

2. **Repurpose `dryRun`.** The parameter now defaults to `true`
   (callers must explicitly opt in to opening a real upstream PR) and
   gates between two paths through the same submit step:

     - dryRun=true: `brew bump-cask-pr --write-only --commit --no-fork`
       produces the bump diff and the conventional commit locally
       without contacting GitHub. The dry-run logs the resulting
       `git show HEAD` so the operator can review exactly what the
       real submission would do.
     - dryRun=false: `brew bump-cask-pr --version=<v> aspire` submits
       to upstream.

   `--sha256` is intentionally not passed: the flag has no per-arch
   form, so for multi-arch casks the bumper emits "Multiple checksum
   replacements required; ignoring specified `--sha256` argument" and
   falls back to downloading the binaries to compute checksums itself.
   This matches the pattern used by `Homebrew/actions:bump-packages`.

3. **Hard-fail non-stable / non-production for real submissions.**
   When dryRun=false, the script refuses to run if the validation
   summary reports isStableRelease=false or if _IsProductionBranch is
   not true. Belt-and-suspenders on top of the existing artifact-name
   gate that already restricts prerelease channels from reaching the
   publish stage — the new hard-fail makes a manually-invoked
   publish-template from a feature branch with dryRun=false fail
   loudly instead of attempting to submit.

The earlier validate-summary step is also updated to require
`schemaVersion: 2` and the new `tapSyntax` check produced by the
prepare-stage hardening in the preceding commit, so any stale
schemaVersion-1 artifact is rejected at publish time.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bring eng/homebrew/README.md in sync with the prepare- and publish-stage
changes that landed in the preceding commits:

- Document `brew bump-cask-pr` as the submission tool (replacing the
  hand-built REST flow whose 6-step explanation no longer matched the
  code).
- Document the `dryRun` parameter's new semantics — default `true`,
  callers must explicitly opt in to a real upstream PR — and the
  defence-in-depth gates that hard-fail real submissions from
  non-production branches or non-stable channels.
- Note that the pipeline only handles version bumps; the initial cask
  submission to `Homebrew/homebrew-cask` is a one-time human-driven
  operation.
- Replace the stale prepare-stage validation list with the current
  five-step flow including `brew test-bot --only-tap-syntax` and the
  upstream-matching `brew audit --cask --online --signing` flags.
- Note `depends_on :macos` on the cask and why it is needed for
  tap-level cross-platform syntax validation.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17405

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17405"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant