Rehearse the release version refresh at PR time - #9445
Merged
Merged
Conversation
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
`uv lock --check` takes uv's satisfies fast path, so it accepts a lock that a different uv version wrote; the release bump re-resolves and can then rewrite the reviewed graph, which only shows up on main. `--rehearse` copies pyproject.toml and uv.lock into a temporary directory, applies the patch bump bump_version.py would apply, and runs the existing refresh against the copy. uv resolves that copy from project metadata alone, because the root declares no dynamic metadata and needs no package tree. The mode reuses check_release_lock, so it runs the same uv command, the same validation and the same restore. It reads the checkout and asserts afterwards that neither file changed, and reports the guard's own error with a pointer to the release-lock document. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The ReleaseLock job checked the committed lock but never re-resolved it, so a lock regenerated with an unpinned uv passed the pull request and failed the next automatic bump on main. The rehearsal runs in the same job, after the committed check, with the pinned uv the release job uses. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Tell contributors to regenerate the lock with the pinned uv rather than the uv they happen to have, describe `--rehearse` and why it must run under that same pin, and replace the paragraphs that still said the country lock was blocked until spm-calculator 1.0.0 reached PyPI. The committed lock resolves that release from PyPI with hashed artifacts. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…he documented uv Review nits on the rehearsal: the two-file copy is only valid while the project declares static metadata, so the project validator now rejects a `dynamic` key; the command's failure path (exit 2 with the hint) has a test; the documented rehearsal command now actually puts the pinned uv first on PATH instead of printing its version beside an unpinned run; and the fixture README no longer calls the production lock pending. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
MaxGhenis
marked this pull request as ready for review
September 12, 2026 01:23
Both conflicts were prose: the lock note and the SPM doc describe the calculator requirement and the certified build's digest as main now ships them, so main's wording is kept. Co-Authored-By: Claude Fable 5.1 <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.
Why
The first automatic version bump after #9428 failed on main in
Update versioningatrelease_lock.py --refreshalthough PR CI had passed.--committedrunsuv lock --check, which takes uv's satisfies fast path and accepts a lock written by another uv version; the bump forces a re-resolution and the runner's uv rewrote 37 resolution-marker lines. #9444 pinned uv 0.12.13 and committed the lock in that normalization. This closes the remaining gap the review of #9444 named: a contributor who regenerates the lock with any other uv still passes PR CI and breaks the next release.What
.github/release_lock.py --rehearse: copiespyproject.tomlanduv.lockinto a temporary directory, bumps the copied root version by one patch level exactly asbump_version.pywould, and runs the existing refresh (check_release_lock(root, refresh=True)) there. The copy holds only the two files; the project declares no dynamic metadata, so uv resolves it without the package tree. The checkout is never written; both files are re-read at the end to prove it.pr.yamlReleaseLockjob: "Rehearse the release version refresh" after the committed check..github/tests/test_release_lock.py(mocked uv: passes when only the root version changes, fails with the guard's message when a marker is rewritten, checkout untouched either way; theRELEASE_LOCK_REAL_UV=1probe covers the real resolver)..github/release-lock.md: regenerate the lock with the pinned uv (uvx --from 'uv==0.12.13' uv lock); how--rehearseworks; the stale "blocked until spm-calculator 1.0.0 is on PyPI" paragraph replaced.docs/spm.md: the calculator now resolves from PyPI.Verification
python -m unittest discover -s .github/tests -p test_release_lock.py: 33 tests OK; also OK withRELEASE_LOCK_REAL_UV=1under uv 0.12.13.--rehearseunder uv 0.12.13 on this branch's lock: exit 0 ("Rehearsed the release refresh at version 1.825.3").--rehearseon the pre-Pin the uv release toolchain and commit the lock in its marker normalization #9444 lock (2cda664): exit 2, "Versioning changed the reviewed dependency graph", while plainuv lock --checkon that lock exits 0. That is the gap this closes.🤖 Generated with Claude Code