Publishing releases¶
Releases use the dedicated .github/workflows/release.yml workflow and PyPI
Trusted Publishing. GitHub obtains short-lived credentials through OpenID
Connect; no PyPI API tokens belong in repository or environment secrets.
One-time publisher setup¶
PyPI and TestPyPI use separate accounts and publisher registrations. Use the PyPI publisher settings and TestPyPI publisher settings to register the following pending GitHub publishers before the first release:
Index |
Project |
Owner |
Repository |
Workflow |
Environment |
|---|---|---|---|---|---|
PyPI |
|
|
|
|
|
TestPyPI |
|
|
|
|
|
Create matching pypi and testpypi GitHub environments. Restrict both
environments to tags matching v*, and require approval from a repository
maintainer on pypi. TestPyPI does not require an approval because production
cannot run until its upload succeeds.
Release sequence¶
Set the version in
pyproject.toml, refreshuv.lock, and replaceUnreleasedinCHANGELOG.mdwith the release date.Run the complete validation suite from
CONTRIBUTING.md.Merge the release commit into
mainand confirm all required checks pass.Create an annotated tag whose name exactly matches
v<project-version>, then push it:git tag -a v0.1.0a1 -m "Release 0.1.0a1" git push origin v0.1.0a1
The release workflow builds and validates one wheel and source distribution, then uploads those exact artifacts to TestPyPI.
Inspect the TestPyPI project and test installation in a clean environment:
python -m pip install \ --index-url https://test.pypi.org/simple/ \ --extra-index-url https://pypi.org/simple/ \ "stoch-ir==0.1.0a1"
Approve the waiting
pypienvironment deployment. The workflow publishes the previously tested artifacts to PyPI with digital attestations.Create the corresponding GitHub release from the existing tag.
Published filenames and versions cannot be replaced. Fix any release problem with a new version rather than moving or recreating its tag.