1- # Build sdist+wheel packages using GitHub Actions. Mostly adopted
2- # from https://cibuildwheel.readthedocs.io/en/stable/setup/
1+ # Build sdist+wheel packages using GitHub Actions, and publish them on
2+ # TestPyPI (on pull requests and tags) and PyPI (on tags).
3+ #
4+ # The build_wheels job is mostly adopted from
5+ # https://cibuildwheel.readthedocs.io/en/stable/setup/
6+ #
7+ # The upload_pypi and upload_testpypi jobs are adopted from Python
8+ # Packaging User Guide.
39
410name : " Packages"
511
@@ -108,19 +114,47 @@ jobs:
108114 name : sdist
109115 path : dist/*.tar.gz
110116
117+ # Both `upload_pypi` and `upload_testpypi` jobs are based on
118+ # "Publishing package distribution releases using GitHub Actions CI/CD
119+ # workflows" page of Python Package User Guide. Specifically see the
120+ # section under "The whole CI/CD workflow".
121+ #
122+ # https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/#the-whole-ci-cd-workflow
123+ #
124+ # The important bit here is that we use GitHub Actions as the "trusted
125+ # publisher" to publish packages on both PyPI and TestPyPI. We do not
126+ # use long-lived tokens anymore. Instead, both PyPI and TestPyPI are
127+ # configured to trust this GH Actions workflow, and the workflow will
128+ # use a short-lived tokens minted by them.
129+ #
130+ # https://docs.pypi.org/trusted-publishers/
131+ #
132+ # There is a bit of duplication below but that seems to be necessary
133+ # because the environment configuration is different for PyPI and
134+ # TestPyPI. Perhaps the duplication is not necessary, but let us just
135+ # stick with the Python Package User Guide's recommendation.
136+
111137 upload_pypi :
138+ name : Publish zfec on PyPI
139+
140+ # Publish to PyPI on release tag pushes.
141+ if : >-
142+ github.event_name == 'push' &&
143+ startsWith(github.event.ref, 'refs/tags/zfec-')
144+
112145 needs :
113146 - " build_wheels"
114147 - " build_sdist"
115148
116- # It only needs to run once. It will fetch all of the other build
117- # artifacts created by the other jobs and then upload them.
118149 runs-on : " ubuntu-latest"
119150
120- # Select the GitHub Actions environment that contains the PyPI tokens
121- # necessary to perform uploads. This was configured manually using the
122- # GitHub web interface.
123- environment : " release"
151+ environment :
152+ name : " release"
153+ url : " https://pypi.org/project/zfec/"
154+
155+ # This permission is mandatory for trusted publishing
156+ permissions :
157+ id-token : write
124158
125159 steps :
126160 # Download all artifacts previously built by this workflow to the dist
@@ -132,43 +166,44 @@ jobs:
132166 path : " dist"
133167 merge-multiple : true
134168
135- # Define a conditional step to upload packages to the testing instance
136- # of PyPI.
137- #
138- # The overall workflow is already restricted so that it runs for:
139- # 1) pushes to master
140- # 2) pushes to release tags
141- # 3) pushes to branches with associated PRs
142- #
143- # The conditional in this step should cause it to run only for case (3).
144- - name : " Publish to TEST PyPI"
145- uses : " pypa/gh-action-pypi-publish@v1.6.4"
146- if : >-
147- github.event_name == 'pull_request'
169+ - name : " Publish to PyPI"
170+ uses : " pypa/gh-action-pypi-publish@v1.12.4"
171+ with :
172+ # Run `twine upload --verbose`.
173+ verbose : true
174+
175+ upload_testpypi :
176+ # Publish both builds triggered by pull requests and builds
177+ # triggered by release tags to TestPyPI.
178+ name : Publish zfec on TestPyPI
179+
180+ needs :
181+ - " build_wheels"
182+ - " build_sdist"
148183
184+ runs-on : " ubuntu-latest"
185+
186+ environment :
187+ name : " testpypi"
188+ url : " https://test.pypi.org/project/zfec/"
189+
190+ # This permission is mandatory for trusted publishing
191+ permissions :
192+ id-token : write
193+
194+ steps :
195+ # Do the same thing as the download-artfact step in
196+ # upload_testpypi job.
197+ - uses : " actions/download-artifact@v4"
149198 with :
150- # Authenticate using a token from a PyPI account with upload
151- # permission to the project. See https://pypi.org/help/#apitoken
152- user : " __token__"
153- # Read it from a GitHub Actions "environment" secret. See
154- # https://docs.github.com/en/actions/security-guides/encrypted-secrets
155- password : " ${{ secrets.testpypi_token }}"
156- # Override the default in order to upload it to the testing
157- # deployment.
158- repository_url : " https://test.pypi.org/legacy/"
159-
160- # Now define a conditional step to upload packages to the production
161- # instance of PyPI.
162- #
163- # The cases to consider are the same as for the upload to the testing
164- # instance. This time, we have a conditional that runs only for case
165- # (2).
166- - name : " Publish to LIVE PyPI"
167- uses : " pypa/gh-action-pypi-publish@v1.6.4"
168- if : >-
169- github.event_name == 'push' &&
170- startsWith(github.event.ref, 'refs/tags/zfec-')
199+ pattern : " *"
200+ path : " dist"
201+ merge-multiple : true
171202
203+ - name : " Publish to TestPyPI"
204+ uses : " pypa/gh-action-pypi-publish@v1.12.4"
172205 with :
173- user : " __token__"
174- password : " ${{ secrets.pypi_token }}"
206+ # Override the default in order to upload to TestPyPi.
207+ repository-url : https://test.pypi.org/legacy/
208+ # Run `twine upload --verbose`.
209+ verbose : true
0 commit comments