Skip to content

ci(sanitize): refuse to move an existing release tag - #74

Open
rob-p wants to merge 1 commit into
mainfrom
ci/no-force-move-release-tags
Open

ci(sanitize): refuse to move an existing release tag#74
rob-p wants to merge 1 commit into
mainfrom
ci/no-force-move-release-tags

Conversation

@rob-p

@rob-p rob-p commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Fixes the mechanism behind #73.

What happened

sanitize-cargo.yml runs on any push to main whose head commit message contains the tag marker, and tagged with git tag --force + git push --force. On 2026-07-20 main was reset back to 3dec905 after an accidental push of dev work; that force-push replayed a push event whose head commit was the already-released v0.10.3 commit, so the job ran a second time on the same source SHA and repointed the tag:

before after
tag commit 2a640e25 (Jul 16 12:35:23Z) a2e296fb (Jul 20 03:43:41Z)
tree b84e6524 b84e6524 (identical)
parent 3dec9058 3dec9058 (identical)

The release contents never changed — identical tree SHA — but GitHub stamps archive member mtimes from the commit date, so the generated v0.10.3.tar.gz changed bytes and its sha256 went from 4fb1d812… to e952fae1…, breaking checksum verification downstream (Homebrew).

Release assets and crates.io were unaffected: the re-run Release workflow failed at host (release already exists) and Publish to crates.io was skipped.

The change

Query origin for the tag before doing anything and fail with a clear ::error:: if it already exists, then tag and push without --force.

Trade-off: legitimately re-cutting a version now requires deleting the tag by hand first. That is the intent — moving a published tag should be a deliberate, human action, not a side effect of a force-push.

🤖 Generated with Claude Code

The sanitize job fired on any push to main whose head commit message
contains the tag marker, then created the sanitized commit with
`git tag --force` / `git push --force`. Re-pushing an already-released
head commit (e.g. resetting main after an accidental push) therefore
re-ran the job on the same source SHA and silently repointed the release
tag at a fresh commit.

The tree is identical in that case, but GitHub stamps archive member
mtimes from the commit date, so the generated source tarball changes
bytes and its sha256 changes with it -- which broke checksum
verification for downstream packagers (#73).

Check origin for the tag first and fail loudly if it exists, and drop
both --force flags so the tag can never be moved implicitly.
Re-releasing a version now requires deleting the tag by hand.
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