| name | release |
| description | Activate when user asks to release, bump version, cut a release, merge to main, or tag a version. Handles version bumping (semver), CHANGELOG updates, PR merging, git tagging, and GitHub release creation. |
| category | process |
| scope | development |
| subcategory | release |
| tags | ["release","versioning","changelog","github"] |
| version | 10.2.18 |
| author | Karsten Samaschke |
| contact-email | karsten@vanillacore.net |
| website | https://vanillacore.net |
Release Skill
Handles the complete release workflow: version bump, CHANGELOG, merge, tag, and GitHub release.
Triggering
Use this skill when the request requires release-specific git/version actions.
Use this skill when prompts include:
- release, cut a release, ship, publish, or tag a version
- bump version (
major/minor/patch) and update changelog for release
- merge a release PR to
main
Do not use this skill for:
- regular feature PR creation to
dev (use commit-pr)
- implementation-only or planning-only requests
- explanation-only prompts with no release action request
- explain release strategy options
Acceptance Tests
| Test ID | Type | Prompt / Condition | Expected Result |
|---|
| RLS-T1 | Positive trigger | "Cut a patch release and tag it" | skill triggers |
| RLS-T2 | Positive trigger | "Merge this release PR to main and publish notes" | skill triggers |
| RLS-T3 | Negative trigger | "Create a PR to dev for this feature" | skill does not trigger |
| RLS-T4 | Negative trigger | "Explain release strategy options" | skill does not trigger |
| RLS-T5 | Behavior | skill triggered for release flow | enforces release gates, worktree/branch policy, and explicit approval for non-draft publish |
| RLS-T6 | Behavior | missing autonomy.system_level in user ica.config.json | asks user, persists autonomy.system_level, then proceeds |
| RLS-T7 | Behavior | missing autonomy.project_level in project ica.config.json | asks user, persists autonomy.project_level, then proceeds |
| RLS-T8 | Behavior | project autonomy is follow-system | resolves effective autonomy and applies it to release confirmation behavior |
| RLS-T9 | Behavior | release PR missing ICA-REVIEW-RECEIPT | runs post-PR review loop, refreshes receipt for current head SHA, then re-checks gates |
| RLS-T10 | Behavior | release PR missing ICA-SECURITY-REVIEW-RECEIPT | runs post-PR security loop, refreshes receipt for current head SHA, then re-checks gates |
| RLS-T11 | Behavior | release PR has no required checks configured | treats checks gate as pass-with-note (no required checks configured) |
| RLS-T12 | Behavior | release flow reaches merge gate | requires current review+security receipts and checks result before merge |
| RLS-T13 | Behavior | security receipt missing dedicated-subagent verification fields | fails release merge gate and requires refreshed verified security receipt |
Autonomy Level Resolution (MANDATORY)
Resolve autonomy settings from ica.config.json hierarchy (not tracking config):
- user config:
${ICA_HOME}/ica.config.json
$HOME/.codex/ica.config.json
$HOME/.claude/ica.config.json
- project config:
Required keys:
autonomy.system_level: L1 | L2 | L3 (default L2)
autonomy.project_level: follow-system | L1 | L2 | L3 (default follow-system)
Bootstrap prompts (if missing):
- If
autonomy.system_level missing:
- ask: "No system autonomy level is configured. Set system autonomy level to
L2 (recommended), L1, or L3?"
- persist in user
ica.config.json
- If
autonomy.project_level missing:
- ask: "No project autonomy level is configured. Set project autonomy level to
follow-system (recommended), L1, L2, or L3?"
- persist in project
ica.config.json
Compatibility:
- If legacy
autonomy.level exists and autonomy.system_level is missing, treat legacy value as system level for this run and persist it as autonomy.system_level.
Effective level:
- if
project_level is L1/L2/L3, use project level
- if
project_level is follow-system, use system level
Effective-level behavior for release:
L1: require explicit confirmation for each release transition (version bump commit, PR merge, tag, publish)
L2: standard release flow; explicit confirmation remains mandatory for larger-change release actions
L3: automate mechanical release actions when gates pass and release automation is enabled, while still requiring explicit approval for non-draft publish
Auto-Merge vs Agent Merge
This skill does NOT require GitHub "auto-merge" (gh pr merge --auto).
When automation is enabled, the agent performs the merge itself (runs gh pr merge) once the merge gates pass.
When to Use
- User asks to "release", "cut a release", "ship it"
- User asks to "bump version" (major/minor/patch)
- User asks to "merge to main" after PR approval
- User asks to "tag a version" or "create a release"
Prerequisites
Before releasing:
- All changes committed and pushed
- PR created and reviewed (ICA Stage 3 receipt is the required review gate by default)
- Security review receipt exists and is current for release PR head SHA
- Tests passing
- No blocking review findings
validate checks pass for release scope
- Backend-aware tracking verification passes
- Worktree/branch policy resolved from ICA config (
git.worktree_branch_behavior)
- Effective autonomy level resolved from ICA config (
autonomy.system_level + autonomy.project_level)
- Explicit user confirmation for larger changes (release is always a larger change)
Worktree + Branch Policy (ICA Config)
Read git.worktree_branch_behavior from ica.config.json hierarchy.
Allowed values:
always_new
ask
current_branch
If missing:
- ask user which behavior to use
- persist in project/user
ica.config.json
Release enforcement:
- if
always_new, use a dedicated release worktree + branch before release actions
- if
ask, ask before release actions and follow response
- even with
current_branch, release remains a larger-change flow and requires explicit confirmation
Validation And Check Gates (MANDATORY)
Pre-release gate:
- release request explicitly confirmed by user
- tests + reviewer + security review + validate all pass
- backend-aware tracking verification passes
- release PR target is
main
- branch/worktree policy is satisfied for release scope
- autonomy level resolved and applied for release scope
- required checks are green (or no required checks are configured)
Pre-tag gate:
- release PR merged successfully
- local
main is up to date and clean
- validate checks pass for release artifacts (version/changelog)
- autonomy level resolved and applied for release scope
Pre-publish gate:
- tag exists remotely
- release notes prepared and reviewed
- explicit user approval for non-draft publish (draft creation is safe-default)
- autonomy level resolved and applied for release scope
Fail-closed behavior:
- if any gate fails, STOP release progression and surface exact blocker.
Automation Controls (Skills-Level)
These controls are driven by workflow configuration (AgentTask workflow.* and ica.workflow.json):
workflow.auto_merge=true: standing approval to merge PRs once gates pass
workflow.release_automation=true: automate the mechanical release steps (tag + GitHub release creation)
Safety defaults:
- Never auto-merge to
main unless the user explicitly requested a release workflow.
- Never publish a non-draft GitHub release without explicit user approval (draft releases are OK).
Autonomy-level enforcement:
L1: pause for explicit user confirmation at each release transition.
L2: continue routine release steps after gates pass; keep explicit confirmations for larger-change actions.
L3: may proceed through gated release steps automatically when workflow settings allow, but must still respect explicit-approval rules above.
Pre-Release Receipt And Checks Loop (MANDATORY)
Before merge, release flow must verify receipts/checks for the current release PR head SHA.
If any receipt/check gate fails:
- Run post-PR reviewer Stage 3 loop on the release PR branch.
- Run post-PR security review loop on the release PR branch in a dedicated security subagent context.
- Preferred:
security-best-practices
- Escalation option:
security-engineer for high-risk/complex findings
- Push fixes when needed.
- Re-run receipt and checks verification.
Required receipt outcomes for current head SHA:
ICA-REVIEW-RECEIPT: Findings: 0, Result: PASS
ICA-SECURITY-REVIEW-RECEIPT: Findings: 0, Result: PASS, and:
Security-Reviewer-Stage: post-pr (temp checkout)
Security-Reviewer-Agent: ... (subagent)
Security-Reviewer-Execution: dedicated-security-subagent
Security-Reviewer-Executor: github:<login>
Security-Reviewer-Run-ID: <non-empty run id>
- comment author login must match
Security-Reviewer-Executor
Checks behavior:
- If required checks exist: all required checks must pass.
- If no required checks exist: record
no required checks configured and treat checks gate as pass-with-note.
Release Workflow
Step 1: Verify Ready to Release
gh pr status
gh pr view <PR-number> --json reviews
CHECKS_OUTPUT=$(gh pr checks <PR-number> 2>&1 || true)
if echo "$CHECKS_OUTPUT" | rg -q "no checks reported"; then
echo "No required checks configured; checks gate = pass-with-note."
else
echo "$CHECKS_OUTPUT"
fi
gh pr view <PR-number> --json baseRefName --jq .baseRefName
PR=<PR-number>
HEAD_SHA=$(gh pr view "$PR" --json headRefOid --jq .headRefOid)
RECEIPT=$(gh pr view "$PR" --json comments --jq '.comments | map(select(.body | contains("ICA-REVIEW-RECEIPT"))) | last | .body // ""')
echo "$RECEIPT" | rg -q "Reviewer-Stage: 3 \\(temp checkout\\)"
echo "$RECEIPT" | rg -q "Head-SHA: $HEAD_SHA"
echo "$RECEIPT" | rg -q "Result: PASS"
SEC_RECEIPT=$(gh pr view "$PR" --json comments --jq '.comments | map(select(.body | contains("ICA-SECURITY-REVIEW-RECEIPT"))) | last | .body // ""')
echo "$SEC_RECEIPT" | rg -q "Security-Reviewer-Stage: post-pr \\(temp checkout\\)"
echo "$SEC_RECEIPT" | rg -q "Security-Reviewer-Agent:.*\\(subagent\\)"
echo "$SEC_RECEIPT" | rg -q "Security-Reviewer-Execution: dedicated-security-subagent"
echo "$SEC_RECEIPT" | rg -q "^Security-Reviewer-Run-ID: [A-Za-z0-9._:-][A-Za-z0-9._:-]*$"
echo "$SEC_RECEIPT" | rg -q "Head-SHA: $HEAD_SHA"
echo "$SEC_RECEIPT" | rg -q "Result: PASS"
SEC_EXECUTOR=$(echo "$SEC_RECEIPT" | sed -n 's/^Security-Reviewer-Executor: github:\\(.*\\)$/\\1/p' | head -n1)
SEC_AUTHOR=$(gh pr view "$PR" --json comments --jq '.comments | map(select(.body | contains("ICA-SECURITY-REVIEW-RECEIPT"))) | last | .author.login // ""')
test -n "$SEC_EXECUTOR"
[ "$SEC_AUTHOR" = "$SEC_EXECUTOR" ]
Security Receipt Template (Copy/Paste)
PR=<PR-number>
HEAD_SHA=$(gh pr view "$PR" --json headRefOid --jq .headRefOid)
BASE_BRANCH=$(gh pr view "$PR" --json baseRefName --jq .baseRefName)
DATE_UTC=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
SEC_REVIEWER=$(gh api user --jq .login)
SEC_RUN_ID="sec-$(date -u +%Y%m%dT%H%M%SZ)-${HEAD_SHA:0:12}"
gh pr comment "$PR" --body "$(cat <<EOF
ICA-SECURITY-REVIEW
ICA-SECURITY-REVIEW-RECEIPT
Security-Reviewer-Stage: post-pr (temp checkout)
Security-Reviewer-Agent: security reviewer (subagent)
Security-Reviewer-Execution: dedicated-security-subagent
Security-Reviewer-Executor: github:$SEC_REVIEWER
Security-Reviewer-Run-ID: $SEC_RUN_ID
PR: #$PR
Base: $BASE_BRANCH
Head-SHA: $HEAD_SHA
Date-UTC: $DATE_UTC
Findings: 0
NO FINDINGS
Result: PASS
EOF
)"
Step 2: Determine Version Bump
Ask user if not specified:
| Type | When | Example |
|---|
major | Breaking changes | 1.0.0 → 2.0.0 |
minor | New features, backward compatible | 1.0.0 → 1.1.0 |
patch | Bug fixes, no new features | 1.0.0 → 1.0.1 |
Step 3: Update VERSION File
CURRENT=$(cat src/VERSION 2>/dev/null || cat VERSION 2>/dev/null || echo "0.0.0")
Step 4: Update CHANGELOG
Add new section at top of CHANGELOG.md:
## [X.Y.Z] - YYYY-MM-DD
### Added
- New features
### Changed
- Changes to existing features
### Fixed
- Bug fixes
### Removed
- Removed features
Derive changes from:
git log --oneline $(git describe --tags --abbrev=0 2>/dev/null || echo "HEAD~10")..HEAD
Step 5: Commit Version Bump
git add VERSION src/VERSION CHANGELOG.md
git commit -m "chore: Bump version to X.Y.Z"
git push
Step 6: Merge PR
gh pr merge <PR-number> --squash --delete-branch
Or if merge commit preferred:
gh pr merge <PR-number> --merge --delete-branch
Step 7: Create Git Tag
git checkout main
git pull origin main
git tag -a "vX.Y.Z" -m "Release vX.Y.Z"
git push origin "vX.Y.Z"
Step 8: Create GitHub Release (if using GitHub)
gh release create "vX.Y.Z" \
--draft \
--title "vX.Y.Z" \
--notes "$(cat <<'EOF'
## What's Changed
### Added
- Feature 1
- Feature 2
### Fixed
- Bug fix 1
**Full Changelog**: https://github.com/OWNER/REPO/compare/vPREV...vX.Y.Z
EOF
)"
Or generate notes automatically:
gh release create "vX.Y.Z" --generate-notes
Version File Locations
Check for VERSION in order:
src/VERSION
VERSION
package.json (for Node projects)
pyproject.toml (for Python projects)
CHANGELOG Format
Follow Keep a Changelog format:
# Changelog
All notable changes to this project will be documented in this file.
## [Unreleased]
## [X.Y.Z] - YYYY-MM-DD
### Added
### Changed
### Deprecated
### Removed
### Fixed
### Security
Safety Checks
Before any release action:
- Confirm user approval for merge
- Verify on correct branch
- Check no uncommitted changes
- Verify review and security receipts are current for PR head SHA
- Verify security receipt has dedicated-subagent verification fields and executor/author match
- Verify required checks pass (or note
no required checks configured)
- Run
validate checks for current release step
- Run backend-aware tracking verification
Integration
Works with:
- commit-pr skill - For version bump commit
- git-privacy skill - No AI attribution in release notes
- branch-protection skill - Respect branch rules
- reviewer skill - Verify no blocking findings
Examples
Patch Release
User: "Release a patch for the bug fixes"
→ Bump 1.2.3 → 1.2.4
→ Update CHANGELOG
→ Commit, merge, tag, release
Minor Release
User: "Cut a minor release with the new features"
→ Bump 1.2.3 → 1.3.0
→ Update CHANGELOG
→ Commit, merge, tag, release
Major Release
User: "Major release - we have breaking changes"
→ Bump 1.2.3 → 2.0.0
→ Update CHANGELOG (note breaking changes)
→ Commit, merge, tag, release
Rollback
If release needs to be reverted:
git tag -d vX.Y.Z
git push origin :refs/tags/vX.Y.Z
gh release delete vX.Y.Z --yes
git revert <merge-commit-sha>
Validation Checklist
Output Contract
When this skill runs, produce:
- release scope confirmation (repo, PR, branch target, bump type)
- autonomy resolution (
system_level, project_level, effective level, and whether defaults were bootstrapped)
- resolved branch/worktree policy (
git.worktree_branch_behavior) and enforcement result
- gate summary (tests, reviewer receipt, security receipt, validate, tracking verification, checks status)
- pre-release loop status (auto-remediation attempts, receipt refresh result, checks-gate result)
- security executor verification result (subagent marker, run-id, executor/author match)
- version/changelog update summary
- merge/tag/release results (PR merge status, tag, release URL/draft status)
- explicit blocker details when any gate fails