mcpField
R
release-notes

release-notes

github.com/niekcandaeleDevelopment647 installsUpdated 2d ago
Repository

About release-notes

release-notes is a skill for turning commits, pull requests and issue context into concise, user-facing release notes. It helps maintainers explain what changed and why, using narrative prose rather than a commit dump.

Key features

  1. 01Collects changes from Git ranges and branches
  2. 02Looks up PR and issue context
  3. 03Filters internal-only changes
  4. 04Groups related changes and flags breaking changes
  5. 05Writes concise narrative release notes

Use cases

  1. 01Drafting notes for a version release
  2. 02Summarizing changes across a feature branch
  3. 03Explaining the user impact of linked PRs and issues

Install

Copy the command and run it in a terminal.

$npx skills add https://github.com/niekcandaele/skills --skill release-notes

After installing, type/release-notesin Claude Code to confirm it loaded.

Details

From the project README

Release Notes Generator

Generate user-facing release notes from: $ARGUMENTS

Release notes are for humans, not machines. The goal is to communicate what changed and why it matters — at the level your audience cares about. A commit documents code evolution; a release note documents significance to the user.

Step 1: Parse Input

Detect what the user provided and gather the raw change data accordingly.

Version/tag range (matches v1.2.0..v1.3.0 or 1.2..1.3):

git log --format='%H %s' $RANGE
git log --format='%B---COMMIT_BOUNDARY---' $RANGE
git diff --stat $RANGE

Branch comparison (matches main..feature or origin/main..HEAD):

git log --format='%H %s' $RANGE
git log --format='%B---COMMIT_BOUNDARY---' $RANGE
git diff --stat $RANGE

PR numbers (matches #42, #43, etc.):

gh pr view <num> --json title,body,commits,labels

Raw text: If the input doesn't match any pattern above, treat it as a direct description of changes. Skip git commands and work from the text. Also skip Steps 2 and 3 — go straight to Step 4.

No arguments: Compare current branch against base:

CURRENT_BRANCH=$(git branch --show-current)
DEFAULT_BRANCH=$(git symbolic-ref refs/remotes/origin/HEAD 2>/dev/null | sed 's@^refs/remotes/origin/@@')
# Fallback: try main, master, develop
git log --format='%H %s' $DEFAULT_BRANCH..$CURRENT_BRANCH
git log --format='%B---COMMIT_BOUNDARY---' $DEFAULT_BRANCH..$CURRENT_BRANCH
git diff --stat $DEFAULT_BRANCH..$CURRENT_BRANCH

Step 2: Detect Platform

Figure out where this project lives and where its issues are tracked. These can be different — a project might host code on GitHub but track issues in Jira.

Code host

Parse the git remote to detect the platform:

git remote get-url origin
  • github.com → GitHub, use gh CLI
  • gitlab.com (or a custom GitLab domain) → GitLab, use glab CLI
  • Anything else → git-only mode (skip PR/issue lookups)
Issue tracker

Scan the commit messages gathered in Step 1 for reference patterns:

  • #123 style references → issues live on the code host (GitHub or GitLab)
  • PROJ-123 style references (uppercase letters, dash, number) → Jira. Use the Atlassian MCP tools if available (mcp__claude_ai_Atlassian__getJiraIssue)
  • Both patterns can appear in the same project — check for both

If the platform tools aren't available or authentication fails, fall back gracefully to git-only mode. Don't block on this.

Step 3: Deep Dive — Follow the References

This is what turns a commit log paraphrase into real release notes. Commits tell you what changed in code. PRs tell you why it was done. Issues tell you who asked for it and what problem they had. All three are important.

Extract references

Scan every commit message from Step 1 for:

  • PR/MR numbers: #123 (GitHub), !123 (GitLab)
  • Issue numbers: #456 (GitHub/GitLab), PROJ-789 (Jira)
  • URLs pointing to PRs or issues

Deduplicate — many commits reference the same PR. Build a unique list of PRs and issues to fetch.

Fetch PRs/MRs

For each unique PR reference:

GitHub:

gh pr view <num> --json title,body,closingIssuesReferences,labels,commits

GitLab:

glab mr view <num> --output json

Read the PR description carefully — this is where developers explain:

  • The motivation for the change
  • What user-visible impact it has
  • Design decisions and trade-offs
  • Screenshots or before/after comparisons
Fetch linked issues

For each issue referenced by PRs (via closingIssuesReferences on GitHub, or mentioned in PR/commit text):

GitHub:

gh issue view <num> --json title,body,labels

GitLab:

glab issue view <num> --output json

Jira: Use mcp__claude_ai_Atlassian__getJiraIssue with the issue key (e.g., PROJ-789).

Issue bodies are where the real context lives — user stories, bug reports with reproduction steps, feature requests explaining what users need and why. This is gold for writing release notes that speak to users.

Build a context map

For each logical change, you now have up to three layers of context:

  • Commits — what changed in code
  • PR description — why it was done, how it was approached
  • Issue body — the original user request, bug report, or feature spec
  • Labels — categorization hints (bug, feature, breaking-change, security, etc.)

Not every change will have all three. Some commits won't reference a PR. Some PRs won't link to issues. Use whatever is available — even one layer deeper than the commit message dramatically improves the release notes.

Scaling for large releases

For releases with many commits (50+), focus your lookups on unique PRs — most commits map back to a small number of PRs. If there are too many to fetch individually, prioritize:

  1. PRs with breaking, security, or feature labels
  2. PRs that close issues (they have user-facing context)
  3. PRs with the longest descriptions (more context to work with)

Step 4: Understand the Project

Before writing anything, understand who will read these notes. Scan the repo quickly:

  1. Project type: Check package.json, Cargo.toml, pyproject.toml, go.mod, or README.md to determine if this is a library, CLI tool, web app, API, framework, or plugin
  2. Audience: Library → developers/API consumers. CLI → terminal users. Web app → end users. API → integrators
  3. Existing changelog: Check for CHANGELOG.md, CHANGES.md, or HISTORY.md. If one exists, read its most recent entry and match its conventions (heading style, entry format, tone)

This context shapes every decision in the next steps — a library's notes can mention API changes directly, while an end-user app's notes should describe outcomes, not implementation.

Step 5: Analyze and Curate

This is the core transformation — turning code changes into user-facing communication. Use the full context map from Step 3, not just commit messages.

Filter out noise

Skip changes that don't affect users:

  • CI/CD configuration changes (unless they affect release/deploy behavior users depend on)
  • Linter/formatter config, whitespace fixes
  • Internal refactoring with no behavior change
  • Dependency version bumps (unless they fix a user-visible bug or security issue)
  • Test-only changes
Group related commits

Multiple commits that implement one feature or fix become one entry. Look for:

  • Commits referencing the same PR or issue number
  • Sequential commits touching the same files with related messages
  • "fixup" or "address review" commits that follow an initial implementation
Identify breaking changes

Scan for these signals — breaking changes must never be buried:

  • BREAKING CHANGE: or BREAKING: in commit bodies
  • ! after the type in conventional commits (e.g., feat!:)
  • Removed public APIs, changed function signatures, renamed config options
  • Database migrations that require user action
  • Changed default behavior
  • Labels like breaking, breaking-change on PRs
Transform language using the full context

This is where the deep dive pays off. Instead of just rephrasing commit messages, use the richer context:

  • Issue has a bug report? Use the user's experience to frame the fix: "Players reported crashes when joining servers with custom mods" → "Fix crash when joining modded servers"
  • PR description explains user impact? Prefer that framing over the commit title
  • Issue has a feature request with use cases? Explain what users can now do, not what was implemented
  • Labels indicate category? Use them to help with grouping (bug, feature, security, etc.)
  • No deeper context available? Fall back to transforming the commit message as before

Examples of the transformation:

  • Commit: "Fix null pointer in UserService.getProfile()" / Issue: "App crashes when I click my profile" → "Fix crash when viewing user profiles"
  • Commit: "Add Redis caching to product queries" / PR: "Product search was taking 3+ seconds for large catalogs" → "Speed up product search — results now load instantly even for large catalogs"
  • Commit: "Bump lodash from 4.17.20 to 4.17.21" → "Fix security vulnerability in lodash dependency" (if it's a security fix) or skip (if routine)

Step 6: Write the Notes

The release notes should read as short narrative prose — a few paragraphs that tell the story of the release. Not a bullet list, not a categorized changelog. The raw commit/PR list already exists; the point of this skill is to produce something different: a human summary that someone can read in 30 seconds and understand what changed and why it matters.

Structure

Group related changes into short paragraphs by theme. A natural flow is:

  1. Lead with the headline features — what's new and exciting. Open with the version number in bold and go straight into what the biggest additions are, explaining what they enable for the user.
  2. Infrastructure or performance improvements — if there are backend changes that affect the user experience (faster queries, better scalability), weave them into a paragraph.
  3. Smaller improvements and UX changes — navigation improvements, new views, quality-of-life additions.
  4. Bug fixes — close with a paragraph summarizing the reliability and bug fix work. You don't need to list every fix individually — group them by theme ("several reliability issues", "a handful of UI bugs") and call out the most notable ones specifically.

Not every release needs all four sections. A small patch release might be a single paragraph. A major release might need five or six. Let the content dictate the shape.

Tone
  • Write in present tense, conversational but not casual — like a thoughtful teammate explaining the release to someone who uses the product
  • Use "you" to address the reader directly ("you can now import your shop listings")
  • Technical terms are fine when the audience would know them — don't dumb things down, but don't use internal jargon either
  • Keep it tight. Each paragraph should be 2-4 sentences. The whole thing should be readable in under a minute
Breaking changes

If the release has breaking changes, lead with them before everything else. Be direct about what changed and what the user needs to do. This is the one place where a short bullet list is appropriate — breaking changes need to be scannable and unmissable.

Example

Here's what good narrative release notes look like:

**v0.5.0** introduces Shop Actions, a new module component type that lets you
create automated actions triggered by shop purchases — opening up new
possibilities for your in-game economy. You can now also react to player
inventory changes through hook events, enabling modules for loot tracking,
item-based triggers, and more.

On the infrastructure side, events are now stored in ClickHouse, which means
faster queries and better scalability as your player count grows. If you're
migrating from CSMM, you can now import your shop listings directly.

This release also fixes several reliability issues — database connection pool
exhaustion that could occur around midnight, cronjob failures under high load,
and a handful of UI bugs including the version number incorrectly showing as
"0.0.0".

Notice: no bullet lists, no category headers, no "Added/Fixed/Changed" taxonomy. Just clear prose that a user can read and understand.

What to avoid

  • Bullet lists and categorized changelogs: the raw changelog already exists — don't recreate it in a slightly different format. The value of this skill is the narrative transformation
  • Commit log dumps: listing every commit verbatim defeats the purpose
  • Vague summaries: "Various bug fixes and improvements" tells the reader nothing
  • Internal-only changes: users don't care about CI pipeline config or dependency bumps
  • Jargon mismatch: don't tell end users about "middleware refactoring" — tell them what's faster or fixed
  • Buried breaking changes: if something breaks existing usage, it goes first

Output

Present the release notes directly in the conversation. Do not write to a file unless the user explicitly asks — and if they do, ask where they want it (CHANGELOG.md, RELEASE_NOTES.md, etc.).

When writing to a GitHub release or file, structure it as:

  1. The narrative summary at the top
  2. A horizontal rule (---)
  3. The full raw changelog below — visible, not hidden in a collapsible/spoiler tag. People will miss it otherwise.

Comments

Markdown supported