fix(release): stop the Homebrew cask's postflight deprecation warning - #27
Merged
Merged
Conversation
Homebrew 7.0 deprecated the `postflight` stanza in favour of the declarative `postflight_steps`, so every `brew` command touching the cask printed Warning: Calling `postflight` is deprecated! Use `postflight_steps` instead. and Homebrew deprecations become hard errors a few releases later. The stanza is the cask's quarantine strip, which the unsigned binary needs to launch on macOS, so it cannot simply be dropped. GoReleaser generates `postflight` from `homebrew_casks.hooks.post.install` and cannot emit the `*_steps` stanzas yet (goreleaser/goreleaser#6870, PR #6873, milestone v2.19.0), so write the stanza directly through `custom_block` instead. Two details are load-bearing and documented next to the block: the Homebrew path token is escaped as `{{ "{{staged_path}}" }}` because GoReleaser runs the whole generated cask through its template engine as a final pass, and the steps DSL has no Ruby interpolation, so `run` takes the expanded token as an argument. Placement right after `cask "koc" do` is safe because Homebrew orders artifacts by class (Binary before PostflightSteps), not by file position. Verified by building GoReleaser from source and running a snapshot release: the generated cask carries `postflight_steps`, the literal `{{staged_path}}` token survives the template pass, and the file is valid Ruby. The cask now requires Homebrew >= 7.0, which README and AGENTS.md note. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0122vGrcATX7433WuQ91iLm9
The previous commit moved the quarantine strip to `postflight_steps`
unconditionally, which silences the deprecation warning but raises on any
Homebrew that predates the stanza. Pick the spelling at load time instead:
`postflight_steps` where it works, the original `postflight` block below
that. The cask now installs on every Homebrew and warns on none.
Three versions matter, and they are three releases apart, which is why the
obvious probe is wrong:
6.0.0 the postflight_steps stanza lands
6.0.13 the steps DSL gains the run/on_macos steps the block calls
6.0.16 postflight is deprecated
So the probe is `Homebrew::InstallSteps::DSL.method_defined?(:run)` rather
than `respond_to?(:postflight_steps)` — the latter is true on 6.0.0–6.0.12,
where the block body would then die. That also corrects the floor the last
commit documented: it is 6.0.13, not 7.0.
Verified by regenerating the cask with GoReleaser built from source (both
branches render, `{{staged_path}}` and `#{staged_path}` each survive the
template pass, `ruby -c` clean) and by evaluating the emitted block against
stub DSLs for all three generations: pre-6.0 and 6.0.0–6.0.12 pick
`postflight`, 6.0.13+ picks `postflight_steps` and reaches `run` with the
expected argv.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0122vGrcATX7433WuQ91iLm9
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every
brewcommand touching the cask printed:The stanza is the cask's quarantine strip, which the unsigned binary needs in order to launch on macOS, so it cannot simply be dropped — and Homebrew deprecations become hard errors a few releases later.
What changed
GoReleaser renders
homebrew_casks.hooks.post.installaspostflight do … endand cannot emit the*_stepsstanzas yet (goreleaser/goreleaser#6870, PR #6873, milestone v2.19.0). It also has no way to emit both spellings, so.goreleaser.yamlnow writes the stanza itself throughcustom_block, and the cask picks one at load time:The cask installs on every Homebrew version and prints a deprecation warning on none.
Why the probe is what it is
Three Homebrew releases matter, and they are not the same one:
postflight_stepsstanza landsrun/on_macos— the steps this block callspostflightdeprecated (the warning)So the probe asks
Homebrew::InstallSteps::DSL.method_defined?(:run)rather thanrespond_to?(:postflight_steps): the latter is true on 6.0.0–6.0.12, where the block body would then die. (Cask::DSL#respond_to_missing?returnsfalse, sorespond_to?is a sound probe in principle — it just answers the wrong question here.)Two more details, both spelled out next to the block in
.goreleaser.yaml:{{staged_path}}is written escaped as{{ "{{staged_path}}" }}because GoReleaser runs the whole generated cask through its own template engine as a final pass. The legacy branch spells the same path#{staged_path}, since the steps DSL has no Ruby interpolation — that was the point of deprecatingpostflight.custom_blockis injected right aftercask "koc" do, so the generated file's stanza order is unconventional. It is still correct: Homebrew orders artifacts by class (BinarybeforePostflightSteps, perCask::Artifact::AbstractArtifact.sort_order), never by file position.Verification
goreleaser checkclean; cask regenerated with GoReleaser built from source (main, since no released version carries the fix) via a snapshot release — both branches render,{{staged_path}}and#{staged_path}each survive the template pass,ruby -cclean.No Go code changes, so the command surface is unchanged and
docs/coverage.mdneeds no update. README and AGENTS.md record the version boundaries and the reasoning.The tap keeps serving the v0.32.0 cask until a new tag is cut.
🤖 Generated with Claude Code
https://claude.ai/code/session_0122vGrcATX7433WuQ91iLm9
Generated by Claude Code