PyPI publishing¶
Applies only when the project was generated with enable_pypi_publishing: true
(otherwise release.yml still makes the GitHub release but omits the publish
step). When enabled, release.yml publishes to PyPI automatically on a v* tag.
Authentication uses OIDC trusted publishing — no API token stored in GitHub
secrets.
One-time setup on PyPI¶
- Register at pypi.org and enable 2FA (required since 2024)
- Go to Account → Publishing → Add a new pending publisher
- Fill in:
- PyPI project name: your package name
- GitHub owner: your GitHub username or org
- Repository name: your repo name
- Workflow filename:
release.yml - Environment name: (leave blank)
- Click Add
That's it. The workflow handles authentication automatically — no token, no secret.
Trigger a release¶
Releases are triggered automatically on every merge to main (versioning.yml bumps + tags, then dispatches release.yml). To trigger manually:
The release.yml workflow will:
- Build wheel + sdist with
uv build - Create a GitHub release with the dist files attached
- Publish to PyPI with
uv publish --trusted-publishing auto
Test PyPI¶
To publish to test.pypi.org first, add a pending publisher there (same steps). Then temporarily edit release.yml:
- name: Publish to Test PyPI
run: uv publish --trusted-publishing auto --publish-url https://test.pypi.org/legacy/
Manual publish (local)¶
Requires a PyPI API token:
Zenodo archiving¶
If the Zenodo webhook is enabled, every GitHub release automatically creates a Zenodo record. See CITATION.cff for the metadata format. After the first release, copy the concept DOI from Zenodo and add it to CITATION.cff.