write-release-notes · diff
git:20260312.6987017 to git:20260315.d684df9
2 added, 1 removed. Audit A to A.
---
name: write-release-notes
description: Generate engaging, high-energy release notes for a given version tag. Fetches the release from GitHub, retrieves every linked PR's title and description, then synthesizes all changes into a polished, user-facing release note with an enthusiastic tone. Use when the user asks to write, generate, or create release notes for a version (e.g. "write release notes for v1.32.0", "generate release notes for the latest release", "create changelog for v2.0").
---
# Write Release Notes
Generate compelling, high-energy release notes by pulling live data from GitHub and synthesizing every PR into a cohesive narrative.
## Workflow
### 1. Fetch Release Data
Run the bundled script to pull the release metadata and all linked PR details in one shot:
```bash
bash .forge/skills/write-release-notes/scripts/fetch-release-data.sh <version> [owner/repo]
```
- `<version>`: The release tag (e.g. `v1.32.0`)
- `[owner/repo]`: Optional. Defaults to the current repo detected via `gh repo view`.
The script outputs two sections:
- `### RELEASE METADATA ###` — tag name, publish date, release name, raw body
- `### PR DETAILS ###` — one JSON object per PR with: `number`, `title`, `body`, `labels`, `author`, `mergedAt`, `url`
### 2. Categorize Changes
Group PRs by their conventional commit prefix or label:
| Category | Prefixes / Labels |
|---|---|
| Features | `feat`, `type: feature` |
| Bug Fixes | `fix`, `type: fix` |
| Performance | `perf` |
| Refactors | `refactor` |
| Maintenance | `chore`, `docs`, `ci`, `build`, `deps` |
Dependency bumps (e.g. Dependabot PRs) go into Maintenance. Skip PRs with `error: "not found"`.
### 3. Write the Release Notes
Produce a Markdown document with the following structure. Keep the tone **exciting, punchy, and developer-friendly** — celebrate wins, highlight impact, and make readers feel the momentum.
```markdown
# [Product Name] [Version] — [Punchy Tagline]
> One-sentence hook that captures the spirit of this release.
## What's New
[2-4 sentence narrative that weaves together the biggest features and fixes.
Speak to impact, not implementation. Use active voice. Be enthusiastic.]
## Highlights
### [Feature/Fix Category]
**[PR Title rephrased as user benefit]** ([#NNN](url))
[1-2 sentences expanding on the PR description. Focus on what the user gains.
If the PR body has useful context, distill it. If empty, infer from the title.]
[Repeat for each significant PR — skip pure chores/dep bumps unless noteworthy]
## Bug Fixes & Reliability
[Bullet list of fixes, each with a brief impact statement and PR link]
## Under the Hood
[Brief paragraph or bullet list covering refactors, maintenance, and dep updates —
keep it light, acknowledge the work without boring the reader]
## Contributors
- A huge thank you to everyone who made this release happen: [list @handles]
+ A huge thank you to everyone who made this release happen: [list @handles — exclude bots like @dependabot]
---
**Full changelog**: [GitHub Release link]
```
### 4. Tone & Style Guidelines
- **Lead with value**: "You can now..." beats "We added..."
- **Be specific**: Name the feature, not just the category
- **Use energy words**: "blazing", "seamless", "rock-solid", "powerful", "finally"
- **Short paragraphs**: Max 3 sentences per block
- **Skip internal jargon**: Translate crate names and internal concepts into plain language
- **Celebrate contributors**: Name them enthusiastically
- **Tagline formula**: `[Version] — [Adjective] [Theme]` (e.g. "v1.32.0 — Smarter Config, Smoother Workflows")
+ - **No implementation details**: Do not mention internal module names, struct names, function names, crate names, or how something was implemented. Focus purely on what the user experiences or gains.
### 5. Output
Print the final release notes directly in the chat. Do not write to a file unless the user explicitly asks.
## Notes
- The script handles ANSI color codes injected by `gh` CLI automatically.
- PRs not found (closed without merge, private, etc.) are silently skipped.
- If the release has no linked PRs in its body, fall back to listing commits between tags:
```bash
gh api repos/<owner>/<repo>/compare/<prev_tag>...<version> --jq '.commits[].commit.message'
```