Skip to content

Commit 759eab8

Browse files
authored
Add GitHub Actions to PyPI trusted publishing example (#15753)
Add a complete example for the most common publishing workflow, GitHub Actions to PyPI, with screenshots for settings and a standalone companion repo. Closes #14398
1 parent d5012c6 commit 759eab8

File tree

5 files changed

+78
-1
lines changed

5 files changed

+78
-1
lines changed
82.8 KB
Loading
101 KB
Loading
24.6 KB
Loading

docs/guides/integration/github.md

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,3 +342,74 @@ steps:
342342
https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
343343
[repository secret]:
344344
https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository
345+
346+
## Publishing to PyPI
347+
348+
uv can be used to build and publish your package to PyPI from GitHub Actions. We provide a
349+
standalone example alongside this guide in
350+
[astral-sh/trusted-publishing-examples](https://github.com/astral-sh/trusted-publishing-examples).
351+
The workflow uses [trusted publishing](https://docs.pypi.org/trusted-publishers/), so no credentials
352+
need to be configured.
353+
354+
In the example workflow, we use a script to test that the source distribution and the wheel are both
355+
functional and we didn't miss any files. This step is recommended, but optional.
356+
357+
First, add a release workflow to your project:
358+
359+
```yaml title=".github/workflows/publish.yml"
360+
name: "Publish"
361+
362+
on:
363+
push:
364+
tags:
365+
# Publish on any tag starting with a `v`, e.g., v0.1.0
366+
- v*
367+
368+
jobs:
369+
run:
370+
runs-on: ubuntu-latest
371+
environment:
372+
name: pypi
373+
permissions:
374+
id-token: write
375+
contents: read
376+
steps:
377+
- name: Checkout
378+
uses: actions/checkout@v5
379+
- name: Install uv
380+
uses: astral-sh/setup-uv@v6
381+
- name: Install Python 3.13
382+
run: uv python install 3.13
383+
- name: Build
384+
run: uv build
385+
# Check that basic features work and we didn't miss to include crucial files
386+
- name: Smoke test (wheel)
387+
run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py
388+
- name: Smoke test (source distribution)
389+
run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py
390+
- name: Publish
391+
run: uv publish
392+
```
393+
394+
Then, create the environment defined in the workflow in the GitHub repository under "Settings" ->
395+
"Environments".
396+
397+
![GitHub settings dialog showing how to add the "pypi" environment under "Settings" -> "Environments"](../../assets/github-add-environment.png)
398+
399+
Add a [trusted publisher](https://docs.pypi.org/trusted-publishers/adding-a-publisher/) to your PyPI
400+
project in the project settings under "Publishing". Ensure that all fields match with your GitHub
401+
configuration.
402+
403+
![PyPI project publishing settings dialog showing how to set all fields for a trusted publisher configuration](../../assets/pypi-add-trusted-publisher.png)
404+
405+
After saving:
406+
407+
![PyPI project publishing settings dialog showing the configured trusted publishing settings](../../assets/pypi-with-trusted-publisher.png)
408+
409+
Finally, tag a release and push it. Make sure it starts with `v` to match the pattern in the
410+
workflow.
411+
412+
```console
413+
$ git tag -a v0.1.0 -m v0.1.0
414+
$ git push --tags
415+
```

docs/guides/package.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ hello-world 1.3.1b2 => 1.3.1
121121

122122
## Publishing your package
123123

124+
!!! note
125+
126+
A complete guide to publishing from GitHub Actions to PyPI can be found in the
127+
[GitHub Guide](integration/github.md#publishing-to-pypi)
128+
124129
Publish your package with `uv publish`:
125130

126131
```console
@@ -129,7 +134,8 @@ $ uv publish
129134

130135
Set a PyPI token with `--token` or `UV_PUBLISH_TOKEN`, or set a username with `--username` or
131136
`UV_PUBLISH_USERNAME` and password with `--password` or `UV_PUBLISH_PASSWORD`. For publishing to
132-
PyPI from GitHub Actions, you don't need to set any credentials. Instead,
137+
PyPI from GitHub Actions or another Trusted Publisher, you don't need to set any credentials.
138+
Instead,
133139
[add a trusted publisher to the PyPI project](https://docs.pypi.org/trusted-publishers/adding-a-publisher/).
134140

135141
!!! note

0 commit comments

Comments
 (0)