Skip to content

Commit 523919a

Browse files
author
Guillaume Lessard
committed
feat(release): complete CI-based publishing, matching the proven 0.6.9 flow
Verified against the workflow that shipped 0.6.5 -> 0.6.9: it publishes from CI with pypa/gh-action-pypi-publish via OIDC Trusted Publishing, not by local twine upload. (RELEASE_NOTES' mention of "twine upload" describes an earlier iteration; the shipped file uses the action.) Restored the two pieces that were still missing. skip-existing: true. PyPI refuses re-uploading a file that already exists, so without it a run that uploaded 9 of 15 wheels and then failed could never be retried - the retry dies on the first duplicate and the release is stuck half-published with no way forward. This is the difference between a recoverable and an unrecoverable release failure, and it was in the proven flow. Artifact attestation, non-gating, exactly as commit 49ba957 established: `continue-on-error: true` and skipped on private repos, because provenance needs a public repo or GHAS and its absence must never fail an otherwise-good release. Adds the `attestations: write` permission it requires.
1 parent 7a5b839 commit 523919a

1 file changed

Lines changed: 20 additions & 3 deletions

File tree

.github/workflows/release-build.yml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -195,8 +195,9 @@ jobs:
195195
name: pypi
196196
url: https://pypi.org/p/qector-decoder-v3
197197
permissions:
198-
id-token: write
198+
id-token: write # PyPI Trusted Publishing (OIDC) — no stored token
199199
contents: read
200+
attestations: write # build provenance, non-gating (see 49ba957)
200201
steps:
201202
- uses: actions/checkout@v4
202203
- uses: actions/setup-python@v5
@@ -251,8 +252,24 @@ jobs:
251252
pip install twine
252253
twine check dist/*.whl
253254
254-
- name: Publish
255+
# Non-gating by design: commit 49ba957 ("artifact attestation must not gate
256+
# publishing"). Provenance requires a public repo or GHAS, and on a private
257+
# repo the API returns "Feature not available", which must not fail a
258+
# release that is otherwise good.
259+
- name: Generate artifact attestations
260+
if: ${{ github.event.repository.private == false }}
261+
continue-on-error: true
262+
uses: actions/attest-build-provenance@v2
263+
with:
264+
subject-path: "dist/*"
265+
266+
- name: Publish to PyPI
255267
uses: pypa/gh-action-pypi-publish@release/v1
256268
with:
257269
packages-dir: dist/
258-
attestations: true
270+
# Idempotent upload. PyPI rejects re-uploading a file that already
271+
# exists, so without this a run that uploaded 9 of 15 wheels and then
272+
# failed could never be retried - the retry would die on the first
273+
# duplicate and the release would be stuck half-published. With it,
274+
# a re-run completes the remaining wheels.
275+
skip-existing: true

0 commit comments

Comments
 (0)