Skip to content

Pin GoReleaser and gate the generated Homebrew cask in CI - #511

Merged
joe4dev merged 1 commit into
mainfrom
devx-1124-guard-generated-homebrew-cask
Sep 23, 2026
Merged

joe4dev merged 1 commit into
mainfrom
devx-1124-guard-generated-homebrew-cask

Conversation

@joe4dev

@joe4dev joe4dev commented Sep 21, 2026 •

Copy link
Copy Markdown
Member

Motivation

Nothing in this repo reads the generated Homebrew cask. Only a release writes it, and it lands in a tap with no CI, so a bad cask first surfaces as a user's brew install. That is how the deprecated postflight stanza shipped and survived two releases (#510, localstack/homebrew-tap#7).

Two things made that possible, and this PR closes both.

Solution

Pin GoReleaser. version: "~> v2" floated, so a GoReleaser minor could change the published cask with no change in this repo. .tool-versions now pins goreleaser 2.18.2, and both the check and release jobs read it through the action's version-file: — the same pattern the repo already uses for golangci-lint. A version bump becomes a reviewable diff, and mise/asdf users get the pinned version locally. scripts/check-cask.sh enforces the same pin, as make lint does for golangci-lint.

Gate the cask, in two halves. make check-cask renders it through a snapshot release and asserts what we care about: no deprecated raw-Ruby flight stanza, the quarantine step survives, it targets the whole staged dir with {{staged_path}} intact. Runs last in goreleaser-check, after the cheap checks, ~165s.

make lint-cask then runs Homebrew's own linters, which catch deprecations nobody here thought to look for — Cask/InstallSteps is the cop that flags the stanza #510 fixed. brew style and brew audit --cask, through a throwaway tap, since audit refuses a bare path and the cask cops only apply to a file under Casks/.

The two are split because Homebrew is not on the Linux runners, which I found the hard way on the first CI run here (brew required on PATH). So a new cask-lint job on macos-latest downloads the cask the Linux job rendered and lints those exact bytes, rather than rendering a second time that could diverge. It is deliberately not in the release job's needs: yet — the same staged rollout govulncheck is on.

The script stubs the bundle (fetch-bundled-extensions.sh --stub, per docs/extensions-bundling.md), since the bundled/ globs are live and the real fetch needs a private-repo token. The job gained setup-go and install-only: true, having never built anything before.

Temporarily skipped style checks

brew style runs with --except-cops=Cask/StanzaOrder. #510's custom_block renders the stanza at the top of the cask, so every stanza after it is reported out of order — 9 offences on the generated cask, all from that one cop.

The exception is scoped to that cop alone, and I verified it does not blind the gate: run against the old published cask, brew style --except-cops=Cask/StanzaOrder still fails with Cask/InstallSteps: Casks must use postflight_steps instead of postflight.

A TODO(#512) on the line records the removal. #512 moves the stanza to hooks.post.install_steps, which renders it in place — brew style is then clean with no exception, confirmed against a build of goreleaser/goreleaser#6873.

Validation

  • each assertion fails on its own mutation: a deprecated stanza, a deleted hook, a mangled token, an uninstall_postflight block
  • reverting Fix deprecated postflight stanza in the generated Homebrew cask #510's config under this guard fails the job
  • the pin check fails on a mismatch: goreleaser 2.99.0 required (found: 2.18.2)
  • the throwaway tap is removed on every exit path, including failures

Two gates, not one

This gate runs before a release exists, which bounds what it can see: a rendered cask's url points at an unpublished release and its sha256 are of locally built archives, so neither can be verified here. brew audit --online, the form that fetches every url and checks every checksum, is therefore impossible in this repo.

localstack/homebrew-tap#10 adds that missing half — the last check before users install, run against the artifact as published. The two are complementary:

lstk (this PR) tap#10
When every PR, pre-release on push to the tap, post-publish
Sees the cask our config will generate the cask users will install
Catches config regressions, template drift, a deprecated stanza broken urls, mismatched checksums, hand-edits to the tap

Worth knowing about brew audit here: offline it passes both the fixed and the deprecated cask, so it would not have caught this bug — brew style is what does. It is in this PR for other classes of fault.

Docs

Nothing to document. No new or changed command, flag, env var, or output. make check-cask is a contributor-facing target, covered by the script's own header; the GoReleaser pin is release tooling.

Review

Human review advised: it changes the release job's GoReleaser resolution and adds a build step to every PR.

Todo

Towards DEVX-1124

🤖 Generated with Claude Code

@joe4dev joe4dev added semver: patch docs: skip Pull request does not require documentation changes labels Sep 21, 2026
Base automatically changed from devx-1124-homebrew-cask-generated-tap-warning-switch-hookspostinstall to main September 22, 2026 10:01
@joe4dev
joe4dev force-pushed the devx-1124-guard-generated-homebrew-cask branch 2 times, most recently from 75fb741 to dd3f443 Compare September 22, 2026 10:39
@joe4dev joe4dev changed the title Check the generated Homebrew cask in CI Pin GoReleaser and gate the generated Homebrew cask in CI Sep 22, 2026
@joe4dev
joe4dev force-pushed the devx-1124-guard-generated-homebrew-cask branch 2 times, most recently from be579b7 to 607b035 Compare September 22, 2026 12:56
Co-Authored-By: Claude <noreply@anthropic.com>
@joe4dev
joe4dev force-pushed the devx-1124-guard-generated-homebrew-cask branch from 607b035 to 260bb75 Compare September 22, 2026 14:02
@joe4dev
joe4dev marked this pull request as ready for review September 22, 2026 16:04
@joe4dev
joe4dev requested review from a team and peter-smith-phd as code owners September 22, 2026 16:04

@anisaoshafi anisaoshafi left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking this measure to avoid similar future issues with goreleaser <> homebrew. LGTM! 🚀

@joe4dev
joe4dev merged commit ee7e517 into main Sep 23, 2026
34 checks passed
@joe4dev
joe4dev deleted the devx-1124-guard-generated-homebrew-cask branch September 23, 2026 14:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs: skip Pull request does not require documentation changes semver: patch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants