Skip to content

Harden release workflow: idempotent publishing, fix version-drift root cause - #8

Open
AadhilFarhan wants to merge 1 commit into
mainfrom
ci/harden-release-workflow
Open

Harden release workflow: idempotent publishing, fix version-drift root cause#8
AadhilFarhan wants to merge 1 commit into
mainfrom
ci/harden-release-workflow

Conversation

@AadhilFarhan

Copy link
Copy Markdown
Owner

What

Two gaps flagged by review that a single successful release run wouldn't have exercised:

  1. Non-idempotent release creation. gh release create has no recovery path if a release for the tag already exists — a retry after any mid-job failure (say, the tap-update step erroring) hard-fails immediately instead of finishing. Now checks for an existing release first (gh release view) and falls back to gh release upload --clobber to overwrite assets, instead of trying to create a duplicate.

  2. Version-drift risk, fixed at the root rather than documented around. Support/Info.plist's committed CFBundleShortVersionString could silently drift from reality: CI's PlistBuddy stamp only mutated the ephemeral runner checkout and was never committed back, and a local build-app.sh run had no version logic at all — it always baked in whatever the last-committed value happened to be, release or not. build-app.sh now derives the version itself via git describe --tags --exact-match at build time and stamps the bundle's copy of Info.plist — the same logic runs for a CI release build (which lands exactly on the tag's commit) and a local dev build alike, and an untagged local build now gets an unambiguous 0.0.0-dev instead of a stale-looking release number. The separate CI-only stamp step is now redundant and removed.

One assumption I'm relying on but couldn't fully verify in this session: that actions/checkout@v4 preserves the local tag ref for a tag-triggered workflow, which git describe --tags --exact-match needs. This is a standard, widely-used pattern for exactly this purpose, but worth confirming on the next real tagged release rather than taking on faith.

Test plan

  • Verified the version-derivation line in isolation, both branches: at the v0.1.0 tag's own commit it resolves to 0.1.0; at a later, untagged commit (an already-pushed fix branch) it correctly falls back to 0.0.0-dev without aborting under set -euo pipefail.
  • Rebuilt the app end-to-end with the updated script and confirmed the bundled Info.plist's CFBundleShortVersionString matches (0.1.0, since this branch's HEAD is currently the same commit as the v0.1.0 tag).
  • Sanity-launched the rebuilt app, confirmed it stays alive.
  • Full suite: 9/9 passing (unaffected by this change, hygiene check).
  • Not exercised: the actual idempotent-retry path and a real CI run of the updated release.yml, since that requires pushing a tag — flagged for you to confirm on the next real release rather than done unbidden.

…t cause

- gh release create has no recovery path if a release for the tag
  already exists — a retry after any mid-job failure (e.g. the tap
  update step erroring) hard-fails immediately instead of finishing
  the job. Now checks for an existing release first and falls back to
  gh release upload --clobber to overwrite assets, rather than trying
  to create a duplicate.

- Support/Info.plist's committed CFBundleShortVersionString could
  silently drift from reality: CI's PlistBuddy stamp only mutated the
  ephemeral runner checkout and was never committed back, and a local
  build-app.sh run had no version logic at all, so it always baked in
  whatever the last-committed value happened to be. build-app.sh now
  derives the version itself via git describe --tags --exact-match at
  build time and stamps the bundle's copy of Info.plist directly —
  the same logic runs for both a CI release build (which lands on the
  tag's exact commit) and a local build, and an untagged local build
  gets an unambiguous "0.0.0-dev" instead of a stale-looking release
  number. The separate CI-only stamp step is now redundant and removed.

Verified build-app.sh's version derivation directly: at the v0.1.0
tag's own commit it resolves to "0.1.0"; at a later, untagged commit
it correctly falls back to "0.0.0-dev" without aborting under
set -euo pipefail. Also rebuilt the app end-to-end and confirmed the
bundled Info.plist's CFBundleShortVersionString matches.
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