diff --git a/docs/assets/github-add-environment.png b/docs/assets/github-add-environment.png new file mode 100644 index 000000000..4ae1bb6a9 Binary files /dev/null and b/docs/assets/github-add-environment.png differ diff --git a/docs/assets/pypi-add-trusted-publisher.png b/docs/assets/pypi-add-trusted-publisher.png new file mode 100644 index 000000000..5ee793da9 Binary files /dev/null and b/docs/assets/pypi-add-trusted-publisher.png differ diff --git a/docs/assets/pypi-with-trusted-publisher.png b/docs/assets/pypi-with-trusted-publisher.png new file mode 100644 index 000000000..ebc85ecae Binary files /dev/null and b/docs/assets/pypi-with-trusted-publisher.png differ diff --git a/docs/guides/integration/github.md b/docs/guides/integration/github.md index e8a12f7f4..774c8a3df 100644 --- a/docs/guides/integration/github.md +++ b/docs/guides/integration/github.md @@ -342,3 +342,74 @@ steps: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens [repository secret]: https://docs.github.com/en/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions#creating-secrets-for-a-repository + +## Publishing to PyPI + +uv can be used to build and publish your package to PyPI from GitHub Actions. We provide a +standalone example alongside this guide in +[astral-sh/trusted-publishing-examples](https://github.com/astral-sh/trusted-publishing-examples). +The workflow uses [trusted publishing](https://docs.pypi.org/trusted-publishers/), so no credentials +need to be configured. + +In the example workflow, we use a script to test that the source distribution and the wheel are both +functional and we didn't miss any files. This step is recommended, but optional. + +First, add a release workflow to your project: + +```yaml title=".github/workflows/publish.yml" +name: "Publish" + +on: + push: + tags: + # Publish on any tag starting with a `v`, e.g., v0.1.0 + - v* + +jobs: + run: + runs-on: ubuntu-latest + environment: + name: pypi + permissions: + id-token: write + contents: read + steps: + - name: Checkout + uses: actions/checkout@v5 + - name: Install uv + uses: astral-sh/setup-uv@v6 + - name: Install Python 3.13 + run: uv python install 3.13 + - name: Build + run: uv build + # Check that basic features work and we didn't miss to include crucial files + - name: Smoke test (wheel) + run: uv run --isolated --no-project --with dist/*.whl tests/smoke_test.py + - name: Smoke test (source distribution) + run: uv run --isolated --no-project --with dist/*.tar.gz tests/smoke_test.py + - name: Publish + run: uv publish +``` + +Then, create the environment defined in the workflow in the GitHub repository under "Settings" -> +"Environments". + +![GitHub settings dialog showing how to add the "pypi" environment under "Settings" -> "Environments"](../../assets/github-add-environment.png) + +Add a [trusted publisher](https://docs.pypi.org/trusted-publishers/adding-a-publisher/) to your PyPI +project in the project settings under "Publishing". Ensure that all fields match with your GitHub +configuration. + +![PyPI project publishing settings dialog showing how to set all fields for a trusted publisher configuration](../../assets/pypi-add-trusted-publisher.png) + +After saving: + +![PyPI project publishing settings dialog showing the configured trusted publishing settings](../../assets/pypi-with-trusted-publisher.png) + +Finally, tag a release and push it. Make sure it starts with `v` to match the pattern in the +workflow. + +```console +$ git tag -a v0.1.0 -m v0.1.0 +$ git push --tags +``` diff --git a/docs/guides/package.md b/docs/guides/package.md index c6017986d..5ca8aea8e 100644 --- a/docs/guides/package.md +++ b/docs/guides/package.md @@ -121,6 +121,11 @@ hello-world 1.3.1b2 => 1.3.1 ## Publishing your package +!!! note + + A complete guide to publishing from GitHub Actions to PyPI can be found in the + [GitHub Guide](integration/github.md#publishing-to-pypi) + Publish your package with `uv publish`: ```console @@ -129,7 +134,8 @@ $ uv publish Set a PyPI token with `--token` or `UV_PUBLISH_TOKEN`, or set a username with `--username` or `UV_PUBLISH_USERNAME` and password with `--password` or `UV_PUBLISH_PASSWORD`. For publishing to -PyPI from GitHub Actions, you don't need to set any credentials. Instead, +PyPI from GitHub Actions or another Trusted Publisher, you don't need to set any credentials. +Instead, [add a trusted publisher to the PyPI project](https://docs.pypi.org/trusted-publishers/adding-a-publisher/). !!! note