Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Draft Release Notes

ASecurity

Draft the GitHub release notes for a RomM release, stable or alpha/beta prerelease, from the diff since the previous stable tag, in the house format the published RomM releases use. Use when asked to "draft the 5.3.0 notes", "write the release notes for the beta", "what goes in the 5.3.0-alpha.1 notes", or to refresh a draft after more PRs land. Produces callouts, Highlights, Minor changes, Fixes, Other changes, API changes and New Contributors, and never publishes.

13,119 stars
0 votes
0 copies
1 views
Added 9/20/2026
documentationgobashgitapifrontendbackenddocumentation

Works with

api

Security Analysis

A100/100

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add rommapp/romm --skill draft-release-notes --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Draft Release Notes?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Draft Release Notes
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/rommapp-draft-release-notes/badge)](https://www.skillsdirectory.com/skills/rommapp-draft-release-notes)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: draft-release-notes
description: Draft the GitHub release notes for a RomM release, stable or alpha/beta prerelease, from the diff since the previous stable tag, in the house format the published RomM releases use. Use when asked to "draft the 5.3.0 notes", "write the release notes for the beta", "what goes in the 5.3.0-alpha.1 notes", or to refresh a draft after more PRs land. Produces callouts, Highlights, Minor changes, Fixes, Other changes, API changes and New Contributors, and never publishes.
argument-hint: "[tag to draft, e.g. 5.3.0 or 5.3.0-alpha.1 | nothing to infer it]"
---

# Drafting release notes

Turn a tag range into the notes RomM actually publishes, for a stable release or
for an alpha/beta prerelease. The GitHub autogenerated list is raw material, not
the deliverable: the published notes reorganize it into sections, lift the few
changes that matter into prose Highlights, and add the callouts an upgrader needs
before they pull the image.

Output a markdown file and print it. **Never** run `gh release create` or
`gh release edit`. Publishing is the maintainer's call.

---

## 1. Pick the shape

Two documents exist, and the tag decides which one you are writing.

| Tag                                                 | Document                              |
| --------------------------------------------------- | ------------------------------------- |
| `X.Y.Z`, `X.Y.Z-alpha.1`, `X.Y.Z-beta.1`            | the full treatment, sections 3 onward |
| `X.Y.Z-alpha.2` and later, `X.Y.Z-beta.2` and later | flat `## What's Changed`              |
| a stable patch with no `feat:` work                 | flat `## What's Changed`              |

This is what the history does without exception: every `.1` prerelease and every
feature-carrying stable gets Highlights and partitioned bullets, while every
later prerelease in the same line is a plain list of what landed since. The flat
shape is just the autogenerated body with `## New Contributors` and the compare
link kept, so for those tags steps 4 through 6 do not apply.

## 2. Resolve the range

`$ARGUMENTS` is the tag being drafted. If it is empty, infer it: take the last
stable tag, bump minor for a range containing `feat:` work or patch otherwise,
and say which you picked so it can be corrected.

The base is **the stable tag below the release line**, for a stable release and a
prerelease alike, so a whole line accumulates against one base. `5.1.0-alpha.1`,
`5.1.0-beta.1` and `5.1.0` all compare against `5.0.0`, which makes each document
a superset of the one before it rather than a delta on top of it.

```bash
TAG=5.3.0-alpha.1                       # what you are drafting, stable or prerelease
LINE=${TAG%%-*}                         # 5.3.0, the stable version of this line
git fetch origin master --tags

# the stable tag immediately below $LINE. Numeric tags only, since the legacy
# v-prefixed ones sort above them, and sort -V rather than --sort=v:refname
BASE=$(git tag --list '[0-9]*' | grep -vE -- '-(alpha|beta|rc)' | grep -vFx "$LINE" \
  | { cat; echo "$LINE"; } | sort -V | grep -B1 -Fx "$LINE" | head -1)

# an already-tagged prerelease is drafted against its tag, not against master,
# or the draft picks up everything merged since it shipped
if git rev-parse -q --verify "refs/tags/$TAG" >/dev/null; then HEAD_REF="$TAG"; else HEAD_REF=origin/master; fi

RANGE="$BASE..$HEAD_REF"
git rev-list --count $RANGE
git diff --stat $RANGE | tail -20
```

Sanity-check the pair before going further. `$BASE` should equal the tag in the
previous release's compare link. If `$TAG` is a prerelease and `$LINE` is already
tagged stable, the line has shipped and `$TAG` is wrong: stop and confirm the
version.

## 3. Pull the raw material

The autogenerated list is the spine. Its **order is merge order, keep it** when
you partition lines into sections, and keep each line's `by @user in <url>` tail
byte for byte so attribution and first-time-contributor detection stay correct.

```bash
gh api repos/rommapp/romm/releases/generate-notes \
  -f tag_name="$TAG" -f previous_tag_name="$BASE" --jq '.body' > /tmp/raw-notes.md
```

Then run the sweeps that find what the PR titles do not say. They are an index,
not an answer: a `@protected_route(...)` or `_get_env(...)` call wrapped across
lines matches only on the line that actually changed, so a moved path or a new
default can surface as a bare `+@protected_route(`. Read the full hunks of every
file a sweep touches before writing the tables.

```bash
# new or changed env vars
git diff $RANGE -- backend/config/__init__.py | grep -E '^[+-].*_get_env'
# new, moved or removed routes
git diff $RANGE -- backend/endpoints/ | grep -E '^[+-].*@(protected_route|router\.)'
# response-schema changes the frontend types are generated from
git diff --stat $RANGE -- backend/endpoints/responses/ backend/handler/scan_handler.py
# migrations, which imply an irreversible upgrade step
git diff --name-status $RANGE -- backend/alembic/versions/
# config.yml surface
git diff $RANGE -- backend/config/config_manager.py | grep -E '^[+-].*(class |: )' | head -40
```

```bash
# the sweeps only point at files, so read what actually changed inside them
git diff $RANGE -- backend/endpoints/ backend/config/
```

For each candidate Highlight, read the PR itself rather than paraphrasing its
title: `gh pr view <n> --json title,body,author`. The prose in the notes is
usually a compression of the PR description.

## 4. Assemble the document

Follow `template.md` in this skill directory for the exact skeleton. Sections in
this order, all optional except the last two:

| Section               | Contents                                                             |
| --------------------- | -------------------------------------------------------------------- |
| Callouts              | `> [!WARNING]` upgrade actions, `> [!NOTE]` env vars and API changes |
| `## Highlights`       | `### Title` + prose per headline feature                             |
| `## Minor changes`    | every `feat:` PR not already a Highlight                             |
| `## Fixes`            | every `fix:` PR                                                      |
| `## Other changes`    | `perf:`, `chore:`, `docs:`, `refactor:`, `revert:`, `build(deps):`   |
| API changes           | table, inline for an alpha, in `<details>` once it gets long         |
| `## New Contributors` | verbatim from the autogenerated body                                 |
| `**Full Changelog**`  | verbatim from the autogenerated body                                 |

Which of the two optional tables you carry depends on the line, not on whether
the tag is stable. See section 6.

**A patch release skips all of it**, stable or prerelease. Under roughly eight
PRs with no `feat:`, publish a single flat `## What's Changed` list plus the
changelog link, the way `4.9.1-beta.1` and `4.9.1` both did. Do not manufacture
Highlights for a bugfix release.

## 5. Section rules

**Highlights.** Three to eight for a minor line, zero for a patch line. A change
earns one only if it changes what a user can do or how they run RomM: a new
subsystem, a new metadata source, a new UI surface, a new export format. Format:

- `### Sentence case name of the thing`, no trailing punctuation.
- One or two short paragraphs, second person, present tense. Say what it does,
  then the one thing the reader has to know to use it (the config key, the
  setting, the caveat). Name real keys and paths in backticks.
- End the first paragraph with a space and the bare PR reference, `#3211`. Bare
  `#NNNN` in
  prose, full URLs only in the bullet lists.
- Add a fenced `yaml` block when a config key drives the feature.
- Leave a `<!-- screenshot: ... -->` placeholder for anything visual. Do not
  invent `user-images.githubusercontent.com` URLs; the maintainer pastes real
  ones.

**Bullet sections.** One line per PR, copied from the autogenerated body. Fix up
only the title, in place: give it a conventional-commit prefix and scope if it
lacks one (`Skip DMCA-locked grids when scraping SteamGridDB` becomes
`fix: Skip DMCA-locked grids when scraping SteamGridDB`), and lowercase a shouty
one. Never drop a PR, never merge two into one line, never reorder across
sections. Promoting a PR to a Highlight **removes** its bullet: every published
release does this, so `5.1.0-beta.1` lists neither #3211 nor #3854 under Minor
changes, and #3155 left the `4.9.0-alpha.1` bullets once the beta gave it a
Highlight. Promote or list, never both.

`build(deps):` and `dependabot[bot]` lines always land in Other changes, never
in Fixes, even when the bump closes a CVE. Call the CVE out in a callout instead
if it matters.

**Callouts.** A `> [!WARNING]` is for something the upgrader must do, and it goes
at the very top, above Highlights: a renamed `config.yml` key, a DB privilege
the migration needs, a proxy cache to purge. Write the migration action, not the
rationale. A `> [!NOTE]` carries the env var table and the API change table. A
`> [!IMPORTANT]` marks a feature shipping ahead of its documentation.

Env vars go in a table with `variable | default | description`; API changes in a
table with `Change | Description` for edits, and `Method | Path | Description`
for a new endpoint group. Prefix a breaking entry with `⚠️`.

## 6. Prerelease versus stable

The three documents on a line are the same document, regenerated over a range
that keeps growing against a fixed base. Each one starts as its predecessor, not
as a blank page, so open the previous one's body and edit that:

```bash
# the release before $TAG on this line: its alpha.1, or its last full beta
gh release view 5.1.0-beta.1 --json body --jq .body
```

- **alpha.1** opens the line. Put the env var and API tables in one `> [!NOTE]`
  block at the top, where the third-party app developers reading the alpha will
  see them first.
- **beta.1** is the alpha's notes plus everything merged since. Carry the alpha's
  Highlights across verbatim unless the feature changed, add the new ones, and
  fold in any warning that alpha feedback produced. Once the API table runs past
  roughly fifteen rows, move it to the bottom inside
  `<details><summary><h2>API changes</h2></summary>`, since by the beta most
  readers are upgraders rather than integrators.
- **the stable release** is the last full-treatment prerelease's notes plus
  everything merged during the beta. Two things change:

  **Re-curate the Highlights.** They are not carried over untouched. Going from
  `5.0.0-beta.1` to `5.0.0`, four were added (CRT mode, server-side ROM patching,
  the permission system, the music player), three were dropped, and three were
  renamed, "A brand-new frontend" becoming "UI overhaul". Pick what the finished
  release is about, not what the beta was about.

  **Drop the tables a prerelease already published.** The API table is for the
  developers tracking the line, and they read it in the alpha. `5.1.0`, `5.0.0`,
  `4.9.0` and `4.8.0` all dropped theirs; `5.2.0` kept one only because its line
  shipped no prerelease that carried it. Keep the env var table when it grew
  during the beta, as `5.1.0` did going from three variables to seven, since a
  reader upgrading straight from the last stable has seen none of them.

## 7. Before handing it over

- Every PR in `/tmp/raw-notes.md` is accounted for exactly once, either as a
  Highlight or as a bullet, never both and never dropped.
- Every `#NNNN` in the Highlights resolves to a PR in the range.
- Every new env var found in step 3 is documented, and every route change too.
- A migration in the range means you have checked whether it needs a warning.
- The `**Full Changelog**` compare link ends in the tag you are drafting. Editing
  a prerelease's body into a stable one makes this easy to miss: `4.9.0` shipped
  pointing at `4.8.1...4.9.0-beta.1`.
- No em-dashes, no invented screenshot URLs, no marketing claims the diff does
  not support.

Print the draft and say what you could not determine (which screenshots are
needed, which version you inferred), rather than guessing.

Attribution

rommapprommapp
View sourceMore from rommapp →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

Context Fundamentals

Understand the components, mechanics, and constraints of context in agent systems. Use when designing agent architectures, debugging context-related failures, or optimizing context usage.

179001 votes

release-notes

Draft release notes and changelog entries from git history or merged PRs between two refs (tags/SHAs/branches), including breaking changes, migrations, and upgrade steps. Use when the user asks for release notes, changelog updates, or a GitHub Release draft.

1301 votes

docs-style-guide

Documentation style guide enforcer by @planetabhi. Applies and reviews the writing style guide when authoring or editing product documentation and tutorials. Use to check prose for voice, tense, word choice, inclusive language, formatting, code block, UI, Markdown, and number/date conventions.

11 votes

Caveman Help

Quick-reference card for caveman modes, skills and commands. Trigger: /caveman-help or "caveman help".

1074700 votes

How It Works

Explain how claude-mem captures observations, when memory injection kicks in, and where data lives. Use when the user asks "how does claude-mem work?" or "what is this thing doing?".

947440 votes
View all in documentation →