fix: keep the packaged version in step with the release tag (#17)
## The defect `pyproject.toml` carried a static version while releases are derived from conventional commits and tagged by CI. The first release after the packaging change was cut as **v0.4.0** while the file still declared `0.3.0`, so both the Python package metadata and the Nix store path understated the release. ## Why a human cannot fix this by hand The version is computed from commit messages *since the last tag* and is only known inside the release job, after the build. The pull request that causes a release cannot know the number it will produce — especially with more than one PR in flight. Any hand-set value drifts again at the next release. ## The fix The release job now writes the computed version into `pyproject.toml`, commits it as `chore(release): vX.Y.Z`, and tags **that** commit. - Neither push re-triggers the workflow: it listens on `main` only for the image-affecting paths, and `pyproject.toml` is not one of them. - `chore(release)` produces no bump of its own on the next run. - The branch push is ordered before the tag push, so a rejected push (main moved on) cannot leave a tag pointing at a commit that is not on `main`. - `pyproject.toml` is bumped to `0.4.0` here to correct today's state; from the next release onward CI maintains it, and a comment in the file says so. ## Verification - The version-rewrite step was extracted from the workflow and run against a copy of `pyproject.toml`: the line is rewritten, and the step raises if it ever finds no version line rather than silently doing nothing. - `bash -n` on the step, `nix flake check` green at 0.4.0. - `main` has no branch protection rules, so the job's push will be accepted. If you ever add protection, the CI token needs an exemption or this step fails. --------- Co-authored-by: Emma Thorpe <emma.thorpe@citrix.com> Reviewed-on: #17
This commit was merged in pull request #17.
This commit is contained in:
@@ -153,15 +153,46 @@ jobs:
|
||||
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
|
||||
# Record the release as an annotated git tag so the next run computes the
|
||||
# following version from it. This push does not re-trigger the workflow,
|
||||
# which only listens on the main branch and pull requests.
|
||||
- name: Tag the release
|
||||
# Record the release: write the computed version into pyproject.toml, then
|
||||
# commit and tag it, so the packaging metadata always matches the release
|
||||
# instead of drifting behind it. The version is derived from commit
|
||||
# messages and only known here, after the build, so it cannot be set by
|
||||
# hand in the pull request that causes the release.
|
||||
#
|
||||
# Neither push re-triggers this workflow: it listens on main only for the
|
||||
# image-affecting paths above, and pyproject.toml is not one of them. The
|
||||
# chore(release) subject also produces no bump of its own on the next run.
|
||||
- name: Record and tag the release
|
||||
if: steps.version.outputs.release == 'true'
|
||||
env:
|
||||
VERSION: ${{ steps.version.outputs.version }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
v="v${{ steps.version.outputs.version }}"
|
||||
|
||||
python - "$VERSION" <<'PY'
|
||||
import pathlib
|
||||
import re
|
||||
import sys
|
||||
|
||||
version = sys.argv[1]
|
||||
path = pathlib.Path("pyproject.toml")
|
||||
text = path.read_text()
|
||||
text, count = re.subn(
|
||||
r'(?m)^version = ".*"$', f'version = "{version}"', text, count=1
|
||||
)
|
||||
if count != 1:
|
||||
raise SystemExit("no version line found in pyproject.toml")
|
||||
path.write_text(text)
|
||||
PY
|
||||
|
||||
git config user.name "${{ github.actor }}"
|
||||
git config user.email "${{ github.actor }}@users.noreply.${REGISTRY}"
|
||||
git tag -a "$v" -m "$v"
|
||||
git push origin "$v"
|
||||
git add pyproject.toml
|
||||
git commit -m "chore(release): v${VERSION}"
|
||||
|
||||
# Push the branch before the tag. If main has moved on and this push
|
||||
# is rejected, the job fails without having left a tag pointing at a
|
||||
# commit that is not on main.
|
||||
git push origin "HEAD:${GITHUB_REF_NAME}"
|
||||
git tag -a "v${VERSION}" -m "v${VERSION}"
|
||||
git push origin "v${VERSION}"
|
||||
|
||||
Reference in New Issue
Block a user