Skip to content

Commit 28d0825

Browse files
feat: releases ship with PEP 740 attestations (#24)
uv publish uploads attestations it is given but does not create them, so no release in the org had provenance on PyPI, although the publish job already holds the OIDC token Sigstore signs with. The publish job now runs pypi-attestations sign over the built wheel and sdist before uploading. It writes <file>.publish.attestation next to each, and uv publish, with its default dist/* file set, sends them along. PyPI verifies each attestation against the Trusted Publisher and rejects the upload if one does not match, so a broken signature fails the release instead of shipping without provenance. Closes #13
1 parent 00ac431 commit 28d0825

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

‎template/.github/workflows/publish.yml.jinja‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,13 @@ jobs:
148148
- uses: astral-sh/setup-uv@v7
149149

150150
- run: uv build
151-
# --check-url: a run repeated after a failure skips what is already on the
152-
# index instead of failing on it.
151+
# PEP 740 provenance. uv publish uploads attestations but does not make
152+
# them: this signs each distribution with the job's OIDC identity
153+
# (Sigstore) into <file>.publish.attestation, and PyPI rejects an upload
154+
# whose attestation does not match the Trusted Publisher.
155+
- run: uvx --from 'pypi-attestations>=0.0.30' pypi-attestations sign dist/*.whl dist/*.tar.gz
156+
# No file arguments: uv's default, dist/*, takes in the .attestation files
157+
# too; naming the distributions would upload them without their
158+
# attestations. --check-url: a run repeated after a failure skips what is
159+
# already on the index instead of failing on it.
153160
- run: uv publish --check-url https://pypi.org/simple/{{ project_slug }}/

0 commit comments

Comments
 (0)