Skip to content

feat(release): auto-bump the Homebrew cask on each published release#10

Merged
barscn merged 1 commit into
mainfrom
ci/homebrew-cask-autobump
Jul 8, 2026
Merged

feat(release): auto-bump the Homebrew cask on each published release#10
barscn merged 1 commit into
mainfrom
ci/homebrew-cask-autobump

Conversation

@barscn

@barscn barscn commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Why

The homebrew-tap cask pins a version + sha256, so brew install --cask capsule-native/tap/capsule keeps serving the old version after a release until someone hand-edits the cask. (Existing installs are fine — auto_updates true lets Sparkle update them in place — but fresh brew installs go stale.) This closes that gap.

What

After Publish GitHub Release, the release job now:

  1. Determine Homebrew tap availability — checks for the HOMEBREW_TAP_TOKEN secret; absent (forks), it skips with a warning, mirroring the existing signing-availability gate.
  2. Bump the Homebrew cask — reads the version from App/Info.plist (per the repo's "version comes from the app" rule), recomputes the DMG's SHA-256, renders Casks/capsule.rb with the new pure Scripts/release/update-homebrew-cask.sh, and pushes it to capsule-native/homebrew-tap. Idempotent — an unchanged cask is a no-op (no empty commit), so re-running a release is safe.

update-homebrew-cask.sh is network-free and secret-free (just renders the cask to stdout), keeping this repo the single source of truth for the cask template.

⚠️ Action required to activate

This is a safe no-op until a secret is added — merge anytime. To turn it on, add a repo secret HOMEBREW_TAP_TOKEN on capsule-native/capsule:

  • Fine-grained PAT (recommended) — Resource owner capsule-native, Repository access → only capsule-native/homebrew-tap, Permissions → Contents: Read and write (Metadata: Read-only is auto-included). Nothing else.
  • Org note: because the tap is org-owned, org settings may need to allow fine-grained PATs (you're the owner, so you can approve).
  • Alternative: a classic PAT with the repo scope — simpler but grants all your repos; fine-grained is tighter.

Verification

  • update-homebrew-cask.sh 0.1.0 <real v0.1.0 DMG> renders byte-identical to the live tap cask → first CI run is a clean no-op.
  • brew style on the rendered cask at a Casks/ path: no offenses.
  • make check green (swift-format, architecture, license headers); bash -n clean; YAML parses with both new steps and timeout-minutes: 60 intact.

🤖 Generated with Claude Code

The homebrew-tap cask pins a version + SHA-256, so `brew install` served the old
version until someone hand-edited it. Add a release-job step that, after the GitHub
Release is published, recomputes the DMG's SHA-256, renders Casks/capsule.rb via a
new pure `update-homebrew-cask.sh`, and pushes it to capsule-native/homebrew-tap.

Gated on a HOMEBREW_TAP_TOKEN secret (a PAT scoped to the tap, since the job's own
GITHUB_TOKEN can't write another repo); absent — on forks — it's skipped with a
warning, mirroring the existing signing-availability gate. Idempotent: re-running a
release whose cask is unchanged is a no-op (no empty commit).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@barscn barscn merged commit 16b851e into main Jul 8, 2026
1 of 2 checks passed
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