Releasing¶
fountain-py publishes to PyPI and deploys its docs automatically when you cut a GitHub Release. You never handle a PyPI token: publishing uses PyPI trusted publishing over OIDC.
How a Release Works¶
Publishing a GitHub Release (the release: published event) fires two workflows:
.github/workflows/publish.ymlbuilds the package and runsuv publish, which authenticates to PyPI through the repository’s OIDC identity and uploads the wheel and sdist..github/workflows/docs.ymlbuilds the Sphinx docs and deploys them to GitHub Pages.
The publish job runs only after its test and build jobs pass. It runs in the pypi deployment environment with id-token: write, which is what lets PyPI trust it.
Cutting a Release¶
Make sure
mainis green and holds the code you want to ship.Bump
versionunder[project]inpyproject.tomlto the new version, and merge that tomain.Create a GitHub Release whose tag is the version prefixed with
v(for examplev0.1.0), targetingmain:gh release create v0.1.0 --target main --title "v0.1.0" --generate-notes
Publishing the Release is what triggers the workflows. A plain tag push does not.
Verifying¶
Watch the runs, then confirm the results:
gh run watch
Install the published version in a clean environment to smoke-test it:
pip install fountain-py
One-Time Setup¶
These are already configured. This section records them so a new maintainer can reproduce them.
PyPI trusted publisher for the
fountain-pyproject: ownerMasonEgger, repositoryfountain-py, workflowpublish.yml, environmentpypi. Before the first release the project does not exist on PyPI, so this is added as a pending publisher under PyPI account publishing. The first successful publish creates the project and activates the publisher.GitHub environments:
pypi(used bypublish.yml) andgithub-pages(used bydocs.yml).GitHub Pages: enabled with GitHub Actions as the build source. The
github-pagesenvironment allows deployments frommainand fromv*tags, so both the push-to-main and the release-triggered docs deploys succeed.
Troubleshooting¶
The publish step returns 403. PyPI has no trusted publisher matching the upload. Confirm the publisher’s project name reads
fountain-pyand that the owner, repository, workflow filename (publish.yml), and environment (pypi) all match.The release-triggered docs deploy fails while the push-to-main deploy succeeded. The
github-pagesenvironment is rejecting the tag ref. Add a deployment branch policy that allowsv*tags.