Release Pipeline¶
A CUTIP release produces a versioned Python wheel published to a GitHub Release and tagged with a git tag. Release branches are temporary — the git tag is the durable version marker.
Trigger¶
Push to release/v{X.Y.Z} — triggers release.yml.
GitHub Actions: release.yml¶
Push to release/v{X.Y.Z}
│
▼
Build wheel (uv build --wheel)
│
▼
Create GitHub Release
│ - Tag: v{X.Y.Z}
│ - Uploads wheel as asset
│
▼
Release published
The git tag (v{X.Y.Z}) is created by softprops/action-gh-release as part of the release step. Do not tag manually.
Release branch lifecycle¶
Release branches (release/v{X.Y.Z}) are short-lived:
- Created from
integration - Pushed to trigger
release.yml - Deleted after the GitHub Release is published
Versioned code is preserved via the git tag (v{X.Y.Z}), not via a permanent branch.
Full release sequence¶
1. Bump version in pyproject.toml
2. Update docs/patch-notes.md
3. PR → staging → merge
4. Forward staging → integration
5. git checkout -b release/v{X.Y.Z} origin/integration
6. git push -u origin release/v{X.Y.Z}
7. Watch release.yml until complete
8. Edit GitHub Release notes (Features + Patch Notes)
9. Remove non-wheel assets from release
10. git branch -d release/v{X.Y.Z} (tag persists)
See the complete playbook: .claude/workflows/release.md
GitHub Release structure¶
Release notes use the format from .claude/templates/github-release-notes.md:
## Features
- **cap{N} — {title}**: {user-facing description}
## Patch Notes
- **cap{N} — {title}**: {user-facing description}
## Installation
pip install cutip=={X.Y.Z}
## Features—feat/*caps shipped in this release## Patch Notes—bug/*caps shipped in this release- No PR numbers, no authors, no GitHub-generated "What's Changed"
Dev Release Track (Test PyPI)¶
Every merge to integration automatically publishes a dev build to Test PyPI. Issue fixes accumulate in a single installable pre-release version.
Workflow: .github/workflows/integration.yml (the publish-dev job)
Version format: {major}.{minor}.{patch+1}.dev{RUN_NUMBER} — e.g. 0.1.7.dev42
Install:
pip install --index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
"cutip>=0.1.7.dev0"
The --extra-index-url flag lets pip resolve dependencies from the main PyPI registry.
Requires secret: TEST_PYPI_TOKEN — add once in repo settings → Secrets → Actions.
Patch notes¶
docs/patch-notes.md is updated as part of every release. Each entry follows the same structure: