From 6a191b405b5c9bdbcdab4eb1250bea9fa295f18f Mon Sep 17 00:00:00 2001 From: chopratejas Date: Wed, 6 May 2026 14:04:00 -0700 Subject: [PATCH] fix(ci): pypi publish skip-existing to unblock idempotent re-runs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every push to main since v0.21.5 was first published has failed the publish-pypi job with `400 File already exists`. The workflow's detect-version step has been computing v0.21.5 repeatedly (the canonical+commit-height algorithm hasn't bumped past it for the recent fix-only commits), so each run rebuilds the same wheels with the same version and twine rejects the duplicates. Failed runs: - 25443521479 (PR #406 merge, 15:04 UTC) - 25452026402 (PR #409 merge, 17:55 UTC) - 25452038283 (next push, 17:56 UTC) PyPA's recommended pattern for this scenario is `skip-existing: true` on the publish action — duplicate uploads become no-ops, fresh versions still publish normally. Idempotent. This unblocks main without touching the version-detection algorithm. A follow-up audit of `headroom/release_version.py` is the right deeper fix (so a series of `fix:` commits between releases produces a sequence of patch bumps), but that's a deeper investigation; this patch just stops the publish job from going red on every push. Effect after this lands: - Push to main → wheels rebuilt with whatever version detect-version computes - If that version's wheels are already on PyPI → twine skips them, exit 0, downstream jobs (publish-npm, publish-docker, create-release) run normally - If detect-version computes a NEW version not on PyPI → wheels publish as before, no behaviour change --- .github/workflows/release.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bce87e910..680fde7e6 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -616,6 +616,15 @@ jobs: - name: Publish ${{ env.PYPI_PACKAGE }} to PyPI id: pypi-publish uses: pypa/gh-action-pypi-publish@release/v1 + with: + # Idempotent re-runs: when a wheel filename for the computed + # version is already on PyPI (e.g. a previous push to main + # already published this version, or this run's computed + # semver hasn't bumped past the last release), treat the + # existing file as a no-op instead of a hard failure. PyPA's + # recommended pattern for release workflows that may run + # multiple times against the same version. + skip-existing: true publish-npm: needs: [detect-version, build]