Cut a release in one command — bump, notes, tag, GitHub release. Zero dependencies.
cutrelease does the repetitive release dance for you: it bumps the version in
your project file, writes grouped release notes from the commits since the last
tag, commits the bump, creates an annotated tag, and (optionally) publishes a
GitHub release. Run --dry-run first to see exactly what it will do.
Nothing but the Python standard library and the git you already have.
pip install cutreleaseRequires Python 3.8+ and git.
# See the plan without touching anything
cutrelease --bump minor --dry-run
# Bump the patch version, commit, tag
cutrelease --bump patch
# Release an explicit version, push, and create the GitHub release
export GITHUB_TOKEN=ghp_...
cutrelease 1.4.0 --push --github-release --repo me/myprojectcutrelease finds your version in pyproject.toml or package.json
automatically. If there is no version file, it falls back to your latest git tag.
Plan:
version file : pyproject.toml
version : 1.3.2 -> 1.4.0
tag : v1.4.0
commit : True
push : False
github release: False
Release notes:
## v1.4.0
### Features
- add a --dry-run flag
### Bug Fixes
- handle repos with no tags yet
| Flag | Description |
|---|---|
VERSION |
Explicit version to release (omit when using --bump). |
--bump {major,minor,patch} |
Bump part of the current version. |
--version-file PATH |
Version file to update (default: autodetect). |
--tag-prefix P |
Tag prefix (default v). |
--no-commit |
Do not commit the version bump. |
--push |
Push the commit and tag. |
--github-release |
Create a GitHub release (needs --repo, $GITHUB_TOKEN). |
--dry-run |
Print the plan and make no changes. |
Commits since the last tag are grouped by Conventional
Commits type: feat → Features,
fix → Bug Fixes, and so on. Breaking changes (! or a BREAKING CHANGE
footer) get their own section. Anything unrecognized lands under Other, so
nothing is dropped.
pip install -e ".[test]"
python -m pytestMIT — see LICENSE.