Publishing to PyPI (maintainers)
Releases use trusted publishing (OpenID Connect): GitHub Actions proves the workflow’s identity to TestPyPI and PyPI without long-lived API tokens. Configure the workflow file .github/workflows/publish-pypi.yml as the trusted workflow on both indexes (exact filename PyPI expects is publish-pypi.yml).
GitHub
- Settings → Environments → New environment → name it
pypi(must matchjobs.publish.environmentin the workflow). - Optional: add protection rules (required reviewers, wait timer) before the job can request the OIDC token.
TestPyPI
- Create test.pypi.org account and project
coconet-pythonif needed. - Project → Settings → Publishing → Add a new pending publisher (or trusted publisher).
- Choose GitHub as the publisher; set repository and owner to match this repo.
- Workflow name:
publish-pypi.yml(filename under.github/workflows/). - Environment:
pypi(same as GitHub).
PyPI
- Project → Settings → Publishing on pypi.org.
- Add the same GitHub publisher: same repo, workflow
publish-pypi.yml, environmentpypi.
PyPI and TestPyPI each store their own trusted-publisher record; both must be configured for the two-step CI (TestPyPI → smoke install → PyPI).
When publishing runs
- GitHub Release published → workflow runs on that release’s commit.
- workflow_dispatch → manual run (use with care; still uploads whatever version is in
pyproject.tomlon the selected branch).
Troubleshooting
id-token: writemust be granted on the job (the workflow sets this).- If uploads fail with credential or OIDC errors, run locally with
uv publish --trusted-publishing alwaysfor clearer messages (uv note). - Version reuse: a given version can only be uploaded once per index; bump
versioninpyproject.tomlbefore a new release.
See also: uv + GitHub Actions, PyPI trusted publishers.