Releasing to PyPI
=================
Maintainer-facing notes for cutting a release. Contributors do not
need to read this section.
Releases publish to PyPI via the
`Trusted Publishers / OIDC `__
workflow (:file:`.github/workflows/publish_to_pypi.yml`). No
long-lived ``PYPI_API_TOKEN`` secret is stored in the repository.
One-time setup (release blocker for the first publish)
------------------------------------------------------
The OIDC workflow fails with ``invalid-publisher`` until a trusted
publisher is configured on the PyPI side. Because the project has
never been uploaded, the per-project settings page does not exist
yet — use the **pending publisher** form instead, which lets PyPI
pre-authorize a name and convert it to a real publisher on the first
successful upload.
1. Determine the GitHub owner / repo from the remote URL:
.. code-block:: bash
git remote get-url origin
# → e.g. https://github.com//.git
Use the exact ```` / ```` strings from that output,
case-sensitive, in the steps below.
2. On https://pypi.org/manage/account/publishing/, scroll to
"Add a new pending publisher" → "GitHub":
* PyPI Project Name: ``rms-picmaker``
* Owner: ```` (from step 1)
* Repository name: ```` (from step 1)
* Workflow filename: ``publish_to_pypi.yml``
* Environment name: ``pypi``
The project name must be available — PyPI rejects the form if
someone has reserved it.
3. Repeat on https://test.pypi.org/manage/account/publishing/ with
workflow filename ``publish_to_test_pypi.yml`` and environment
name ``testpypi``. TestPyPI is a separate registry with its own
name reservations and its own pending publisher list.
4. In the GitHub repo, configure Environments → New environment
``pypi`` (and ``testpypi``). The publish jobs run inside these
environments so PyPI can verify the OIDC claim.
5. After the first successful upload, the pending publisher promotes
to a regular trusted publisher and the per-project settings page
(https://pypi.org/manage/project/rms-picmaker/settings/publishing/)
becomes the place to manage it going forward.
Cutting a release
-----------------
1. Ensure CI is green on the branch you intend to tag.
2. Tag the commit and push the tag:
.. code-block:: bash
git tag v0.1.0
git push --tags
:file:`publish_to_pypi.yml` fires on ``release: published``, so
creating a GitHub Release pointing at the tag triggers the
upload. To dry-run against TestPyPI first, trigger
:file:`publish_to_test_pypi.yml` manually from the Actions tab.
3. After the upload completes, verify the release at
https://pypi.org/project/rms-picmaker/.