Releasing to PyPI¶
capsule is published to PyPI as capscorp. The distribution name differs from
the repository (capsule-corp) and from the command (capsule); only the command is
something you type regularly.
Releases use trusted publishing, so no API token is ever created or stored. PyPI verifies the release came from this repository's workflow via OpenID Connect.
One-time setup¶
You only do this once. Steps 1–4 are on the PyPI website.
1. Sign in to PyPI¶
https://pypi.org/account/login/ — create an account if you don't have one. Two-factor authentication is mandatory for publishing, so enable it if prompted.
2. Open the pending-publisher form¶
Go to https://pypi.org/manage/account/publishing/.
Because capscorp does not exist on PyPI yet, use the "Add a new pending
publisher" section at the bottom of that page — not the per-project form, which only
appears once a project exists. A pending publisher reserves the name and lets the very
first upload create the project.
3. Fill in exactly these values¶
| Field | Value |
|---|---|
| PyPI Project Name | capscorp |
| Owner | lenzpracher |
| Repository name | capsule-corp |
| Workflow name | release.yml |
| Environment name | pypi |
The environment name matters: release.yml declares environment: name: pypi, and
PyPI will reject the upload if the two disagree.
Click Add.
4. (Optional) Add the GitHub environment¶
https://github.com/lenzpracher/capsule-corp/settings/environments → New
environment → name it pypi.
This is optional — the workflow works without it — but it gives you a place to add a required reviewer later, so a release cannot go out without an explicit approval.
Cutting a release¶
Everything from here is in the repository.
- Bump the version in
pyproject.toml:
- Commit it, and tag with a matching
vprefix:
- The
releaseworkflow builds an sdist and a wheel, runstwine check, and publishes. It fails deliberately if the tag and the packaged version disagree, so a mistyped tag cannot publish something nobody can correlate with the repo.
Watch it at https://github.com/lenzpracher/capsule-corp/actions/workflows/release.yml.
Afterwards¶
Once the first release lands, the installer picks it up automatically — it already prefers PyPI and only falls back to git:
To install straight from a branch instead, set CAPSULE_CORP_REF:
Versioning¶
__version__ is read from installed package metadata, so pyproject.toml is the
single source of truth. This matters more than it looks: the version is recorded in
every capsule's provenance, so a version that drifts from what was actually released
makes a capsule's own record wrong.