Skip to content

chore: migrate release to reusable macos-sparkle-release workflow - #3

Open
adamXbot wants to merge 2 commits into
mainfrom
chore/reusable-release-workflow
Open

chore: migrate release to reusable macos-sparkle-release workflow#3
adamXbot wants to merge 2 commits into
mainfrom
chore/reusable-release-workflow

Conversation

@adamXbot

@adamXbot adamXbot commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Migrates BananaBlitz from its copy-pasted gen-1 release pipeline to the shared reusable workflows in privacykey/gh-workflows (pinned @v1).

What changed

  • .github/workflows/release.yml — replaced the 119-line gen-1 pipeline with a thin caller of macos-sparkle-release.yml@v1 (xcodeproj: BananaBlitz.xcodeproj, scheme: BananaBlitz, uses_xcodegen: true, release_script: ./Scripts/release.sh, cask_name: bananablitz, tap_repo: adamxbot/homebrew-tap). Secrets are mapped explicitly under the gen-3 names. Caller keeps permissions: contents: write (a called workflow can only reduce the caller's token) and duplicates concurrency per the shared repo's README.
  • .github/workflows/ci.yml — swapped to the macos-app-ci.yml@v1 caller. This is a clean swap: the reusable CI workflow was generalised from this repo's ci.yml. Only deliberate drops: xcpretty decoration and the showdestinations-on-failure fallback (the uploaded xcresult bundle carries all of it).
  • Scripts/release.sh — updated to the shared release-script env contract: notarization now uses the ASC API key (xcrun notarytool … --key/--key-id/--issuer from APPLE_API_KEY_PATH/APPLE_API_KEY_ID/APPLE_API_ISSUER) instead of Apple-ID + app-specific password; signing identity comes from APPLE_SIGNING_IDENTITY (falls back to probing the keychain locally; DEVELOPER_ID still works as an alias); the direct codesign call honours KEYCHAIN_PATH when set; the dSYM is staged to symbols/BananaBlitz-<version>.app.dSYM.zip; the notarization zip is removed from dist/ after stapling so the workflow's built-in generate_appcast (which scans all of dist/) can't pick up a duplicate archive. Still runs locally for dry-runs.
  • Casks/bananablitz.rbpackaging/homebrew/bananablitz.rb — converted to the @@VERSION@@/@@SHA256@@/@@URL@@ template the reusable cask step renders and pushes to adamxbot/homebrew-tap automatically, replacing the manual copy-on-every-release chore. The cask step skips cleanly until a tap token is configured.
  • Scripts/generate-appcast.sh is now unused by CI (the built-in appcast step replaces it, same key-format validation). Kept for local use; can be deleted later.

Secrets required before the next v* tag

The workflow reads these — see the gh-workflows README for what each is and how to mint it: APPLE_CERTIFICATE, APPLE_CERTIFICATE_PASSWORD, APPLE_SIGNING_IDENTITY, APPLE_API_KEY, APPLE_API_KEY_ID, APPLE_API_ISSUER, SPARKLE_PRIVATE_KEY, plus optional HOMEBREW_TAP_TOKEN (fine-grained PAT scoped to the tap only; the cask step skips cleanly without it). Verify with gh secret list before tagging.

Two traps worth knowing:

  • SPARKLE_PRIVATE_KEY is the base64 output of generate_keys -x as-is — do not base64 it again (docs/RELEASES.md's base64 < sparkle-private.pem step would double-encode; the workflow validates and rejects that).
  • The old gen-1 secret names (APPLE_DEVELOPER_ID_*, APPLE_NOTARY_*) are not referenced anywhere after this PR — don't recreate them.

Recommended follow-up (not required for the first release): create a macos-signing environment with a required-reviewers rule, keep SPARKLE_PRIVATE_KEY in it, and switch the caller from explicit secrets: mapping to secrets: inherit — environment secrets resolve empty under explicit mapping.

⚠️ First tag push after merge is the live test

Past releases were cut locally via Scripts/release.sh, so the first v* tag after merge exercises keychain import, ASC-key notarization, appcast generation, Release publish, and appcast push end-to-end, live.

  • Dry-run: workflow_dispatch is not wired (kept the caller minimal). Recommend a prerelease tag first, e.g. v1.0.1-rc.1. Note the tag-verify step requires the tag to exactly match MARKETING_VERSION, so set MARKETING_VERSION: "1.0.1-rc.1" in project.yml for the rc, then bump to the real version. Caveat: an rc run still publishes a real GitHub prerelease and overwrites gh-pages/appcast.xml (Sparkle clients would see the rc) — delete the rc Release and revert the appcast commit afterwards, or dry-run on a fork.
  • Version gate: project.yml currently has MARKETING_VERSION: "1.0.0" while the latest tag is v0.0.3 — the next real tag must be v1.0.0 (or bump the setting to match whatever you tag).
  • The test job runs with no secrets before anything signing-related, so a broken build fails safely.

Rollback

git revert of this PR's merge commit restores the previous self-contained release.yml/ci.yml, the old Scripts/release.sh (Apple-ID notarization), and Casks/bananablitz.rb — no state outside the repo to undo.

Also worth a follow-up: docs/RELEASES.md and the README still describe the old flow and gen-1 secret names.

🤖 Generated with Claude Code

adamXbot and others added 2 commits August 6, 2026 22:32
Replace the copy-pasted gen-1 release pipeline with a thin caller of
privacykey/gh-workflows/.github/workflows/macos-sparkle-release.yml@v1,
switch ci.yml to the shared macos-app-ci.yml@v1 caller (which was
generalised from this repo's CI, so behaviour is unchanged), update
Scripts/release.sh to the shared release-script env contract
(APPLE_SIGNING_IDENTITY / ASC API key notarization / KEYCHAIN_PATH /
dSYM staging), and move the Homebrew cask to
packaging/homebrew/bananablitz.rb as a @@Version@@/@@sha256@@/@@url@@
template so the pipeline can publish it to adamxbot/homebrew-tap
automatically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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