Publishing to PyPI¶
docsynth publishes to PyPI via Trusted
Publishing — GitHub Actions mints a short-lived OIDC token that PyPI verifies,
so there is no API token stored in the repo or in GitHub secrets. The
release.yml
workflow does the work; you cut a GitHub Release and it builds and uploads.
One-time setup¶
Two things, done once.
1. Trusted publisher on PyPI¶
The docsynth project already exists (a 0.0.0 placeholder reserved the name),
so add the publisher to the existing project:
-
pypi.org → Your projects →
docsynth→ Manage → Publishing → Add a trusted publisher (GitHub tab):Field Value Owner kashodevRepository docsynthWorkflow name release.ymlEnvironment pypi
2. A pypi environment on GitHub¶
release.yml's publish job runs in an environment named pypi (which the
publisher above is scoped to):
- GitHub → Settings → Environments → New environment →
pypi. - Recommended protection: Deployment branches and tags → restrict to tags
matching
v*, so a publish can only originate from a release tag.
Cut a release¶
- Bump the version in
pyproject.toml([project].version) on a branch and merge it (CI must pass). Follow SemVer:0.1.0,0.1.1,0.2.0, … -
Tag + release. Create a GitHub Release whose tag is
v<version>(e.g.v0.1.0) targetingmain. Publishing the release triggersrelease.yml.# tag matches [project].version, prefixed with v git tag v0.1.0 && git push origin v0.1.0 # then: GitHub → Releases → Draft a new release → pick the tag → Publish -
The workflow verifies the tag matches
[project].version, builds the sdist + wheel, runstwine check, and uploads to PyPI via OIDC. - Verify: the new version appears at
pypi.org/project/docsynth, and
pip install docsynthinstalls it.
First real release
[project].version is already 0.1.0, so the first release tag is v0.1.0.
The 0.0.0 placeholder can be left as-is or yanked
(Manage → Releases → 0.0.0 → Yank) — yanking hides it from resolvers
without deleting the name.
Test the build before releasing¶
The build is fully reproducible locally — no need to release to check it:
pip install build twine
python -m build # -> dist/*.whl and dist/*.tar.gz
twine check dist/* # metadata/README render check
For an end-to-end dry run, add a TestPyPI trusted publisher (same fields, on
test.pypi.org) and publish a pre-release tag to it
first; the docsynth name is free there.
After the first PyPI release¶
Flip the Quickstart and the README install to PyPI-first
(pip install 'docsynth[studio]') now that it resolves to a real package.