Custy is a CLI tool to automate Git commit, tagging, versioning, changelog generation, and enforcing branching workflows. It supports SemVer, PEP 440, and other strategies.
Ensure the required dependencies are installed (Python, Git, etc). To use:
python app/__main__.py <command> [options]Automates commit + tag creation + version bumping.
python app/__main__.py commit-tag-bump [message_file] [options]Options:
--strategy:semver|pep440|date|gitcount|commitizen--bump:major|minor|patch|auto--tag: Manual tag (e.g.,v1.2.3)--tag-msg: Custom tag message--pre-release: Pre-label (e.g.,alpha,beta,rc)--post-release: Mark as post-release--dev-release: Mark as development version--meta: Metadata (e.g.,sha.abc123)--epoch: Epoch number (PEP 440)--force-tag: Bypass commit-type check--version-file: Defaults toapp/__version__.py--dry-run: Simulate without applying--force-commit: Allow commit even with no staged changes--sync-backup: Also push tobackupremote (e.g., GitHub)
Run the full workflow:
- Commit + tag
- Push to origin (and backup)
- Generate & commit
CHANGELOG.md - Backup commit message
python app/__main__.py all [message_file] [options]Includes all commit-tag-bump options plus:
--stage-mode:all|update--skip-checks: Skip workflow validation--force-changelog: Allow changelog even for prereleases--no-debug: Silence debug info
Push latest commit + tag to origin and optionally to backup.
python app/__main__.py pushGenerate a structured CHANGELOG.md from Git log between last two tags.
python app/__main__.py changelog [options]Options:
--force-changelog: Allow changelog even for pre-releases
Check commit message and Git state before committing.
python app/__main__.py validate [message_file]Backup current commit message file into backups/commit/.
python app/__main__.py backupPrune older backup files.
python app/__main__.py cleaned-backups [--type] [--keep]Options:
--type:commit|tag|all(default)--keep: Number of recent backups to keep (default:10)
Delete old or merged branches.
python app/__main__.py clean-branches --prefix <prefix> [--merged-only] [--older-than <N>d]Examples:
python app/__main__.py clean-branches --prefix feature/ --merged-only
python app/__main__.py clean-branches --prefix release/ --older-than 30dValidate or enforce Git branch→tag strategy.
python app/__main__.py workflow [--enforce] [--check_transition] [options]Options:
--enforce: Enforce naming rules and transition logic--check_transition: Check if a version bump between branches is valid--from-branch/--from-tag/--to-branch/--to-tag: Custom transition override
| Strategy | Description |
|---|---|
semver |
Uses major.minor.patch + optional pre-release (e.g., v1.2.3-beta.1) |
pep440 |
Python standard (e.g., 1.2.3, 1.2.3rc1, 1!1.2.3+sha.abc) |
date |
Uses current date for tag (e.g., 20250804) |
gitcount |
Tag is generated based on commit count (e.g., v0.1.53) |
commitizen |
Uses cz config to auto infer bump and generate tag |
python app/__main__.py commit-tag-bump commit-msg.txt --strategy semver --bump patchpython app/__main__.py all commit-msg.txt \
--strategy pep440 \
--bump patch \
--version-file app/__version__.py \
--force-changelog \
--sync-backuppython app/__main__.py pushpython app/__main__.py changelog --force-changelogpython app/__main__.py validate commit-msg.txtpython app/__main__.py clean-branches --prefix feature/ --older-than 30d| File / Dir | Purpose |
|---|---|
app/__version__.py |
Holds version string __version__ = "x.y.z" |
templates/commit-msg.txt |
Commit message template |
templates/tag-msg.txt |
Tag message template |
backups/commit/ |
Backup of commit messages |
backups/tag/ |
Backup of tag messages |