1
1
[ ![ SWUbanner]] [ SWUdocs ]
2
2
3
+ ![ PyPA badge]
3
4
[ ![ 🧪 GitHub Actions CI/CD workflow tests badge]] [ GHA workflow runs list ]
4
5
[ ![ pre-commit.ci status badge]] [ pre-commit.ci results page ]
6
+ [ ![ GH Sponsors badge]] [ GH Sponsors URL ]
5
7
6
8
# PyPI publish GitHub Action
7
9
@@ -13,6 +15,10 @@ walkthrough check out the [PyPA guide].
13
15
If you have any feedback regarding specific action versions, please leave
14
16
comments in the corresponding [ per-release announcement discussions] .
15
17
18
+ > [ !TIP]
19
+ > A limited number of usage scenarios is supported, including the
20
+ > [ PyPA guide] example. See the [ non-goals] for more detail.
21
+
16
22
17
23
## 🌇 ` master ` branch sunset ❗
18
24
@@ -131,6 +137,9 @@ same identity.
131
137
This GitHub Action [has nothing to do with _building package
132
138
distributions_]. Users are responsible for preparing dists for upload
133
139
by putting them into the `dist/` folder prior to running this Action.
140
+ They are typically expected to do this in a _separate GitHub Actions
141
+ CI/CD job_ running before the one where they call this action and having
142
+ restricted privileges.
134
143
135
144
> [!IMPORTANT]
136
145
> Since this GitHub Action is docker-based, it can only
@@ -155,6 +164,72 @@ by putting them into the `dist/` folder prior to running this Action.
155
164
> sharing the built dists across stages and jobs. Then, use the `needs`
156
165
> setting to order the build, test and publish stages.
157
166
167
+ The expected environment for running `pypi-publish` is the
168
+ GitHub-provided Ubuntu VM. We are running a smoke-test against
169
+ ` ubuntu-latest` in CI but any currently available numbered versions
170
+ should do. We'll consider them supported for as long as GitHub itself
171
+ supports them.
172
+
173
+ Running the action in a job that has a `container:` set is not
174
+ supported. It might work for you but you're on your own when it breaks.
175
+ If you feel the need to use it, it's likely that you're not following
176
+ the recommendation of invoking the build automation in a separate job,
177
+ which is considered a security issue (especially, when using [Trusted
178
+ Publishing][trusted publisher] that may cause privilege escalation and
179
+ would enable the attackers to impersonate the GitHub-backed identity of
180
+ the repository through transitive build dependency poisoning). The
181
+ solution is to have one job (or multiple, in case of projects with
182
+ C-extensions) for building the distribution packages, followed by
183
+ another that publishes them.
184
+
185
+ Self-hosted runners are best effort, provided no other unsupported
186
+ things influence them. We are unable to test this in CI and they may
187
+ break. This is often the case when using custom runtimes and not the
188
+ official GitHub-provided VMs. In general, if you follow the
189
+ recommendation of building in a separate job, you shouldn't need to run
190
+ this action within a self-hosted runner — it should be possible to
191
+ build your dists in a self-hosted runner, save them as a GitHub Actions
192
+ artifact in that job, and then invoke the publishing job that would run
193
+ within GitHub-provided runners, downloading the artifact with the dists
194
+ and publishing them. Such separation is the _recommended_/**supported**
195
+ way of handling this scenario.
196
+ Our understandng is that Trusted publishing is expected to work on
197
+ self-hosted runners. It is backed by OIDC. If it doesn't work, you
198
+ should probably ask GitHub if you missed something. We wouldn't be able
199
+ to assist here.
200
+
201
+ Trusted Publishing cannot be tested in CI at the moment, sadly. It is
202
+ supported and bugs should be reported but it may take time to sort out
203
+ as it often requires cross-project collaboration to debug (sometimes,
204
+ problems occur due to changes in PyPI and not in the action).
205
+
206
+ The only case that is explicitly unsupported at the moment is [Trusted
207
+ Publishing][trusted publisher] in reusable workflows. This requires
208
+ support on the PyPI side and is being worked on. Please, do not report
209
+ bugs related to this case. The current recommendation is to put
210
+ everything else you want into a reusable workflow but keep the job
211
+ calling `pypi-publish` in a top-level one.
212
+
213
+ Invoking `pypi-publish` from composite actions is unsupported. It is not
214
+ tested. GitHub Runners have limitations and bugs in this case. But more
215
+ importantly, this is usually an indication of using it insecurely. When
216
+ using [Trusted Publishing][trusted publisher], it is imperative to keep
217
+ build machinery invocation in a separate job with restrictive privileges
218
+ as [Trusted Publishing][trusted publisher] itself requires elevated
219
+ permissions to make use of OIDC. Our observation is that the users
220
+ sometimes create in-project composite actions that invoke building and
221
+ publishing in the same job. As such, we don't seek to support such a
222
+ dangerous configuration in the first place. The solution is pretty much
223
+ the same as with the previous problem — use a separate job with
224
+ dedicated and scoped privileges just for publishing; and invoke that
225
+ in-project composite action from a different job.
226
+
227
+ And finally, invoking `pypi-publish` more than once in the same job is
228
+ not considered supported. It may work in a limited number of scenarios
229
+ but please, don't do this. If you want to publish to several indexes,
230
+ build the dists in one job and add several publishing jobs, one per
231
+ upload.
232
+
158
233
159
234
# # Advanced release management
160
235
@@ -277,6 +352,8 @@ on supported platforms (like GitHub).
277
352
The Dockerfile and associated scripts and documentation in this project
278
353
are released under the [BSD 3-clause license](LICENSE.md).
279
354
355
+ [PyPA badge] :
356
+ https://img.shields.io/badge/project-yellow?label=PyPA&labelColor=ffd242&color=3775a9
280
357
281
358
[🧪 GitHub Actions CI/CD workflow tests badge] :
282
359
https://github.com/pypa/gh-action-pypi-publish/actions/workflows/build-and-push-docker-image.yml/badge.svg?branch=unstable%2Fv1&event=push
@@ -288,12 +365,24 @@ https://results.pre-commit.ci/latest/github/pypa/gh-action-pypi-publish/unstable
288
365
[pre-commit.ci status badge] :
289
366
https://results.pre-commit.ci/badge/github/pypa/gh-action-pypi-publish/unstable/v1.svg
290
367
368
+ [docs badge] :
369
+ https://img.shields.io/badge/guide-gray?logo=readthedocs&label=PyPUG&color=white
370
+ [PyPUG guide] :
371
+ https://packaging.python.org/en/latest/guides/publishing-package-distribution-releases-using-github-actions-ci-cd-workflows/
372
+
373
+ [GH Sponsors badge] :
374
+ https://img.shields.io/badge/%40webknjaz-transparent?logo=githubsponsors&logoColor=%23EA4AAA&label=Sponsor&color=2a313c
375
+ [GH Sponsors URL] :
376
+ https://github.com/sponsors/webknjaz
377
+
291
378
[use a full Git commit SHA] :
292
379
https://julienrenaux.fr/2019/12/20/github-actions-security-risk/
293
380
294
381
[per-release announcement discussions] :
295
382
https://github.com/pypa/gh-action-pypi-publish/discussions/categories/announcements
296
383
384
+ [non-goals] : # Non-goals
385
+
297
386
[Creating & using secrets] :
298
387
https://help.github.com/en/actions/automating-your-workflow-with-github-actions/creating-and-using-encrypted-secrets
299
388
[has nothing to do with _building package distributions_] :
0 commit comments