PyPI publishing (maintainers)
Releases use Trusted Publishing (OIDC) — no long-lived PyPI password in GitHub secrets.
One-time PyPI setup
- Create the project on PyPI if it does not exist yet (
easy-asomust matchnameinpyproject.toml). - Open Your project → Publishing (or account Publishing for a new pending publisher).
- Add a new pending publisher → GitHub:
- Repository:
bbartling/easy-aso - Workflow name:
publish-pypi.yml(file under.github/workflows/) - Environment name: leave blank unless you add a GitHub Environment named
pypilater.
- Repository:
- Save. PyPI will trust OIDC tokens from that workflow only.
Official guide: Trusted Publishers.
Cutting a release
Merging a PR to master does not publish to PyPI. Only a git push of a tag matching v* runs the publish job (see if: startsWith(github.ref, 'refs/tags/v') in publish-pypi.yml). CI on branch pushes is separate (ci.yml).
Order matters (read this once)
PyPI publishes whatever commit the tag points at. A version-only merge (e.g. “bump pyproject.toml”) does not magically include code that still lives in a separate open PR.
- Merge every PR that carries the release code into
masterfirst (e.g. yourrelease/…or feature branch). - Then bump
versioninpyproject.toml(same PR as the code, or a follow-up PR — both are fine after the code is onmaster). - Only then tag
masterand push the tag.
If you tag after only step (2), you can ship a new version number with old code. PyPI cannot be overwritten for that version — you must publish a newer version (e.g. 0.1.7) with the correct tree.
Before you push the tag — quick verify
After git pull origin master, confirm the tree matches what you intend (examples below; adjust for your release):
grep ^version pyproject.toml
test -f easy_aso/runtime/rpc_docked.py # example: RPC-docked runtime present
Or: git merge-base --is-ancestor origin/<your-release-branch> HEAD should succeed before tagging.
Typical flow:
- Open a PR from
develop(or a feature /release/…branch) intomasterwith all code changes for the release. Merge it. - Ensure
pyproject.tomlversiononmastermatches the release you will tag (bump in another PR if needed). -
On your machine, update local
masterand create the tag on that merge commit:git checkout master git pull origin master git tag vX.Y.Z # must match version in pyproject.toml (with leading v) git push origin vX.Y.ZTags pushed from
developbefore merging still publish whatever commit the tag points to — for a clean release, the tag should usually point atmasterafter the merge. - Watch Actions → Publish easy-aso to PyPI. The workflow runs pytest on Python 3.11 and 3.12, builds with Python 3.12, then Trusted Publishing uploads
dist/*for that tag.
workflow_dispatch runs the same test and build jobs; Publish to PyPI runs only when the workflow run was triggered by a tag (refs/tags/v*).
If publish fails
- “Permission denied” / OIDC: Workflow filename or repository on PyPI must match exactly.
- “File already exists”: You cannot overwrite a given version on PyPI — bump the version and tag again.