1- name : Release (TestPyPI)
1+ name : Release
22
33on :
44 workflow_dispatch :
55
66permissions :
77 contents : read
88
9- # Matches ci.yml: bash everywhere keeps the make recipes portable across the runner images.
109defaults :
1110 run :
1211 shell : bash
1312
1413jobs :
15- release :
16- name : Publish to TestPyPI
14+ build :
15+ name : Build distribution
1716 runs-on : ubuntu-latest
1817 timeout-minutes : 15
19- permissions :
20- contents : read
21- # OIDC token for PyPI trusted publishing, scoped to this job so nothing else in the
22- # workflow can mint one. Job-level permissions replace the workflow-level block outright,
23- # so contents: read has to be repeated here for the checkout.
24- id-token : write
2518 steps :
2619 - uses : actions/checkout@v5
2720
@@ -30,18 +23,45 @@ jobs:
3023 with :
3124 enable-cache : true
3225
33- # The same target CI and the pre-push hook run, so the release path cannot drift from the
34- # checks: it builds into dist/, validates the metadata with twine, and imports the wheel in
35- # a throwaway environment. It leaves dist/ in place, which is what gets published below.
3626 - run : make dist-check
3727
38- # No username, password or token: the TestPyPI trusted publisher is matched on this
39- # repository and on this workflow's filename, so renaming this file breaks publishing.
40- #
41- # Deliberately no skip-existing. A version already present on the index should fail the run
42- # loudly rather than pass as a no-op, because neither index allows a version to be
43- # re-uploaded once taken -- the fix is always a new version, never a retry.
28+ - uses : actions/upload-artifact@v4
29+ with :
30+ name : dist
31+ path : dist/
32+
33+ testpypi :
34+ name : Publish to TestPyPI
35+ needs : build
36+ runs-on : ubuntu-latest
37+ timeout-minutes : 15
38+ permissions :
39+ contents : read
40+ id-token : write
41+ steps :
42+ - uses : actions/download-artifact@v4
43+ with :
44+ name : dist
45+ path : dist/
46+
4447 - name : Publish to TestPyPI
4548 uses : pypa/gh-action-pypi-publish@release/v1
4649 with :
4750 repository-url : https://test.pypi.org/legacy/
51+
52+ pypi :
53+ name : Publish to PyPI
54+ needs : testpypi
55+ runs-on : ubuntu-latest
56+ timeout-minutes : 15
57+ permissions :
58+ contents : read
59+ id-token : write
60+ steps :
61+ - uses : actions/download-artifact@v4
62+ with :
63+ name : dist
64+ path : dist/
65+
66+ - name : Publish to PyPI
67+ uses : pypa/gh-action-pypi-publish@release/v1
0 commit comments