From 23bfa27fd7721b1ddea9441478526c3905eb18ae Mon Sep 17 00:00:00 2001 From: Emma Thorpe Date: Fri, 21 Aug 2026 13:47:17 +0100 Subject: [PATCH] fix: keep the packaged version in step with the release tag The version in pyproject.toml was static, while releases are derived from conventional commits and tagged by CI. The first release after packaging was cut as v0.4.0 while the file still declared 0.3.0, so the Python package and the Nix store path both understated the release. The version cannot be set by hand in the pull request that causes a release: it is computed from the commit messages and is only known inside the release job. So the release job now writes it into pyproject.toml, commits it as chore(release), 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 -- and the chore(release) subject produces no bump of its own on the next run. The branch push is ordered before the tag push so a rejected push cannot leave a tag pointing at a commit that is not on main. pyproject.toml is bumped to 0.4.0 here to correct the current state; from the next release onward CI maintains it. Co-Authored-By: Claude Opus 5 (1M context) --- .gitea/workflows/build-and-publish.yaml | 45 +++++++++++++++++++++---- pyproject.toml | 5 ++- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/.gitea/workflows/build-and-publish.yaml b/.gitea/workflows/build-and-publish.yaml index 88c3d6f..c40b899 100644 --- a/.gitea/workflows/build-and-publish.yaml +++ b/.gitea/workflows/build-and-publish.yaml @@ -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}" diff --git a/pyproject.toml b/pyproject.toml index db26305..24a82d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,10 @@ build-backend = "setuptools.build_meta" [project] name = "legacy-email-proxy" -version = "0.3.0" +# Written by the release job in .gitea/workflows/build-and-publish.yaml, which +# derives the version from conventional commits and tags the result. Do not +# edit by hand: a hand-set value is overwritten at the next release. +version = "0.4.0" description = "Unauthenticated POP3/SMTP front end proxied to authenticated IMAPS/SMTPS backends" readme = "README.md" requires-python = ">=3.12" -- 2.54.0