From 685f110727a50c831f4e82fd995e5d0d15b23d4d Mon Sep 17 00:00:00 2001 From: isayev Date: Thu, 20 Aug 2026 23:25:56 -0400 Subject: [PATCH] fix: pin the PyPI publish action by tag, not by commit SHA The 3.1.0 publish failed 29s in, after a clean build and before PyPI was ever contacted: Unable to find image 'ghcr.io/pypa/gh-action-pypi-publish:a892a5a61159132606e93a2fa6f4358831b04d26' docker: Error response from daemon: manifest unknown The pin was not stale -- a892a5a6 IS v1.14.2, the current latest release. The problem is that this is a DOCKER-based action, and it builds its own image reference out of whatever ref it was invoked with. The run log shows `REF: a892a5a6...` becoming `ghcr.io/pypa/gh-action-pypi-publish:a892a5a6...`, and upstream publishes images tagged by VERSION only. Verified against the registry rather than inferred: a892a5a6... (v1.14.2 SHA) HTTP 404 2834a314... (v1.14.1 SHA) HTTP 404 v1.14.2 HTTP 200 v1.14.1 HTTP 200 So SHA-pinning this action could never have worked, for any release. Every other action in this workflow stays SHA-pinned. checkout, setup-python and upload-artifact are JavaScript actions, where the ref selects code and pinning by SHA is exactly right. The distinction is now a comment above the step, because "why is this one different" is the obvious review question. Nothing was published: PyPI's latest is still 3.0.0 and 3.1.0 is absent, so the version number is still free and the release can be re-cut once this lands. --- .github/workflows/publish.yml | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index a228ff5..c876bde 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -45,5 +45,18 @@ jobs: name: python-package-distributions path: dist/ + # Pinned by TAG, not by commit SHA -- deliberately, and unlike every + # other action in this repository. + # + # This is a Docker-based action: it derives its own image reference from + # the ref it was invoked with, so `@` makes it pull + # ghcr.io/pypa/gh-action-pypi-publish:. Upstream publishes images + # tagged by VERSION only, so no such image exists and the pull fails with + # `manifest unknown` -- after a successful build, before PyPI is ever + # contacted. Verified against the registry: the v1.14.2 and v1.14.1 SHA + # tags both 404, while `v1.14.2` and `v1.14.1` both resolve. + # + # checkout/setup-python/upload-artifact above stay SHA-pinned: they are + # JavaScript actions, where the ref selects code rather than an image. - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@a892a5a61159132606e93a2fa6f4358831b04d26 # v1.14.2 + uses: pypa/gh-action-pypi-publish@v1.14.2