Skip to main content
OrchestKit v7.43.0 — 104 skills, 36 agents, 173 hooks · Claude Code 2.1.105+
OrchestKit
Skills

Release Management

GitHub release workflow with semantic versioning, changelogs, and release automation using gh CLI. Use when creating releases, tagging versions, or publishing changelogs.

Reference low

Auto-activated — this skill loads automatically when Claude detects matching context.

Release Management

Automate releases with gh release, semantic versioning, and changelog generation.

CRITICAL: Task Management is MANDATORY (CC 2.1.16)

BEFORE doing ANYTHING else, create tasks to track progress:

# 1. Create main task IMMEDIATELY
TaskCreate(
  subject="Release: {version}",
  description="Creating release with semantic versioning and changelog",
  activeForm="Releasing {version}"
)

# 2. Create subtasks for each release phase
TaskCreate(subject="Version & changelog", activeForm="Determining version and generating changelog")
TaskCreate(subject="Create release", activeForm="Creating GitHub release")
TaskCreate(subject="Verify & announce", activeForm="Verifying release and announcing")

# 3. Set dependencies for sequential phases
TaskUpdate(taskId="3", addBlockedBy=["2"])
TaskUpdate(taskId="4", addBlockedBy=["3"])

# 4. Before starting each task, verify it's unblocked
task = TaskGet(taskId="2")  # Verify blockedBy is empty

# 5. Update status as you progress
TaskUpdate(taskId="2", status="in_progress")  # When starting
TaskUpdate(taskId="2", status="completed")    # When done

Quick Reference

Create Release

# Auto-generate notes from PRs
gh release create v1.2.0 --generate-notes

# With custom title
gh release create v1.2.0 --title "Version 1.2.0: Performance Update" --generate-notes

# Draft release (review before publishing)
gh release create v1.2.0 --draft --generate-notes

# Pre-release (beta, rc)
gh release create v1.2.0-beta.1 --prerelease --generate-notes

# With custom notes
gh release create v1.2.0 --notes "## Highlights
- New auth system
- 50% faster search"

# From notes file
gh release create v1.2.0 --notes-file RELEASE_NOTES.md

List & View Releases

# List all releases
gh release list

# View specific release
gh release view v1.2.0

# View in browser
gh release view v1.2.0 --web

# JSON output
gh release list --json tagName,publishedAt,isPrerelease

Verify Releases (gh CLI 2.86.0+)

# Verify release attestation (sigstore)
gh release verify v1.2.0

# Verify specific asset
gh release verify-asset v1.2.0 ./dist/app.zip

# Verify with custom trust policy
gh release verify v1.2.0 --owner myorg

Manage Releases

# Edit release
gh release edit v1.2.0 --title "New Title" --notes "Updated notes"

# Delete release
gh release delete v1.2.0

# Upload assets
gh release upload v1.2.0 ./dist/app.zip ./dist/app.tar.gz

Semantic Versioning

MAJOR.MINOR.PATCH
  │     │     │
  │     │     └── Bug fixes (backwards compatible)
  │     └──────── New features (backwards compatible)
  └────────────── Breaking changes

Examples:
  1.0.0 → 1.0.1  (patch: bug fix)
  1.0.1 → 1.1.0  (minor: new feature)
  1.1.0 → 2.0.0  (major: breaking change)

Pre-release:
  2.0.0-alpha.1  (early testing)
  2.0.0-beta.1   (feature complete)
  2.0.0-rc.1     (release candidate)

Release Workflows

Standard and hotfix release procedures using git tags and gh release.

Load Read("${CLAUDE_SKILL_DIR}/references/release-workflows.md") for step-by-step standard and hotfix release workflows.


Changelog Generation

Auto-generated from PRs, custom .github/release.yml templates, and manual CHANGELOG.md format.

Load Read("${CLAUDE_SKILL_DIR}/references/changelog-generation.md") for changelog template examples and Keep-a-Changelog format.


Release Automation & Checklist

GitHub Actions workflow for tag-triggered releases, version bumping script, and pre/post-release checklist.

Load Read("${CLAUDE_SKILL_DIR}/references/release-automation.md") for CI workflow, bump script, and release checklist.


Best Practices

  1. Use semantic versioning - Communicate change impact
  2. Draft releases first - Review notes before publishing
  3. Generate notes from PRs - Accurate, automatic history
  4. Close milestone on release - Track completion
  5. Tag main only - Never tag feature branches
  6. Announce breaking changes - Prominent in release notes
  • ork:github-operations: Milestones, issues, and CLI reference
  • ork:github-operations: Branch management and git operations

References

Load on demand with Read("$\{CLAUDE_SKILL_DIR\}/references/<file>"):

FileContent
semver.mdSemantic versioning rules and decision tree
release-workflows.mdStandard and hotfix release procedures
changelog-generation.mdAuto-generated, template, and manual changelog formats
release-automation.mdGitHub Actions workflow, bump script, and checklist

Rules (2)

Changelog must document all breaking changes with migration instructions — HIGH

Changelog Must Include All Breaking Changes

Why

Developers read changelogs before upgrading. If a breaking change is missing from the changelog, they upgrade without migration steps and hit runtime errors. After one bad experience, teams stop upgrading and fall behind on security patches.

Rule

Before publishing a release:

  1. Cross-reference all commits with the changelog
  2. Every commit with ! or BREAKING CHANGE must appear in the changelog
  3. Breaking changes must include migration instructions
  4. The Breaking Changes section must appear first in the changelog

Incorrect — incomplete changelog missing breaking changes

# Changelog

## [2.0.0] - 2026-03-10

### Added
- Bulk export endpoint (#234)
- Dark mode support (#236)

### Fixed
- Date parser null handling (#235)

Problems:

  • Version is 2.0.0 (major) but no breaking changes listed
  • The commit feat!: remove /v1/users endpoint (#230) is missing
  • The commit refactor!: rename User model to Account (#232) is missing
  • No migration instructions for breaking changes

Correct — complete changelog with migration instructions

# Changelog

## [2.0.0] - 2026-03-10

### BREAKING CHANGES

- **Removed `/v1/users` endpoint** (#230): The deprecated v1 users
  API has been removed. Migrate to `/v2/users` which supports
  cursor-based pagination.

  ```diff
  - GET /v1/users?page=2&limit=20
  + GET /v2/users?cursor=abc123&limit=20
  • Renamed User model to Account (#232): All database tables and API responses now use Account. Run the migration:

    npm run migrate:up

    Update imports:

    - import \{ User \} from "./models/user";
    + import \{ Account \} from "./models/account";

Added

  • Bulk export endpoint (#234)
  • Dark mode support (#236)

Fixed

  • Date parser null handling (#235)

## Verification Script

```bash
#!/bin/bash
LAST_TAG=$(gh release view --json tagName -q .tagName)

# Find all breaking change commits
BREAKING=$(git log "$LAST_TAG"..HEAD --oneline --format="%s" \
  | grep -E '!:|BREAKING CHANGE')

if [ -z "$BREAKING" ]; then
  echo "No breaking changes found"
  exit 0
fi

echo "Breaking changes to verify in CHANGELOG.md:"
echo "$BREAKING" | while IFS= read -r commit; do
  # Extract PR number if present
  PR=$(echo "$commit" | grep -oE '#[0-9]+' | head -1)
  if [ -n "$PR" ] && ! grep -q "$PR" CHANGELOG.md; then
    echo "  MISSING: $commit"
  else
    echo "  OK: $commit"
  fi
done

Changelog Section Order

SectionRequired WhenPosition
BREAKING CHANGESAny ! or BREAKING CHANGE commitFirst
DeprecatedDeprecation noticesSecond
AddedNew featuresThird
ChangedBehavior changesFourth
FixedBug fixesFifth
SecurityCVE patchesSixth

Validate that semantic version bump matches the actual scope of changes — HIGH

Validate Version Bump Matches Change Scope

Why

Semantic versioning is a contract with consumers. A breaking API change shipped as a patch version (1.2.3 -> 1.2.4) causes runtime failures for anyone pinned to ^1.2.3. A bug fix shipped as major (1.2.3 -> 2.0.0) forces unnecessary migration work.

Rule

Before tagging a release:

  1. List all commits since the last release
  2. Classify each commit as patch/minor/major based on its impact
  3. The version bump must match the highest-impact commit
  4. Breaking changes require major bump — no exceptions

Incorrect — bump version without checking changes

# Blindly bump patch without reviewing commits
CURRENT="1.2.3"
NEW="1.2.4"  # Assumed patch

git tag -a "v$NEW" -m "Release v$NEW"
git push origin "v$NEW"
gh release create "v$NEW" --generate-notes

# But commits since v1.2.3 include:
# - "feat!: remove deprecated /v1/users endpoint" (BREAKING)
# - "feat: add /v2/users with pagination" (MINOR)
# - "fix: correct date parsing" (PATCH)
# Correct bump should have been MAJOR (2.0.0)

Correct — classify commits then determine bump

#!/bin/bash
LAST_TAG=$(gh release view --json tagName -q .tagName)
echo "Commits since $LAST_TAG:"

# Classify commits
MAJOR=0; MINOR=0; PATCH=0

while IFS= read -r msg; do
  if echo "$msg" | grep -qE '^(feat|fix|refactor)(\(.+\))?!:|^BREAKING'; then
    MAJOR=$((MAJOR + 1))
    echo "  MAJOR: $msg"
  elif echo "$msg" | grep -qE '^feat(\(.+\))?:'; then
    MINOR=$((MINOR + 1))
    echo "  MINOR: $msg"
  else
    PATCH=$((PATCH + 1))
    echo "  PATCH: $msg"
  fi
done < <(git log "$LAST_TAG"..HEAD --oneline --format="%s")

# Determine correct bump
if [ "$MAJOR" -gt 0 ]; then
  echo "Required bump: MAJOR ($MAJOR breaking changes)"
elif [ "$MINOR" -gt 0 ]; then
  echo "Required bump: MINOR ($MINOR new features)"
else
  echo "Required bump: PATCH ($PATCH fixes)"
fi

Classification Guide

Commit PatternBumpExample
fix:PATCHfix: handle null in date parser
docs:, chore:, ci:PATCHdocs: update API reference
feat:MINORfeat: add bulk export endpoint
feat!: or BREAKING CHANGE:MAJORfeat!: remove v1 API endpoints
refactor!:MAJORrefactor!: rename User to Account

Pre-Release Validation

# Before creating the release, verify:
echo "=== Pre-Release Checklist ==="
echo "1. Last release: $LAST_TAG"
echo "2. Commits since: $(git rev-list "$LAST_TAG"..HEAD --count)"
echo "3. Breaking changes: $MAJOR"
echo "4. New features: $MINOR"
echo "5. Fixes/chores: $PATCH"
echo "6. Proposed version: v$NEW"
echo ""
if [ "$MAJOR" -gt 0 ] && ! echo "$NEW" | grep -qE '^[0-9]+\.0\.0'; then
  echo "ERROR: Breaking changes found but version is not a major bump"
  exit 1
fi

References (4)

Changelog Generation

Changelog Generation

Auto-Generated (from PRs)

# GitHub auto-generates from merged PRs
gh release create v1.2.0 --generate-notes

# Output includes:
# ## What's Changed
# * feat: Add user auth by @dev in #123
# * fix: Login redirect by @dev in #124
# * docs: Update README by @dev in #125

Custom Changelog Template

Create .github/release.yml:

changelog:
  categories:
    - title: "Breaking Changes"
      labels:
        - "breaking"
    - title: "New Features"
      labels:
        - "enhancement"
        - "feature"
    - title: "Bug Fixes"
      labels:
        - "bug"
        - "fix"
    - title: "Documentation"
      labels:
        - "documentation"
    - title: "Other Changes"
      labels:
        - "*"

Manual CHANGELOG.md

# Changelog

## [1.3.0] - 2026-01-15

### Added
- User authentication system (#123)
- Dark mode support (#125)

### Changed
- Improved search performance (#126)

### Fixed
- Login redirect loop (#124)

### Security
- Updated dependencies for CVE-2026-1234

Release Automation

Release Automation

GitHub Actions Release Workflow

# .github/workflows/release.yml
name: Release

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Build
        run: npm run build

      - name: Create Release
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          gh release create ${{ github.ref_name }} \
            --generate-notes \
            ./dist/*.zip

Version Bumping Script

#!/bin/bash
# bump-version.sh

CURRENT=$(gh release view --json tagName -q .tagName | sed 's/v//')
IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT"

case $1 in
  major) NEW="$((MAJOR + 1)).0.0" ;;
  minor) NEW="$MAJOR.$((MINOR + 1)).0" ;;
  patch) NEW="$MAJOR.$MINOR.$((PATCH + 1))" ;;
  *) echo "Usage: $0 [major|minor|patch]"; exit 1 ;;
esac

echo "Bumping $CURRENT -> $NEW"
git tag -a "v$NEW" -m "Release v$NEW"
git push origin "v$NEW"
gh release create "v$NEW" --generate-notes

Usage:

./bump-version.sh patch  # 1.2.3 -> 1.2.4
./bump-version.sh minor  # 1.2.4 -> 1.3.0
./bump-version.sh major  # 1.3.0 -> 2.0.0

Release Checklist

## Release v1.3.0 Checklist

### Pre-Release
- [ ] All PRs merged to main
- [ ] CI/CD passing on main
- [ ] Version numbers updated in package.json/pyproject.toml
- [ ] CHANGELOG.md updated
- [ ] Documentation updated
- [ ] Milestone closed

### Release
- [ ] Tag created and pushed
- [ ] GitHub release created
- [ ] Release notes reviewed
- [ ] Assets uploaded (if applicable)

### Post-Release
- [ ] Deployment verified
- [ ] Announcement posted (if applicable)
- [ ] Next milestone created

Release Workflows

Release Workflows

Standard Release

# 1. Ensure main is up to date
git checkout main
git pull origin main

# 2. Determine version bump
# Check commits since last release
gh release view --json tagName -q .tagName  # Current: v1.2.3
git log v1.2.3..HEAD --oneline

# 3. Create and push tag
git tag -a v1.3.0 -m "Release v1.3.0"
git push origin v1.3.0

# 4. Create GitHub release
gh release create v1.3.0 \
  --title "v1.3.0: Feature Name" \
  --generate-notes

# 5. Close milestone if used
gh api -X PATCH repos/:owner/:repo/milestones/5 -f state=closed

Hotfix Release

# 1. Branch from release tag
git checkout -b hotfix/v1.2.4 v1.2.3

# 2. Fix and commit
git commit -m "fix: Critical security patch"

# 3. Tag and release
git tag -a v1.2.4 -m "Hotfix: Security patch"
git push origin v1.2.4
gh release create v1.2.4 --title "v1.2.4: Security Hotfix" \
  --notes "Critical security fix for authentication bypass"

# 4. Merge fix to main
git checkout main
git cherry-pick <commit-sha>
git push origin main

Semver

Semantic Versioning Guide

Standard versioning for software releases.

Version Format

MAJOR.MINOR.PATCH[-PRERELEASE][+BUILD]

Examples:
1.0.0
2.1.3
3.0.0-alpha.1
3.0.0-beta.2+build.123

When to Bump

PATCH (x.x.X)

Bug fixes, backwards compatible:

1.0.0 -> 1.0.1
  • Fix typo in error message
  • Fix edge case bug
  • Security patch (no API change)
  • Performance improvement (no API change)

MINOR (x.X.0)

New features, backwards compatible:

1.0.1 -> 1.1.0
  • Add new function/method
  • Add new optional parameter
  • Deprecate (but don't remove) feature
  • Add new event/hook

MAJOR (X.0.0)

Breaking changes:

1.1.0 -> 2.0.0
  • Remove function/method
  • Change function signature
  • Change return type
  • Rename public API
  • Change default behavior

Pre-release Versions

2.0.0-alpha.1   # Early development
2.0.0-alpha.2
2.0.0-beta.1    # Feature complete
2.0.0-beta.2
2.0.0-rc.1      # Release candidate
2.0.0-rc.2
2.0.0           # Final release

Precedence

1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta < 1.0.0-rc.1 < 1.0.0

Decision Tree

Is it a breaking change?
├── Yes → MAJOR bump
└── No
    └── Is it a new feature?
        ├── Yes → MINOR bump
        └── No → PATCH bump

Examples

ChangeVersion BumpReason
Fix null pointer crash1.0.0 → 1.0.1Bug fix
Add sort parameter1.0.1 → 1.1.0New feature
Change sort to required1.1.0 → 2.0.0Breaking
Improve performance 2x1.0.0 → 1.0.1No API change
Remove deprecated method1.5.0 → 2.0.0Breaking
Add new endpoint1.0.0 → 1.1.0New feature

Commands

# View current version
cat package.json | jq '.version'

# Bump with npm
npm version patch  # 1.0.0 -> 1.0.1
npm version minor  # 1.0.1 -> 1.1.0
npm version major  # 1.1.0 -> 2.0.0

# With git tag
npm version patch -m "Release %s"

# Manual
git tag -a v1.2.3 -m "Release v1.2.3"
git push origin v1.2.3

0.x.x Versions

For pre-1.0 development:

  • API is unstable
  • MINOR can include breaking changes
  • PATCH for any fixes/features
0.1.0  Initial development
0.2.0  Breaking changes OK
0.9.0  Approaching stable
1.0.0  First stable release
Edit on GitHub

Last updated on