fix(release): fold refreshed lockfile into the version-bump commit#15
Merged
Conversation
…loses #14) cz bump commits and tags atomically, but uv/pixi lockfiles can only be regenerated after the new version is written to pyproject.toml — which means the tagged commit has always shipped with a stale lock. Consumers work around it with a follow-up commit that syncs the lock past the tag, so `git checkout <tag> && uv sync --locked` mismatches (especially bad in uv workspaces with many == cross-pins). Insert a new step between the bump and the push that, while everything is still local: 1. cd to the repo root (workspaces keep the lock at the top). 2. Verify HEAD is the tagged commit — if the recovery path ran and didn't tag, skip with a warning. 3. Refresh the lock via `uv lock` / `pixi lock`. 4. If the lock changed, git add + git commit --amend --no-edit --no-verify, then git tag -f <version> onto the amended commit. 5. Sanity-check the tag now points at HEAD. The push step then publishes the amended commit and the correctly re-pointed tag; no force-push against the remote because none of it was published yet. pip is skipped (no native lockfile). Add a matrix test job (uv + pixi) that snapshots the pre-release lockfile, runs the action, and asserts: - the new tag exists, - HEAD equals the tagged commit (no follow-up past the tag), - the tagged lockfile differs from the pre-release snapshot, - the tagged lockfile records the new version.
…sion guard Add the issue #14 acceptance check to the uv/pixi happy-path job: after the release, re-run the lock against the tagged pyproject.toml and assert no diff (the package-manager-agnostic equivalent of `git checkout <tag> && <pm> sync --locked`), proving the committed lock is consistent, not merely refreshed. Add test-release-pip-no-lockfile-fold: a pip release must leave the tag on the bump commit with no amend and produce no lockfile, guarding that the fold step stays skipped for package-manager: pip.
Every job hard-codes `git push origin main` and the release action itself does a bare `git push`, both of which require a local `main` branch. That holds under the push-to-main trigger (checkout lands on main) but not under workflow_dispatch on a feature branch, where the suite died at setup with "src refspec main does not match any" before any assertion ran. Add a Normalize step after each fake-remote setup that runs `git checkout -B main` and `git config push.default current`, so a local main exists at the current commit and bare pushes resolve regardless of the dispatched ref. This lets the suite (and the new lockfile-fold jobs) be validated from the Run workflow button on any branch, not only post-merge.
…ncy checks A version-only bump changes uv.lock (it records the workspace member version) but not this pixi fixture's pixi.lock, because the fixture does not install the project as a pypi/editable dependency of its own environment — so pixi.lock never records the project version and the fold step correctly no-ops. Gate the "lock differs from pre-release" and "lock records new version" proofs to uv, where folding must happen. For pixi keep the invariants that hold either way: tag sits on the bump commit, no follow-up commit past the tag, and the tagged lock satisfies a re-lock (issue #14 acceptance). Document the uv/pixi difference in the job comment.
MAfarrag
added a commit
to serapeum-org/earthlens
that referenced
this pull request
Jul 19, 2026
…ile-sync steps The release/github composite action now folds the refreshed lockfile into the tagged version-bump commit (serapeum-org/github-actions#15), so the two steps that re-locked and pushed a separate uv.lock commit after the tag are redundant. Point the ref at @main (which carries the fold; @github-release/main was not a valid ref) and remove them.
MAfarrag
added a commit
that referenced
this pull request
Jul 20, 2026
…fold (#17) - Docs: the earthlens[all] exclusions table wrongly said pyrosm ships no wheel. pyrosm 0.11 and osmium 4.3.1 both ship wheels (cp310-cp314); the sdist-only dep is pyrosm's transitive cykhash, so osm-pbf stays out of [all] to keep the install wheel-only (no C compiler). Fixed the table row and the install snippet. - CI: point github-release.yml at the release/github action's @main, which folds the refreshed lockfile into the tagged version-bump commit, and drop the two now-redundant steps that pushed a separate uv.lock commit after the tag. Closes #794, #795 Refs: #783, #14, #15
13 tasks
MAfarrag
added a commit
to serapeum-org/earthlens
that referenced
this pull request
Jul 20, 2026
… specific versions (#793) - Docs: correct the osm-pbf exclusion reason. pyrosm 0.11 and osmium 4.3.1 both ship wheels; the sdist-only dep is pyrosm's transitive cykhash, so osm-pbf stays out of `all` to keep it wheel-only. Fixed in installation.md, the pyproject.toml all-extra comment, and the two osm reference docs. - CI: pin the four serapeum-org/github-actions composite actions to specific versions (release/github@v1.4.0, python-setup/uv@v1.2.0, mkdocs-deploy@v1.3.0, release/pypi@v1.0.2) and adopt their new package-manager-version / version inputs, pinning uv to 0.11.29. - Drop the two redundant lockfile-sync steps in github-release.yml: release/github@v1.4.0 folds the refreshed uv.lock into the tagged version-bump commit itself. Closes #794, #795 Refs: #783, serapeum-org/github-actions#14, serapeum-org/github-actions#15
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.
Description
cz bumpcommits the version bump and creates the tag atomically, but uv/pixi lockfiles can only beregenerated after the new version is written to
pyproject.toml. So the tag has always pointed at a commit whoselockfile still pins the pre-bump versions. Consumers work around this with a follow-up commit that syncs the lock
past the tag, which leaves the tagged tree stale:
git checkout <tag> && uv sync --lockedmismatches (especiallyin uv workspaces with many
==cross-pins).This PR folds the refreshed lockfile into the version-bump commit before anything is pushed, so the tag itself
contains a consistent lock — no follow-up commit, no force-push of published refs.
What the fix does (new step in
actions/release/github/action.yml, between the bump and the push):cdto the repo root (workspaces keep the lock at the top even whenWORK_DIRis a sub-package).HEADis the tagged commit — if the first-release recovery path ran (cz bump --files-only, which doesnot tag), skip with a warning rather than amend the wrong commit.
uv lock/pixi lock. Hard-fail on solver/network errors rather than ship a stale lock.git add,git commit --amend --no-edit --no-verify, thengit tag -f <version>onto theamended commit.
HEAD.The existing push step then publishes the amended commit and the re-pointed tag as if that had been the state all
along.
pipis skipped (no native lockfile).Also in this PR — the release test suite (
.github/workflows/test-release-github.yml) was only runnable underits
push: branches: [main]trigger: every job hard-codesgit push origin main, and the action itself does a baregit push, both of which need a localmain. Dispatching the suite on a feature branch died at setup withsrc refspec main does not match any, so the suite could never be validated pre-merge. A per-job normalize step(
git checkout -B main+git config push.default current) makes the whole suite runnable from the Run-workflowbutton on any branch. This is how the fix below was validated in real CI.
Issues
Type of change
How Has This Been Tested?
Full suite dispatched on this branch and all 34 jobs pass
(run: https://github.com/serapeum-org/github-actions/actions/runs/29693095409). New/affected jobs:
Test release - lockfile folded into tag (uv)— proves the fold amends + retags with a refresheduv.lock;asserts the tagged lock differs from the pre-release snapshot, records the new version, HEAD is the tagged
commit, there is no follow-up commit past the tag, and a re-lock is a no-op (the issue enhancement(release/github): fold the refreshed lockfile into the version-bump commit so the tag is reproducible #14 acceptance check).
Test release - lockfile folded into tag (pixi)— a version-only bump does not change this fixture'spixi.lock(the project is not a pypi/editable dep of its own env), so the fold correctly no-ops; asserts theinvariants that hold either way: tag on the bump commit, no follow-up commit, tagged lock satisfies a re-lock.
Test release - pip unaffected by lockfile fold— pip has no lockfile, so the fold step is guarded off; thetag stays on the bump commit with no amend and no lockfile is produced.
The core
bump → lock → amend → retagmechanic was also reproduced locally against the real uv fixture withuv+commitizen, confirminguv lockrecords the new version andgit checkout <tag>yields a consistent lock.Checklist:
github-release/vX)