Skip to content

Commit 801b64f

Browse files
authored
Merge pull request #129 from tahoe-lafs/127.pypi-trusted-publishing
Use trusted publishing with both PyPI and TestPyPI
2 parents f487a22 + 308bcc7 commit 801b64f

File tree

1 file changed

+79
-44
lines changed

1 file changed

+79
-44
lines changed

.github/workflows/build.yml

+79-44
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
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

410
name: "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

Comments
 (0)