Back to skills
SKILL.md
Ac Release
ASecurityRelease workflow: branch, changelog, PR, tag, GH release. Triggers on keywords: release, create release, publish release, tag release
- 30 stars
- 0 votes
- 0 copies
- 1 view
- Added September 6, 2026
Works with
Security analysis
100/100npx -y skills add MatiasComercio/agentic-config --skill ac-release --agent claude-codeAre you the author of Ac Release?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/matiascomercio-ac-release)---
name: ac-release
description: "Release workflow: branch, changelog, PR, tag, GH release. Triggers on keywords: release, create release, publish release, tag release"
project-agnostic: false
allowed-tools:
- Read
- Edit
- Bash
- Grep
- Glob
- Write
- AskUserQuestion
---
# Release Skill
Automated release workflow: pre-flight, branch, changelog+version update, PR, merge, tag, GH release.
## Arguments
- `--auto` — Skip all confirmation gates (pre-flight + PR merge)
- `--preview` — Create GH release as prerelease instead of latest
## Phase 1: Pre-flight
### 1.1 Read Current State
```bash
CURRENT_VERSION=$(cat VERSION)
# Parse semver: MAJOR.MINOR.PATCH
NEXT_PATCH=$((PATCH + 1))
NEXT_VERSION="$MAJOR.$MINOR.$NEXT_PATCH"
TODAY=$(date +%Y-%m-%d)
```
Read CHANGELOG.md and extract the `## [Unreleased]` section content (everything between `## [Unreleased]` and the next `## [` header).
### 1.2 Validate
- CHANGELOG `[Unreleased]` section MUST have content (not empty)
- If empty: **STOP** — "No unreleased changes in CHANGELOG.md. Nothing to release."
- Current branch MUST be `main`
- Working tree MUST be clean (`git status --porcelain` empty)
### 1.3 Explain Procedure
Display to user:
```
Release v{NEXT_VERSION}
Current: v{CURRENT_VERSION}
Next: v{NEXT_VERSION}
Unreleased changes:
{unreleased content summary — first 10 lines}
Procedure:
1. Create branch release/v{NEXT_VERSION}
2. Update CHANGELOG.md and VERSION
3. Create PR, squash-merge to main
4. Tag v{NEXT_VERSION} on main
5. Create GH release ({"prerelease" if --preview else "latest"})
Proceed?
```
**Confirmation gate**: Use AskUserQuestion (yes/no). Skip if `--auto`.
## Phase 2: Branch
```bash
git checkout -b release/v{NEXT_VERSION}
```
## Phase 3: Update Files
### 3.1 CHANGELOG.md
Replace the `## [Unreleased]` section:
**Before:**
```
## [Unreleased]
### Added
- item A
...
```
**After:**
```
## [Unreleased]
## [{NEXT_VERSION}] - {TODAY}
### Added
- item A
...
```
The `[Unreleased]` section becomes empty (just the header), and a new versioned section is inserted immediately below it with all the previous unreleased content.
### 3.2 VERSION
Write `{NEXT_VERSION}` to VERSION file (single line, no trailing newline beyond what exists).
### 3.3 Plugin Versions
Update the `version` field in every `plugins/*/.claude-plugin/plugin.json` to `{NEXT_VERSION}`:
```bash
for f in plugins/*/.claude-plugin/plugin.json; do
# Update "version": "..." to new version
done
```
Use the Edit tool (not sed) for each file. Only change the `version` field — leave everything else untouched.
### 3.4 Commit
```bash
git add CHANGELOG.md VERSION plugins/*/.claude-plugin/plugin.json
git commit -m "chore(release): prepare v{NEXT_VERSION}"
```
## Phase 4: PR + Merge
### 4.1 Push Branch
```bash
git push -u origin release/v{NEXT_VERSION}
```
### 4.2 Create PR
Create a concise PR:
```bash
gh pr create --title "chore(release): v{NEXT_VERSION}" --body "$(cat <<'EOF'
## Release v{NEXT_VERSION}
{Concise 2-5 bullet summary of unreleased changes — high-level only, not the full changelog}
EOF
)"
```
Capture the PR number from output.
### 4.3 Confirmation Gate
Display PR URL. **Ask user to confirm merge** via AskUserQuestion. Skip if `--auto`.
### 4.4 Merge
```bash
gh pr merge {PR_NUMBER} --squash --admin
```
## Phase 5: Checkout Main
```bash
git checkout main
git pull origin main
```
## Phase 6: Tag
### 6.1 Extract Changelog Entry
Extract the `## [{NEXT_VERSION}]` section content from CHANGELOG.md (everything between `## [{NEXT_VERSION}]` header line and the next `## [` header). Include the `###` sub-headers (Added, Changed, Fixed, Removed) but NOT the `## [{NEXT_VERSION}]` line itself.
### 6.2 Create Annotated Tag
```bash
git tag -a "v{NEXT_VERSION}" -m "$(cat <<'EOF'
{changelog entry content with ### headers}
EOF
)"
```
The tag message mirrors the changelog entry content — same format as existing tags (e.g., v0.1.18).
### 6.3 Push Tag
```bash
git push origin "v{NEXT_VERSION}"
```
## Phase 7: GH Release
```bash
gh release create "v{NEXT_VERSION}" \
--title "v{NEXT_VERSION}" \
--notes "$(cat <<'EOF'
{changelog entry content — same as tag message}
EOF
)" \
{--prerelease if --preview, otherwise --latest}
```
Default: `--latest`. If `--preview` argument provided: `--prerelease` instead.
## Phase 8: Summary
```
Release complete: v{NEXT_VERSION}
- Branch: release/v{NEXT_VERSION} (merged)
- PR: {PR_URL}
- Tag: v{NEXT_VERSION}
- Release: {RELEASE_URL}
Cleanup (optional):
git branch -d release/v{NEXT_VERSION}
git push origin --delete release/v{NEXT_VERSION}
```
## Abort Conditions
| Condition | Action |
|-----------|--------|
| Empty [Unreleased] | STOP — nothing to release |
| Dirty working tree | STOP — commit or stash first |
| Not on main | STOP — checkout main first |
| PR creation fails | STOP — show error |
| Merge fails | STOP — show error, branch still exists |
| Tag push fails | Retry with `--force` if tag exists on remote from failed attempt |
| User declines at any gate | STOP — clean up branch if created |
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.