| name | cut-release |
| description | Cut a clean release — bump versions across all files, update changelog, create GitHub release |
| category | workflow |
| tags | ["release","versioning","semver","automation"] |
| version | 1.0.0 |
Cut Release
Automated release workflow: determine version → delegate to cut-release.sh → commit → create PR → merge → publish GitHub release.
When to Use
Invoke this skill whenever you are ready to cut a new release. Common triggers:
- After merging feature branches that warrant a version bump
- Before publishing a new skill or template version
- When
[Unreleased] in CHANGELOG.md has accumulated changes worth releasing
Prerequisites
- All work for this release is committed and pushed
CHANGELOG.md has entries under [Unreleased]
- You have push access to the repository
Phase 1: Determine Version (You do this)
-
Read current version from .template-version:
cat .template-version
-
Read changelog to understand what has changed under [Unreleased]:
head -30 CHANGELOG.md
-
Compute next version using semver:
feat: commits → minor bump (e.g. 1.2.0 → 1.3.0)
fix: commits → patch bump (e.g. 1.2.0 → 1.2.1)
feat!: or BREAKING CHANGE in body → major bump (e.g. 1.2.0 → 2.0.0)
-
Ask user to confirm or override the computed version before proceeding.
If [Unreleased] is empty, abort — nothing to release.
Phase 2: Execute Release (cut-release.sh does this)
Run the automation script with the version bump:
bash .omp/skills/cut-release/scripts/cut-release.sh <OLD_VERSION> <NEW_VERSION>
Example:
bash .omp/skills/cut-release/scripts/cut-release.sh 0.5.0 0.6.0
What the script does:
-
Pre-flight: Verifies OLD_VERSION exists in all 7 version manifest files. Aborts if any are missing (prevents wrong version being passed).
-
Update files: Replaces version in all manifest files:
| File | Pattern |
|---|
.template-version | whole file content |
README.md | template-vX.Y.Z in badge |
AGENTS.md | version **X.Y.Z** |
SETUP_GUIDE.md | `X.Y.Z` |
.omp/skills/template-guide/SKILL.md | (X.Y.Z) in examples |
.omp/skills/template-guide/scripts/audit.sh | TEMPLATE_VERSION=X.Y.Z line |
CHANGELOG.md | Creates new version section from Unreleased |
-
Post-flight: Verifies NEW_VERSION exists in all files and OLD_VERSION is gone.
-
Audit: Runs audit.sh — must pass before proceeding.
Dry run mode:
bash .omp/skills/cut-release/scripts/cut-release.sh <OLD> <NEW> --dry-run
Shows what would change without making any modifications.
Phase 3: Commit, PR, Merge, Tag, Release (You do this)
-
Review changes:
git diff
-
Commit:
git add -A
git commit -m "chore: cut vX.Y.Z"
-
Push branch:
git push -u origin HEAD
-
Create PR (or use merge-to-main skill):
gh pr create --base main --title "chore: cut vX.Y.Z" --body "## Summary
Cut release vX.Y.Z.
## Changes
- Updated version references across all manifest files
- CHANGELOG.md updated with release section
## Verification
- audit.sh passes
- No stale version references remain"
-
Monitor CI and merge when all checks pass:
gh pr merge <pr-number> --squash
-
Switch to main and pull:
git checkout main && git pull
-
Create annotated tag:
git tag -a vX.Y.Z -m "Release vX.Y.Z"
-
Push tag:
git push origin vX.Y.Z
-
Create GitHub release:
gh release create vX.Y.Z --title "vX.Y.Z" --notes "<changelog-body>"
The release body should be the changelog section for this version (everything between ## [X.Y.Z] and the next ## [ or end of file).
Phase 4: Verify
-
Release exists and is not draft:
gh release list
gh release view vX.Y.Z
-
Release body matches CHANGELOG.md:
Compare gh release view vX.Y.Z --json body --jq '.body' with the corresponding section in CHANGELOG.md
-
All manifest files contain the new version:
cat .template-version
grep "vX.Y.Z" README.md
-
No stale references to old version remain:
grep -rn "vOLD-VERSION" . --include='*.md' --include='*.sh'
Edge Cases
| Situation | Handling |
|---|
Empty [Unreleased] section | Abort — nothing to release |
| Multiple version-like strings | Use anchored patterns (handled by script) |
| Tag already exists | Detect via git tag -l vX.Y.Z and abort |
| Wrong version passed | Pre-flight check catches missing OLD_VERSION |
| Audit fails after update | Script aborts; fix manually before committing |
What This Skill Does NOT Do
- Does not write the code or features being released (those are your main tasks)
- Does not force-push or rewrite shared history
- Does not publish to package registries (npm, PyPI, crates.io, etc.)
- Does not auto-resolve merge conflicts
- Does not bypass branch protection or skip CI checks