Summary
Releases are currently published to PyPI by hand: build sdist/wheel locally,
then twine upload. This is error-prone (forgotten artifacts, wrong version,
local environment drift) and forces the release token to live on a maintainer's
machine. A workflow triggered by release: published would build and upload
automatically, using PyPI Trusted Publishers (OIDC) instead of a long-lived
API token.
PyPI now supports "trusted publishing" via OpenID Connect, so projects can
authenticate publishes from GitHub Actions without storing an API token.
— https://docs.pypi.org/trusted-publishers/
Root cause
No automation exists today:
Releases rely on a maintainer running python -m build && twine upload locally,
which makes the publish step manual, untraceable, and dependent on whoever holds
the PyPI token.
Fix
Add .github/workflows/publish.yml that fires on release: published, builds
with python -m build, and publishes via pypa/gh-action-pypi-publish using
OIDC (no token stored in the repo):
name: Publish to PyPI
on:
release:
types: [published]
jobs:
publish:
runs-on: ubuntu-latest
environment: pypi
permissions:
id-token: write # required for trusted publishing
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: \"3.12\"
- run: python -m pip install --upgrade build
- run: python -m build
- uses: pypa/gh-action-pypi-publish@release/v1
Prerequisite: register the repo as a Trusted Publisher on PyPI
(`Account → Publishing → Add a new pending publisher`), specifying workflow
`publish.yml` and environment `pypi`.
Affected locations
| File |
Line(s) |
Context |
| `.github/workflows/publish.yml` |
new file |
Workflow triggered by GitHub Release |
| `pyproject.toml` |
13 |
Version source for the published artifact (already declared) |
Summary
Releases are currently published to PyPI by hand: build sdist/wheel locally,
then
twine upload. This is error-prone (forgotten artifacts, wrong version,local environment drift) and forces the release token to live on a maintainer's
machine. A workflow triggered by
release: publishedwould build and uploadautomatically, using PyPI Trusted Publishers (OIDC) instead of a long-lived
API token.
Root cause
No automation exists today:
Releases rely on a maintainer running
python -m build && twine uploadlocally,which makes the publish step manual, untraceable, and dependent on whoever holds
the PyPI token.
Fix
Add
.github/workflows/publish.ymlthat fires onrelease: published, buildswith
python -m build, and publishes viapypa/gh-action-pypi-publishusingOIDC (no token stored in the repo):
Prerequisite: register the repo as a Trusted Publisher on PyPI
(`Account → Publishing → Add a new pending publisher`), specifying workflow
`publish.yml` and environment `pypi`.
Affected locations