skills/create-release/SKILL.md
Push a release branch and open a PR to the target branch. Step 2 of the release workflow — runs after branching, before merging.
npx skillsauth add nexus-a1/claude-skills create-releaseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Workflow:
/create-release-branch→/create-release→/merge-release→/release
Working directory: !pwd
Current branch: !git branch --show-current 2>/dev/null || echo "(not in a git repository)"
Available branches: !git branch -a --list 'master' 'main' 'develop' 'release/*' 'origin/master' 'origin/main' 'origin/release/*' 2>/dev/null || echo "(no branches)"
Arguments provided: $ARGUMENTS
Release terminology — see ${CLAUDE_PLUGIN_ROOT}/shared/release-concepts.md.
Thin dispatcher over ${CLAUDE_PLUGIN_ROOT}/shared/release/. Run all steps in a single message; use parallel tool calls where independent. Do not re-derive parsing, ref resolution, ticket extraction, or gh-CLI mechanics — call the scripts and surface their structured output.
git rev-parse --is-inside-work-tree 2>/dev/null
If non-zero, stop with the standard "not in a git repository" message instructing the user to cd into a service repo.
bash "${CLAUDE_PLUGIN_ROOT}/shared/release/parse-args.sh" \
--skill=pr-create --json -- $ARGUMENTS
Outcomes:
target and version/release_branch populated; proceed.missing contains version. Run version-suggest.sh --json and use AskUserQuestion to pick. Re-run parser with the chosen version. version-suggest.sh fetches remote tags first so the suggestion reflects the authoritative tag set; watch its stderr — if it emits a [stale-tags] or [no-remote] marker, surface that to the user before presenting the recommendation (the version may be based on stale local tags). Do not block on the marker; continue.commits-data.sh self-fetches both refs from origin and prefers origin/<ref> during resolution, so a stale local release branch will not mask real upstream commits. No manual git fetch needed.
bash "${CLAUDE_PLUGIN_ROOT}/shared/release/commits-data.sh" \
--base=<target> --head=<release_branch> --json
The output JSON has:
commit_count — true count across the full rangecommits_returned, truncated — how many entries commits[] actually holds; true when the range exceeds --limit (default 500). Aggregates are full-range; only commits[] is sliced (oldest dropped). When truncated, disclose "showing N of M commits" in the PR body.file_counttickets[] — uppercased, deduped ticket IDs (e.g. JIRA-123)breakdown — counts by conventional-commit type (feat, fix, chore, …)has_breaking_changecommits[] — per-commit {short, subject, type, scope, tickets, breaking} (full sha is intentionally omitted; short is what release notes render and GitHub auto-links)If commit_count == 0, stop with: "No commits to release — release branch matches the target."
The shell library does not generate the PR body. That is your job.
Title: defaults to Release <version> (the script will use this if you pass --title="" or omit it). Override only if the user asked for something custom.
Body: write a concise, well-organized markdown PR body using the JSON from Step 2. A good shape:
## Release v1.2.0
<one-paragraph summary derived from breakdown — e.g. "12 commits: 4 feat, 6 fix, 1 chore. No breaking changes.">
## Tickets
- JIRA-123, JIRA-456 …
## Highlights
- **feat(api)**: <subject from a feat commit>
- **fix(ui)**: <subject from a fix commit>
- (group by type, surface the most user-visible items)
## Commits
- abcd123 feat(api): subject — JIRA-123
- (full list, oldest-first or newest-first; pick whichever reads better)
## Testing checklist
- [ ] Manual smoke test
- [ ] Release notes reviewed
- [ ] Breaking changes documented (if any)
If has_breaking_change is true, surface it prominently at the top.
Write the body to a tempfile under .claude/session-state/ (or /tmp/ if the workspace path isn't available):
# Use the Write tool to create the file at e.g.
# .claude/session-state/release-pr-body-<version>.md
bash "${CLAUDE_PLUGIN_ROOT}/shared/release/pr-create.sh" \
--target=<target> --release-branch=<release_branch> \
--plan --json
The output reports:
existing_pr — non-null if an open PR exists for this head branchwill_push_branch (bool) — apply will run git push -u origin <release_branch> firstwill_update_existing (bool) — apply will edit the existing PR rather than create a new one (requires --update-existing)will_refuse_existing (bool) — apply would refuse because a PR is already open and --update-existing was not passedShow the plan summary to the user. If existing_pr.state == "OPEN", surface the URL and use AskUserQuestion to ask whether to update that PR (re-run apply with --update-existing) or abort.
Use AskUserQuestion to confirm: Open release PR now?.
If the user confirms, record the audit gate (this script issues git push):
bash "${CLAUDE_PLUGIN_ROOT}/hooks/record-audit.sh"
Immediately followed by apply:
bash "${CLAUDE_PLUGIN_ROOT}/shared/release/pr-create.sh" \
--target=<target> --release-branch=<release_branch> \
--body-file=<tempfile> [--title="<custom>"] \
--apply [--update-existing] --json
If apply exits non-zero, surface stderr verbatim and stop.
On success:
✓ Release PR <created|updated>
PR: #<n>
url: <url>
branch: <release_branch> → <target>
Next:
/merge-release # merge once approved
record-audit.sh must run immediately before pr-create.sh --apply, since the script issues git push. Do not run anything between them that could change HEAD or branch.commits-data.sh is what you have to work with. Keep it factual and grouped, no marketing voice.development
Add a new entry to the product knowledge base. Wizard-guided — prompts for category, title, and content, then writes a structured markdown file and rebuilds the manifest.
data-ai
Show all active work sessions across brainstorms, requirements, proposals, and epics. Supports --update to advance lifecycle on one session and --sync to sweep them all.
documentation
Review and update project documentation using an agent team. Inventories docs, identifies gaps and drift, updates technical and API docs in parallel.
tools
Annotate an active work session with a note, scope change, or new finding. Auto-detects the active session, synthesizes the salient points of the current conversation, and appends a timestamped entry to state.json after a single target confirmation. Use mid-session when you learn something that should be preserved.