Release runs one CI pass, and the tag it cuts agrees with its own lockfile - #64
Merged
Conversation
…kfile The v0.1.1 release broke CI twice over. The tag push re-ran the suite the release preflight had just run on the identical tree — `on: push` with no filter fires for tags too — so one release produced two runs. And both runs failed honestly: mint's version bump landed a pyproject that disagreed with uv.lock, because the lock records the project's own version and nothing re-locked it. The preflight could not have caught this — it ran `uv sync --locked` on a tree that was still consistent, and the bump that broke it came after. CI now triggers on branch pushes only; a tag never re-runs what preflight already proved on the same tree. The bump fix lives where the drift is made. mint's pre_tag hook runs on the PRE-BUMP tree (device-verified with a probe repo: releasing v0.0.3, the hook read the version file and saw 0.0.2) and no hook runs between mint's bump and the tag — so the hook now does the bump itself: `uv version "$MINT_NEW_VERSION"` moves pyproject and uv.lock together, mint sweeps both into its pre-tag artifacts commit, and its own bump finds the file already current. This also fixes a second latent defect the same ordering caused: `uv build` was baking the pre-bump version into the wheel, so v0.1.1's sanity-check wheel was versioned 0.1.0. The stale lock on main is re-locked here. The v0.1.1 tag itself keeps its inconsistent lock — moving a published tag is worse, and instances never read it: the shim's uvx builds from the tree. Verified end-to-end in a scratch repo: with the hook in place the tag's checkout passes `uv sync --locked`, and the bookkeeping commit carries just the changelog. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The config says what it does; the why lives in CLAUDE.md, which is the present tense. Drops the ten-line pre_tag block from .mint.toml and the branch-filter block from ci.yml, trues up ci.yml's header (it still claimed every push), and re-wraps the CLAUDE.md prose to the file's width. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Same reason as the last commit: .mint.toml is now fifteen lines that say exactly what they do, and CLAUDE.md's release-gate paragraph carries every why the comment was holding. Co-Authored-By: Claude Opus 5 <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.
The v0.1.1 release broke CI twice over — one structural, one real.
Two runs per release
on: pushwith no filter fires for tag pushes too, so the release produced one run for the branch push and one for the tag — the same tree twice, right after the release preflight had already run the identical four gates locally. CI now triggers on branch pushes only (branches: ["**"]); PRs unchanged.Both runs failed — the lock drift
Every job died on
uv sync --locked: mint's version bump landedversion = "0.1.1"in pyproject while uv.lock still recorded 0.1.0 (the lock records the project's own version). The preflight couldn't have caught it — it ranuv sync --lockedon a tree that was still consistent, and the bump that broke it came after.Where the fix can live was established empirically, not by reading docs (probe repo, three releases driven through real
mint releaseruns):pre_taghook runs on the pre-bump tree — releasing v0.0.3, a probe hook read the version file and saw0.0.2— so a naiveuv lockthere locks the old version;MINT_NEW_VERSIONto hooks, and sweeps any tree changes a hook makes into achore(release): pre-tag artifactscommit before tagging.So the hook now does the bump itself:
uv version "$MINT_NEW_VERSION"moves pyproject and uv.lock together, mint's artifacts commit carries both, and mint's own bump then finds the file already current — the bookkeeping commit carries just the changelog. Verified end-to-end in the probe repo: a checkout of the resulting tag passesuv sync --locked.This also fixes a second latent defect from the same ordering:
uv buildwas building the wheel from the pre-bump tree, so v0.1.1's sanity-check wheel was actually versioned 0.1.0.What this PR does not do
The v0.1.1 tag keeps its inconsistent lock — moving a published tag is worse than the blemish, and instances never read the lock (the shim's
uvxbuilds from the tree). Main's drift is re-locked here, so CI on main goes green on merge.CLAUDE.md's CI and release-gate paragraphs updated to stay true.
Four gates green locally, including the exact
uv sync --lockedthat failed in CI: 2041 passed, ruff, ty, format.