Skip to main content
AI/MLWaterplanAI

ac-git-release

Full release workflow including changelog validation, squash, rebase, push, merge to main, and GitHub release preparation. Triggers on keywords: release, create release, publish release, tag release

Stars
31
Source
WaterplanAI/agentic-config
Updated
2026-05-25
Slug
WaterplanAI--agentic-config--ac-git-release
View on GitHubRaw SKILL.md

// install — copy + paste into any project

mkdir -p .claude/skills && curl -fsSL https://raw.githubusercontent.com/WaterplanAI/agentic-config/HEAD/packages/pi-ac-git/skills/ac-git-release/SKILL.md -o .claude/skills/ac-git-release.md

Drops the SKILL.md into .claude/skills/ac-git-release.md. Works with Claude Code, Cursor, and any agent that loads SKILL.md files from .claude/skills/.

Release Command

Full release workflow: validate changelog, prepare a squashed release commit and tag, sync the VERSION file plus repo/package version metadata, rebase, push, and merge to main.

No arguments required - auto-detect the current branch, release version, and release inputs.

Compatibility Note

This pi wrapper preserves the original release workflow but performs the former milestone-preparation steps directly because ac-tools-milestone does not ship as a separate pi wrapper in the current package surface.

Context Awareness

Before any destructive history rewrite, use /skill:ac-git-git-safe to inspect the dry-run plan and confirm the exact squash/tag steps you intend to execute.

Phase 1: Prepare the Release Locally

1.1 Pre-Flight

Verify all of the following before rewriting history:

  • git state is clean
  • branch is not main
  • commits exist ahead of origin/main
  • CHANGELOG.md has a populated [Unreleased] section
  • the next release version can be derived from VERSION or the latest v*.*.* tag

Suggested checks:

git status --short
git fetch origin main
git rev-parse --abbrev-ref HEAD
git log --oneline origin/main..HEAD
git tag -l 'v*.*.*' | sort -V | tail -1
test -f VERSION && cat VERSION
test -f CHANGELOG.md && sed -n '/\[Unreleased\]/,/^## /p' CHANGELOG.md

1.2 Determine Release Inputs

Capture these values for the rest of the flow:

  • BRANCH: current branch name
  • VERSION: next release tag (prefer patch bump from VERSION, otherwise patch bump from latest semantic tag)
  • COMMITS_INCLUDED: the commit list that will be squashed

1.3 Prepare the Squashed Release Commit

Use the same dry-run-first safety rules as ac-git-git-safe:

  1. propose the exact squash plan before executing
  2. create a backup branch before rewriting history
  3. squash the commits ahead of origin/main into one conventional commit
  4. keep CHANGELOG.md aligned with the release contents
  5. create an annotated tag for {VERSION} on the squashed commit
  6. do not push yet

After the squash/tag step succeeds, capture:

  • VERSION
  • BRANCH
  • SQUASH_SHA
  • the final squashed commit message
  • the commit list that was included

If local preparation fails: STOP - show the error and do not proceed.

Phase 1.5: Sync VERSION, package manifests, and version-pinned install docs

After the local squash/tag preparation succeeds, ensure the tracked version file, shipped package manifests, and pinned install examples all match the released version.

1.5.1 Normalize the plain version

PLAIN_VERSION=$(printf '%s' "{VERSION}" | sed 's/^v//')

1.5.2 Update VERSION

Set the VERSION file contents to {PLAIN_VERSION} exactly.

1.5.3 Update the repository root package metadata

Update the repository root package.json version field to {PLAIN_VERSION}.

Then refresh the root lockfile so the tracked version stays aligned:

npm install --package-lock-only --ignore-scripts --no-audit --no-fund

1.5.4 Update every shipped package manifest under packages/*/package.json

For each package manifest:

  • set its own version field to {PLAIN_VERSION}
  • update every internal @agentic-config/* dependency pin to {PLAIN_VERSION}
  • keep exact sibling-version alignment intact across the monorepo package set

This includes the umbrella package plus all shipped plugin packages. Use a scripted edit rather than hand-editing selected manifests so no package is skipped.

1.5.5 Update version-pinned install docs

Update these tracked files to use the released version values:

  • README.md
  • docs/getting-started.md
  • docs/distribution.md
  • packages/README.md

Required sync rules:

  • primary git-tag examples for this repository must use WaterplanAI/agentic-config@{VERSION}
  • branch-based dev examples may keep @main or another branch example when the intent is explicitly local testing/dev rather than a release tag
  • keep existing wording intact unless a pinned version string must change
  • npm distribution should remain documented as future work unless the repository has explicitly enabled and validated that path

1.5.6 Commit the sync if anything changed

git add VERSION package.json package-lock.json packages/*/package.json README.md docs/getting-started.md docs/distribution.md packages/README.md
if ! git diff --cached --quiet; then
  git commit -m "docs(release): sync version references for {VERSION}"
fi

Notes:

  • This step is mandatory when the root package version, any packages/*/package.json manifest, pinned git-tag examples, or the VERSION file changed.
  • If this creates a follow-up commit after the local squash/tag step, the existing tag re-create step below must move {VERSION} to the new HEAD.

Phase 2: Rebase onto origin/main

After the local squash/tag preparation succeeds:

2.1 Fetch Latest

git fetch origin main

2.2 Check Rebase Need

git rev-list HEAD..origin/main --count

If count > 0, main has advanced and a rebase is required.

2.3 Perform Rebase

git rebase origin/main

If rebase conflicts:

  1. show conflicting files with git status
  2. provide resolution guidance
  3. wait for the user to resolve conflicts manually
  4. continue with git rebase --continue
  5. if the user aborts, run git rebase --abort
    • note that {VERSION} still points to the pre-rebase squashed commit until Phase 3 updates it

Phase 3: Re-create Tag If Rebase Changed SHA

3.1 Check If Tag Needs Update

TAG_SHA=$(git rev-list -n1 {VERSION})
HEAD_SHA=$(git rev-parse HEAD)

If TAG_SHA != HEAD_SHA:

3.2 Delete Old Tag

git tag -d {VERSION}

3.3 Create New Tag on Rebased Commit

git tag -a {VERSION} -m "Release {VERSION}"

Phase 4: Push Branch and Tag

4.1 Force Push Branch

git push --force-with-lease origin {BRANCH}

Due to squash + possible rebase, force push is required.

4.2 Push Tag

git push origin {VERSION}

If the tag already exists on remote from an earlier failed attempt:

git push --delete origin {VERSION}
git push origin {VERSION}

Phase 5: Merge to main

5.1 Confirmation Gate

STOP HERE and show:

Ready to merge to main:
- Branch: {BRANCH}
- Version: {VERSION}
- Commit: {HEAD_SHA short}

This will:
1. Checkout main
2. Pull latest
3. Fast-forward merge from {BRANCH}
4. Push main

Proceed with merge to main? (yes/no)

Wait for explicit yes. Any other response aborts the merge while keeping the release branch/tag valid.

5.2 Execute Merge (on yes)

git checkout main
git pull origin main
git merge --ff-only {BRANCH}

If fast-forward fails:

Fast-forward merge failed. This means main has diverged.

Options:
(A) Force merge (creates merge commit)
(B) Abort - investigate manually

Choose (A/B):

On A:

git merge {BRANCH} -m "chore(release): merge {BRANCH} for {VERSION}"

On B: STOP - check out back to {BRANCH}.

5.3 Push Main

git push origin main

Phase 6: Final Report

Display summary:

## Release Complete

### Version Released
- Tag: {VERSION}
- Commit: {FINAL_SHA}
- Message: {commit message first line}
- VERSION file: synced to {PLAIN_VERSION}
- Root package metadata: synced in package.json and package-lock.json
- Shipped package manifests: synced across packages/*/package.json
- Version-pinned docs: synced in README.md, docs/getting-started.md, docs/distribution.md, and packages/README.md

### Commits Included
{COMMITS_INCLUDED}

### Branch Status
- Feature branch: {BRANCH} (pushed)
- Main branch: merged and pushed
- Tag: {VERSION} (pushed)

### Remote URLs
- Branch: {remote URL for branch}
- Main: {remote URL for main}
- Release: {remote URL for tag}

### Cleanup (optional)
To delete feature branch:
  git branch -d {BRANCH}
  git push origin --delete {BRANCH}

Abort Conditions

Condition Action
Local release preparation fails STOP: Show the validation/squash/tag error
Rebase conflicts unresolved STOP: Provide manual resolution steps
Push fails STOP: Show error and suggest manual push
Fast-forward merge fails Offer force merge or abort
User declines merge Release is valid, just not merged to main

Usage

# Full auto - no arguments needed
/skill:ac-git-release

The command will:

  1. validate release prerequisites and derive the release inputs
  2. prepare the squashed release commit and annotated tag locally
  3. rebase onto origin/main
  4. re-tag if needed
  5. push branch and tag
  6. merge to main with confirmation
  7. report the final release state