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.
3
9
4
10
name : " Packages"
5
11
@@ -108,19 +114,47 @@ jobs:
108
114
name : sdist
109
115
path : dist/*.tar.gz
110
116
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
+
111
137
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
+
112
145
needs :
113
146
- " build_wheels"
114
147
- " build_sdist"
115
148
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.
118
149
runs-on : " ubuntu-latest"
119
150
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
124
158
125
159
steps :
126
160
# Download all artifacts previously built by this workflow to the dist
@@ -132,43 +166,44 @@ jobs:
132
166
path : " dist"
133
167
merge-multiple : true
134
168
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"
148
183
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"
149
198
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
171
202
203
+ - name : " Publish to TestPyPI"
204
+ uses : " pypa/gh-action-pypi-publish@v1.12.4"
172
205
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