From 7fe1ffdaaf3b91c01458b60dd19b78d83cd5798c Mon Sep 17 00:00:00 2001 From: vahid-ahmadi Date: Fri, 18 Sep 2026 11:25:13 +0100 Subject: [PATCH 1/2] Tag releases again publish-git-tag.sh called 'python .github/fetch_version.py'. That file has never existed in this repository, so the command failed, git tag received an empty argument, and '|| true' discarded the error. Releases have gone to PyPI untagged since v0.4.4 while the version reached 1.5.2. Reads the version from pyproject.toml with the same regex bump_version.py uses, and drops the '|| true' so a failure surfaces. The script now exits cleanly when the tag already exists locally or on the remote, so reruns and backfills are safe. The publish job also had no permissions block, so it relied on whatever the repository default happens to be; contents: write is now explicit. --- .github/publish-git-tag.sh | 26 +++++++++++++++++++++++--- .github/workflows/versioning.yaml | 5 ++++- changelog.d/git-tags.fixed.md | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 changelog.d/git-tags.fixed.md diff --git a/.github/publish-git-tag.sh b/.github/publish-git-tag.sh index ce9ff586..1e353851 100755 --- a/.github/publish-git-tag.sh +++ b/.github/publish-git-tag.sh @@ -1,4 +1,24 @@ -#! /usr/bin/env bash +#!/usr/bin/env bash +# Tag the commit that published this version. +# +# Run from the publish job after the version bump has landed on main. Exits +# non-zero if tagging fails, so a broken release is visible rather than silent. +set -euo pipefail -git tag `python .github/fetch_version.py` # create a new tag -git push --tags || true # update the repository version \ No newline at end of file +PYTHON=$(command -v python || command -v python3) +VERSION=$("$PYTHON" -c "import re, pathlib; print(re.search(r'^version\s*=\s*\"(\d+\.\d+\.\d+)\"', pathlib.Path('pyproject.toml').read_text(), re.M).group(1))") +TAG="v${VERSION}" + +if git rev-parse -q --verify "refs/tags/${TAG}" >/dev/null; then + echo "Tag ${TAG} already exists locally; nothing to do." + exit 0 +fi + +if git ls-remote --exit-code --tags origin "refs/tags/${TAG}" >/dev/null 2>&1; then + echo "Tag ${TAG} already exists on the remote; nothing to do." + exit 0 +fi + +echo "Tagging ${TAG}" +git tag "${TAG}" +git push origin "${TAG}" diff --git a/.github/workflows/versioning.yaml b/.github/workflows/versioning.yaml index 26378961..ee2ca81f 100644 --- a/.github/workflows/versioning.yaml +++ b/.github/workflows/versioning.yaml @@ -49,6 +49,9 @@ jobs: name: Publish to PyPI if: (github.event.head_commit.message == 'Update package version') runs-on: ubuntu-latest + permissions: + contents: write + id-token: write steps: - name: Checkout code uses: actions/checkout@v6 @@ -69,7 +72,7 @@ jobs: run: | make build - name: Publish a git tag - run: ".github/publish-git-tag.sh || true" + run: ".github/publish-git-tag.sh" - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: diff --git a/changelog.d/git-tags.fixed.md b/changelog.d/git-tags.fixed.md new file mode 100644 index 00000000..0345e075 --- /dev/null +++ b/changelog.d/git-tags.fixed.md @@ -0,0 +1 @@ +Release tagging now works: the tag script reads the version from pyproject.toml rather than a helper that never existed, and fails loudly instead of silently. From 44cbf751316fbf04ba1ec38a93230b8259ed83c8 Mon Sep 17 00:00:00 2001 From: vahid-ahmadi Date: Fri, 18 Sep 2026 12:03:11 +0100 Subject: [PATCH 2/2] Tag after the PyPI upload, not before Per review: as ordered, a tag failure blocked the release. The tag push is the one step not yet exercised in CI, and skip-existing on the upload keeps a rerun safe either way. --- .github/workflows/versioning.yaml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/versioning.yaml b/.github/workflows/versioning.yaml index ee2ca81f..fc66f24c 100644 --- a/.github/workflows/versioning.yaml +++ b/.github/workflows/versioning.yaml @@ -71,11 +71,13 @@ jobs: - name: Build package run: | make build - - name: Publish a git tag - run: ".github/publish-git-tag.sh" - name: Publish to PyPI uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ password: ${{ secrets.PYPI }} skip-existing: true + # After the upload, so a tag failure can never hold back a release. + # skip-existing above keeps a rerun safe. + - name: Publish a git tag + run: ".github/publish-git-tag.sh"