Use this skill to draft or update the [Unreleased] section of CHANGELOG.md from the actual changes since the last tag. Run this at any point during development to keep a working copy of the release narrative. Does NOT bump versions or create tags.
Update the [Unreleased] section at the top of CHANGELOG.md with a narrative release story based on the real changes since the last tag. This is a non-destructive working copy — run it as many times as you want during development.
Identify the last release tag and gather changes.
LAST_TAG=$(git tag --list "v*" --sort=-v:refname | head -n 1)
echo "Last tag: $LAST_TAG"
Then collect raw material from three sources:
a. Commit log since last tag:
git log --oneline "$LAST_TAG"..HEAD
b. GitHub-generated release notes preview (PR titles, new contributors):
gh api repos/:owner/:repo/releases/generate-notes \
-f tag_name="vNEXT" \
-f target_commitish="$(git rev-parse HEAD)" \
-f previous_tag_name="$LAST_TAG" \
--jq '.body'
c. Diff stat for theme analysis:
git diff --stat "$LAST_TAG"..HEAD
Draft the release narrative.
Write markdown for the [Unreleased] section following the format below. Do not include the ## [Unreleased] heading itself — just the body content.
Update CHANGELOG.md.
Replace everything between ## [Unreleased] and the next ## [ heading with the new draft. Preserve the HTML comment header and all existing release sections below.
The [Unreleased] section must always exist and always be the first section after the header comments.
Do NOT commit, tag, or bump versions. Just leave the file modified in the working tree.
Structure the [Unreleased] section like this:
## [Unreleased]
<One strong opening paragraph: what this release is about and why it matters.
Tie it to concrete shipped changes. No vague hype.>
<One paragraph on major technical shifts, if applicable.>
### <Feature/Theme Group>
- Bullet points with specifics
- Reference PRs where available: ([#123](https://github.com/jamiepine/voicebox/pull/123))
### <Another Group>
- ...
### Bug Fixes
- ...
If git log "$LAST_TAG"..HEAD is empty, leave the [Unreleased] section empty (just the heading) and tell the user there's nothing to draft.
[Unreleased] section. It never modifies stamped release sections.release-bump skill depends on this draft being up to date before it finalizes.