Skip to content

Commit fd23d1f

Browse files
committed
feat: add github-release slash command for creating GitHub releases
1 parent 1ffcec3 commit fd23d1f

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

.claude/commands/github-release.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
---
2+
name: github-release
3+
description: Create a GitHub release with auto-generated release notes matching the style of previous releases
4+
allowed-tools: Bash, Read, Write, Edit, AskUserQuestion
5+
argument-hint: "<version> (e.g., 1.2.3 or v1.2.3)"
6+
---
7+
8+
# GitHub Release
9+
10+
## Input
11+
12+
**Version argument**: `$ARGUMENTS`
13+
**Working directory**: !`pwd`
14+
15+
## Git Safety Rules
16+
17+
- This command creates tags and GitHub releases — confirm with the user before executing
18+
- **NEVER** force-push, delete tags, or delete releases without explicit user request
19+
- All tags and versions MUST have a leading `v` prefix (e.g., `v1.2.3`)
20+
21+
---
22+
23+
## Step 1: Parse & Validate Version
24+
25+
1. Extract the version from `$ARGUMENTS`
26+
2. Strip leading `v` if present, then re-add it — the canonical version is always `v{major}.{minor}.{patch}`
27+
3. Validate it looks like a semver version (e.g., `1.2.3`, `v1.2.3`)
28+
4. If invalid or missing, ask the user for a valid version using `AskUserQuestion`
29+
5. Confirm the repo has a GitHub remote: `git remote get-url origin`
30+
31+
## Step 2: Identify Current Repo Context
32+
33+
Run these commands to understand the repo:
34+
35+
```bash
36+
# Get the GitHub owner/repo
37+
gh repo view --json nameWithOwner -q '.nameWithOwner'
38+
39+
# Get the default branch
40+
git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'
41+
42+
# Get the latest 2 releases for style reference
43+
gh release list --limit 2
44+
45+
# Get the most recent release tag
46+
gh release view --json tagName -q '.tagName'
47+
```
48+
49+
## Step 3: Study Previous Release Style
50+
51+
1. Fetch the last 2 releases' notes:
52+
```bash
53+
gh release view <tag1> --json body -q '.body'
54+
gh release view <tag2> --json body -q '.body'
55+
```
56+
2. Analyze the format: heading style, grouping (features/fixes/etc.), bullet format, whether commit hashes or PR numbers are included, any intro/outro text, emoji usage, contributor mentions, etc.
57+
3. Note the pattern so the new release notes match it precisely.
58+
59+
## Step 4: Gather Changes Since Last Release
60+
61+
1. Get the diff between the most recent release tag and the current HEAD of `main`:
62+
```bash
63+
# Commit log
64+
git log <latest-tag>..origin/main --oneline --no-merges
65+
66+
# Optionally, also check merge commits for PR titles
67+
git log <latest-tag>..origin/main --merges --oneline
68+
```
69+
2. If there are merged PRs, fetch their titles/numbers:
70+
```bash
71+
gh pr list --state merged --base main --search "merged:>=$(git log -1 --format=%aI <latest-tag>)" --limit 50 --json number,title,labels
72+
```
73+
3. Collect the full picture of what changed.
74+
75+
## Step 5: Compose Release Notes
76+
77+
1. Write release notes that **match the exact format and style** observed in Step 3
78+
2. Group changes the same way previous releases did (e.g., by category, by type, flat list, etc.)
79+
3. Use the same heading levels, bullet styles, emoji patterns, and any other conventions
80+
4. Include the same kinds of references (commit SHAs, PR numbers, contributor mentions) as previous releases
81+
5. Present the draft to the user for review using `AskUserQuestion` with options:
82+
- "Looks good, create the release"
83+
- "Let me edit first" (then ask for their edits)
84+
85+
## Step 6: Create the Release
86+
87+
Once the user approves:
88+
89+
```bash
90+
gh release create v{version} \
91+
--target main \
92+
--title "v{version}" \
93+
--notes "<approved-release-notes>"
94+
```
95+
96+
Report the release URL back to the user:
97+
```bash
98+
gh release view v{version} --json url -q '.url'
99+
```
100+
101+
---
102+
103+
## Error Handling
104+
105+
- If `gh` CLI is not authenticated, tell the user to run `! gh auth login`
106+
- If there are no previous releases, ask the user what format they'd like and use that
107+
- If the tag already exists, inform the user and ask how to proceed
108+
- If there are no changes since the last release, warn the user before proceeding

0 commit comments

Comments
 (0)