Create release
Push a release branch and open a PR to the target branch. Step 2 of the release workflow — runs after branching, before merging.From its SKILL.md
npx -y skills add nexus-a1/claude-skills --skill create-releaseAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
6.8 KB, as published. Nobody here has run it
Create Release PR Command
Workflow:
/create-release-branch→/create-release→/merge-release→/release
Context
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.
Your Task
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.
Step 0 — Pre-flight: verify git repo
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.
Step 1 — Parse arguments
bash "${CLAUDE_PLUGIN_ROOT}/shared/release/parse-args.sh" \
--skill=pr-create --json -- $ARGUMENTS
Outcomes:
- Exit 0 —
targetandversion/release_branchpopulated; proceed. - Exit 10 —
missingcontainsversion. Runversion-suggest.sh --jsonand use AskUserQuestion to pick. Re-run parser with the chosen version.version-suggest.shfetches 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. - Exit 20 — surface errors and stop.
Step 2 — Gather commit data
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 entriescommits[]actually holds;truewhen the range exceeds--limit(default 500). Aggregates are full-range; onlycommits[]is sliced (oldest dropped). Whentruncated, 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;shortis what release notes render and GitHub auto-links)
If commit_count == 0, stop with: "No commits to release — release branch matches the target."
Step 3 — Author PR title and body
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
Step 4 — Plan: validate via pr-create.sh
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 rungit 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-existingwas not passed
Show 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.
Step 5 — Confirm and apply
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.
Step 6 — Report
On success:
✓ Release PR <created|updated>
PR: #<n>
url: <url>
branch: <release_branch> → <target>
Next:
/merge-release # merge once approved
Important Notes
- Single message execution — all steps in one assistant turn.
- No re-derived gh/git logic in prose — every gh/git operation goes through the shared scripts.
- Audit gate —
record-audit.shmust run immediately beforepr-create.sh --apply, since the script issuesgit push. Do not run anything between them that could change HEAD or branch. - Body authoring is your job — the shell scripts deliberately don't template prose; the JSON from
commits-data.shis what you have to work with. Keep it factual and grouped, no marketing voice.