Skip to content

Commit d853683

Browse files
committed
feat: releases ship with PEP 740 attestations
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 8ebf45d commit d853683

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
@@ -69,6 +69,13 @@ jobs:
6969
echo "__version__ = \"$VERSION\" # x-release-please-version" > {{ package_name }}/__version__.py
7070

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

0 commit comments

Comments
 (0)