PyPI Release Process¶
Overview¶
One release method: push tag v* → release-on-tag.yml handles everything (tests, build, PyPI publish, Docker push, GitHub Release).
Automatic Release¶
Prerequisites¶
- PyPI Trusted Publishing configured (one-time setup)
- GitHub Environment
pypicreated
PyPI Trusted Publishing Setup¶
- Go to PyPI Publishing Settings
- Click Add trusted publisher:
- In GitHub: Settings → Environments → New environment →
pypi - No protection rules needed (or add if desired)
Note:
release-on-tag.ymlis the only workflow that publishes to PyPI. The version is read frompyproject.toml, so bump it there and tag with a matchingvX.Y.Z.
Release Steps¶
# 1. Bump version in pyproject.toml
# version = "0.1.0" → "0.2.0"
# 2. Commit version bump
git add pyproject.toml
git commit -m "chore: bump version to 0.2.0"
# 3. Create and push tag (must match pyproject.toml version)
git tag v0.2.0
git push origin v0.2.0
That's it! GitHub Actions will:
1. ✅ Read version from pyproject.toml and verify tag matches
2. ✅ Run full test suite
3. ✅ Build package (python -m build)
4. ✅ Publish to PyPI via Trusted Publishing (OIDC token)
5. ✅ Build & push Docker to GHCR
6. ✅ Create GitHub Release with changelog
Version Bump¶
The version lives only in pyproject.toml. Bump it, commit, and push a matching tag:
# Edit pyproject.toml: version = "0.1.0" → "0.2.0"
git add pyproject.toml
git commit -m "chore: bump version to 0.2.0"
git tag v0.2.0
git push origin v0.2.0
No manual workflow needed — the tag push triggers release-on-tag.yml, which reads the
version from pyproject.toml.
Versioning¶
Semantic Versioning (SemVer):
- MAJOR.MINOR.PATCH
- MAJOR: Breaking changes
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
Release tags: v0.1.0, v1.0.0, etc.
Changelog¶
Auto-generated by release-drafter from PR labels:
| Label | Category |
|---|---|
breaking-change |
💥 Breaking Changes |
feature, enhancement |
💡 New Features |
bug, fix, bugfix |
🐛 Bug Fixes |
refactor |
⚙️ Technical Debt |
documentation |
📝 Documentation |
Configure labels in GitHub repo settings.
First Release Checklist¶
- [ ] PyPI Trusted Publishing configured
- [ ] GitHub Environment
pypicreated - [ ]
release-drafterlabels created - [ ]
.github/release-drafter-config.ymlcustomized - [ ] Test release with
v0.0.1(can yank later)
Troubleshooting¶
| Issue | Solution |
|---|---|
Tag already exists |
Delete tag locally/remote, re-tag |
Version mismatch |
Update pyproject.toml version before tagging |
PyPI publish failed |
Check Trusted Publishing config, Environment exists |
Docker push failed |
Check GHCR permissions, GITHUB_TOKEN scope |
Tests failed |
Fix tests, re-run workflow |
Yanking a Release¶
# On PyPI
twine yank indian-bank-statement-parser 0.1.0 -m "Broken release"
# Or via PyPI web UI: Project → Release history → Yank
Note: Yanked versions cannot be re-uploaded. Bump version instead.