From 02e76b7a09ff9dee1018dc22d2c2be97e505704f Mon Sep 17 00:00:00 2001 From: Marc Sibson <125162+sibson@users.noreply.github.com> Date: Wed, 15 Jul 2026 21:15:22 -0400 Subject: [PATCH 1/4] ci: restore PyPI and TestPyPI publish jobs Commit f558acd ("Refine CI workflows to align with community practices") removed the publish-to-pypi and publish-to-testpypi jobs from publish.yml, leaving only build and github-release. Tag pushes have since built the distribution and cut a GitHub release without ever uploading to PyPI, so v2.3.4 and v2.4.0 are tagged and released on GitHub but absent from PyPI, where 2.3.3 (2025-07-02) is still the latest. Reported in #316. Restore both jobs, and make github-release depend on publish-to-pypi rather than build so a failed upload fails the release instead of passing silently. The TestPyPI job rebuilds instead of reusing the build artifact because pbr derives the version from git describe and needs full history to produce a unique .devN version; skip-existing keeps re-runs from failing on an already-uploaded version. Fixes #316 Co-Authored-By: Claude Opus 4.8 --- .github/workflows/publish.yml | 68 ++++++++++++++++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 17876e2..c8cfa35 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -46,12 +46,37 @@ jobs: name: python-package-distributions path: dist/ + publish-to-pypi: + name: >- + Publish Python 🐍 distribution 📦 to PyPI + needs: + - build + runs-on: ubuntu-latest + timeout-minutes: 10 + if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes + + environment: + name: pypi + url: https://pypi.org/p/celery-redbeat + + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + - name: Download all the dists + uses: actions/download-artifact@v4 + with: + name: python-package-distributions + path: dist/ + - name: Publish distribution 📦 to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + github-release: name: >- Sign the Python 🐍 distribution 📦 with Sigstore and upload them to GitHub Release needs: - - build + - publish-to-pypi runs-on: ubuntu-latest timeout-minutes: 10 if: startsWith(github.ref, 'refs/tags/') @@ -90,3 +115,44 @@ jobs: gh release upload "$GITHUB_REF_NAME" dist/** --repo "$GITHUB_REPOSITORY" + + publish-to-testpypi: + name: Publish Python 🐍 distribution 📦 to TestPyPI + needs: + - build + runs-on: ubuntu-latest + timeout-minutes: 10 + + environment: + name: testpypi + url: https://test.pypi.org/p/celery-redbeat + + permissions: + id-token: write # IMPORTANT: mandatory for trusted publishing + + steps: + # rebuild rather than reuse the build job's artifact: pbr derives the + # version from git describe, so it needs the full history to produce a + # unique .devN version for TestPyPI. + - name: Check out source code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + persist-credentials: false + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.12' + cache: pip + - name: Install build tooling + run: | + python -m pip install --upgrade pip + python -m pip install build + - name: Build a binary wheel and a source tarball + run: python -m build + - name: Publish distribution 📦 to TestPyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + verbose: true + skip-existing: true + repository-url: https://test.pypi.org/legacy/ From 22cdeb9c36132df238591144edb247b013df8f71 Mon Sep 17 00:00:00 2001 From: Marc Sibson <125162+sibson@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:30:07 -0400 Subject: [PATCH 2/4] docs: add 2.4.1 changelog entry noting PyPI republish 2.3.4 and 2.4.0 were tagged but never reached PyPI due to the removed publish jobs (see #316). 2.3.4's changes are a subset of 2.4.0's already listed here, so no separate entry is added; 2.4.1 will be the first PyPI release since 2.3.3 and carries all 2.4.0 changes. Co-Authored-By: Claude Opus 4.8 --- CHANGES.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.txt b/CHANGES.txt index 5dd372d..12605c0 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,9 @@ -2.4.1dev (unreleased) +2.4.1 (unreleased) --------------------- + - ci, restore PyPI/TestPyPI publish jobs dropped in a CI refactor; 2.3.4 and + 2.4.0 were tagged but never published to PyPI, fixes #316 + - First PyPI release since 2.3.3; includes all 2.4.0 changes below + 2.4.0 (2026-03-26) --------------------- - Drop support for Python 3.8 and add CI coverage through Python 3.13. From 87fa7a2e668715cba2197ced1656d1303b3f6c1c Mon Sep 17 00:00:00 2001 From: Marc Sibson <125162+sibson@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:34:10 -0400 Subject: [PATCH 3/4] ci: build TestPyPI dist with explicit PBR_VERSION dev version setup.cfg pins the last released version, so on untagged commits pbr derives the next patch version from git and errors: ValueError: git history requires a target version of 2.4.1, but target version is 2.4.0 Override with PBR_VERSION=.dev, computed from the latest tag, so every untagged push builds a unique PEP 440-compliant dev release. Verified locally: PBR_VERSION=2.4.1.dev630 builds celery_redbeat-2.4.1.dev630. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/publish.yml | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c8cfa35..2c436c2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -131,14 +131,22 @@ jobs: id-token: write # IMPORTANT: mandatory for trusted publishing steps: - # rebuild rather than reuse the build job's artifact: pbr derives the - # version from git describe, so it needs the full history to produce a - # unique .devN version for TestPyPI. + # Rebuild rather than reuse the build job's artifact: setup.cfg pins the + # last released version, so on untagged commits pbr's git-derived version + # (next patch) conflicts with the pin and the build fails. Override with an + # explicit PBR_VERSION of .dev so every untagged push + # produces a unique, PEP 440-compliant dev release. Needs full history for + # the tag lookup and commit count. - name: Check out source code uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false + - name: Compute dev version + run: | + base=$(git describe --tags --abbrev=0 | sed 's/^v//') + next=$(echo "$base" | awk -F. '{print $1"."$2"."$3+1}') + echo "PBR_VERSION=${next}.dev$(git rev-list --count HEAD)" >> "$GITHUB_ENV" - name: Set up Python uses: actions/setup-python@v5 with: From 9376b4600c2fc45339e37023959dd7a4c1d01922 Mon Sep 17 00:00:00 2001 From: Marc Sibson <125162+sibson@users.noreply.github.com> Date: Thu, 16 Jul 2026 08:39:09 -0400 Subject: [PATCH 4/4] build: let pbr derive version from git tags instead of static pin setup.cfg pinned `version = 2.4.0` in both [metadata] and [pbr], despite acf8261 introducing pbr specifically for dynamic git-tag-based versioning. pbr cross-checks any static pin against git history and errors once a commit lands after the tag it points to: ValueError: git history requires a target version of 2.4.1, but target version is 2.4.0 This broke every untagged build (e.g. the TestPyPI job), and was previously worked around with a PBR_VERSION override script rather than fixed at the source. Removing the pin lets pbr do what it's designed for: exact tag -> clean version (verified 2.4.0 at v2.4.0), untagged commit -> automatic .devN (verified 2.4.1.dev5, N = commits since v2.4.0), both confirmed locally including under actions/checkout's default shallow fetch for the tag case. makefile no longer rewrites setup.cfg on release (git tag now IS the version of record); `make version` uses `python setup.py --version` to read it back through pbr instead of grepping a field that no longer exists. Co-Authored-By: Claude Opus 4.8 --- .github/workflows/publish.yml | 14 +++----------- makefile | 5 ++--- setup.cfg | 4 ---- 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 2c436c2..98ebbe2 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -131,22 +131,14 @@ jobs: id-token: write # IMPORTANT: mandatory for trusted publishing steps: - # Rebuild rather than reuse the build job's artifact: setup.cfg pins the - # last released version, so on untagged commits pbr's git-derived version - # (next patch) conflicts with the pin and the build fails. Override with an - # explicit PBR_VERSION of .dev so every untagged push - # produces a unique, PEP 440-compliant dev release. Needs full history for - # the tag lookup and commit count. + # Rebuild rather than reuse the build job's artifact: pbr derives the + # version from git tags (X.Y.Z on a tag, X.Y.(Z+1).devN between tags), so + # this needs full history, not the shallow default, to see prior tags. - name: Check out source code uses: actions/checkout@v4 with: fetch-depth: 0 persist-credentials: false - - name: Compute dev version - run: | - base=$(git describe --tags --abbrev=0 | sed 's/^v//') - next=$(echo "$base" | awk -F. '{print $1"."$2"."$3+1}') - echo "PBR_VERSION=${next}.dev$(git rev-list --count HEAD)" >> "$GITHUB_ENV" - name: Set up Python uses: actions/setup-python@v5 with: diff --git a/makefile b/makefile index e205da3..b177926 100644 --- a/makefile +++ b/makefile @@ -31,9 +31,8 @@ release-tag: ifndef VERSION @echo "usage: make release VERSION='M.m.p'" && false else - sed -i '' -e 's|version = .*|version = $(VERSION)|' setup.cfg sed -i '' -e "s/unreleased/$(TODAY)/" CHANGES.txt - git ci -m"prepare for release of $(VERSION)" CHANGES.txt setup.cfg || git commit -m"prepare for release of $(VERSION)" CHANGES.txt setup.cfg || true + git ci -m"prepare for release of $(VERSION)" CHANGES.txt || git commit -m"prepare for release of $(VERSION)" CHANGES.txt || true git tag -a v$(VERSION) -m"release version $(VERSION)" git push --tags printf "%s\n%s\n%s\n -\n" "$(NEXT_VERSION)dev (unreleased)" "---------------------" "$$(cat CHANGES.txt)" > CHANGES.txt @@ -57,4 +56,4 @@ clean-venv: rm -rf .venv version: - @grep -m1 '^version' setup.cfg | sed 's/.*= *//' + @python setup.py --version diff --git a/setup.cfg b/setup.cfg index 6b19e51..994763b 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,7 +1,6 @@ [metadata] name = celery-redbeat description = A Celery Beat Scheduler using Redis for persistent storage -version = 2.4.0 license = Apache License, Version 2.0 author = Marc Sibson @@ -44,6 +43,3 @@ universal = 1 [tool:pytest] # ... if you use pytest ... - -[pbr] -version = 2.4.0