fix(release): make the tag step idempotent for job re-runs - #37
Merged
Merged
Conversation
The recovery path the workflow documents did not work. If the publish failed after the tag was cut, the intended fix was to re-run the job — but `fetch-depth: 0` fetches tags, so a bare `git tag -s` exited non-zero on the second pass, the job died before reaching `gh release upload --clobber`, and the release was stuck needing a human to delete a tag this repository treats as immutable. Which is the exact situation immutability exists to prevent. Re-running the whole WORKFLOW cannot substitute: `guard` would see the tag on the remote and correctly report the version as already released, skipping verify and publish entirely. So the job re-run is the only path, and it has to survive an existing tag. It now detects the ref, verifies the signature that is already on it, and skips re-cutting. Also corrects a justification that was simply false. The header claimed the tag is checked out because `main` is a moving ref that a later merge could slip into the release. `actions/checkout` defaults to `github.sha`, so every job was already pinned to the triggering commit — building from the tag is a provenance statement, not a race fix. Both claims were flagged in the review of the commit that introduced them; this is that follow-up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Summary
Last fix before cutting 5.0.0, and it protects the operation we are about to perform for the first
time. Two problems in
release.yml, both flagged during the review of the commit that introducedthem (#36) and deliberately left for a follow-up.
1. The documented recovery path did not work. If the publish fails after the tag is cut, the
workflow says to re-run the job. But
fetch-depth: 0fetches tags, so a baregit tag -sexitsnon-zero on the second pass — the job dies there and never reaches
gh release upload --clobber.The release would be stuck needing a human to delete a tag this repository treats as immutable,
which is the exact situation immutability exists to prevent.
Re-running the whole workflow is not a substitute:
guardwould see the tag on the remote andcorrectly report the version as already released, skipping
verifyandpublishentirely. The jobre-run is the only path, so it has to survive an existing tag. It now detects the ref, verifies the
signature already on it, and skips re-cutting.
2. A justification that was false. The header claimed the tag is checked out because
mainis amoving ref a later merge could slip into the release.
actions/checkoutdefaults togithub.sha,so every job was already pinned to the triggering commit. Building from the tag is a provenance
statement, not a race fix — corrected rather than left as a plausible-sounding reason someone would
later rely on.
Type of change
Risk and rollback
Risk: touches only the release path, and only the branch that runs when a tag already exists —
which is unreachable on a first, successful release. If it is wrong, it is wrong in the direction of
not re-cutting a tag that should have been cut, and that fails loudly at
git verify-tag.Rollback: revert. Nothing here reaches a user.
How was this tested?
release.ymlparses (yaml.safe_load) — and that check earned its keep: it caught a straycharacter on line 1 that would have broken the entire workflow file. It was local-only and
never committed, but the file was one
git addaway from a release workflow that cannot parse.pass reports it exists and does not re-cut.
execution of
release.ymlis 5.0.0 itself.Notes for reviewers
This is the last thing between us and the release.
apply-rulesets.shstill has to run after#36 is merged (it is) and before #35 goes in — the
No bot PRs pending on developcheck has toexist as a job before it can be required, or #35 blocks on a check nothing will ever report.
Not fixed here and left for 5.0.1: the CHANGELOG entry for 5.0.0 predates tonight's CI work (image
segmentation, release ordering, the bot gate, CodeQL required on develop), so the record of the
release is incomplete on that point.