Release workflow¶
Branch topology¶
main ←── PR merges from feature/bug/hotfix branches
feature/*, fix/*, chore/* ←── created from main, deleted after merge
Tags on main are the release record. There is no prod branch — git checkout v1.2.3 gives you any released state.
Step-by-step¶
# 1. Create a branch
git checkout main && git pull
git checkout -b feature/my-feature
# 2. Do your work, committing with cz
cz commit # interactive prompt enforcing Conventional Commits
# 3. Push branch and open PR
git push -u origin feature/my-feature
gh pr create --base main --title "feat: my feature"
# 4. CI runs: lint on push, tests on PR to main — merge is blocked until green
# 5. Merge PR (rebase or squash)
gh pr merge --rebase --delete-branch
# 6. bump.yml fires automatically on push to main:
# → reads commits since last tag
# → runs cz bump --yes to determine patch/minor/major
# → creates version tag (e.g. v1.3.0) and pushes it
# 7. release.yml fires on the new tag:
# → builds wheel + sdist
# → creates GitHub release with dist files attached
# → publishes to PyPI via OIDC trusted publishing (no stored token)
# → Zenodo webhook archives the release (if enabled)
How version bumps are determined¶
Commitizen reads all commits since the previous tag:
| Commits contain | Bump |
|---|---|
only fix:, docs:, chore:, refactor:, test: |
patch 0.0.x |
at least one feat: |
minor 0.x.0 |
BREAKING CHANGE: footer or feat!:/fix!: |
major x.0.0 |
If there are no bumpable commits since the last tag, bump.yml exits silently — no error, no tag.
Manual bump (override)¶
Automated bumping covers most cases. Override when needed:
cz bump --increment PATCH
cz bump --increment MINOR
cz bump --increment MAJOR
git push --follow-tags
Conventional Commits format¶
Common types: feat, fix, docs, chore, refactor, test, ci, build.
Common issues¶
bump.yml pushed a tag but release.yml didn't trigger
GitHub prevents downstream push triggers when GITHUB_TOKEN is the actor. If this happens, store a PAT as BUMP_TOKEN and set token: ${{ secrets.BUMP_TOKEN }} in the checkout step of bump.yml.
cz bump fails with exit code 128
- Detached HEAD →
git checkout mainfirst - Uncommitted changes → commit or stash first
- Tag already exists →
git tagto list,git tag -d <tag>to remove locally
GPG signing failure
See GPG signing.