Release Notes skill for Codex

Say what changed for the user, breaking first. Codex collects every merged PR between the last tag and the release commit, drops internal noise into a separate list, and rewrites what remains as effects users will notice, with breaking changes and required actions at the top. It configures release.yml categories, checks flag names against the code, and creates a draft release that is published only after you confirm.

  • Writing & Docs
  • $release-notes
  • 184 lines
  • 2 files
  • ~1,950 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- release-notes

Installs to ~/.agents/skills/release-notes/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $release-notes, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Writes release notes people actually read for a specific version - gathers merged PRs and commits since the last tag, filters out internal noise, rewrites each change as user impact, puts breaking changes and required actions first with migration steps, and formats for GitHub Releases, docs sites, app stores or in-product "What's new". Configures .github/release.yml categories and drafts with gh release create --draft. Use when preparing notes for a release or tag, when auto-generated notes are an unreadable list of PR titles, or when writing App Store or Google Play update text.

Use it when

  • A version is about to be tagged or published and needs notes
  • Auto-generated release notes are a list of developer-facing PR titles
  • A release contains breaking changes that need migration instructions

Use something else when

How to check the result

Every merged PR in the tag range is either in the notes or on the dropped list, flag names and defaults match the code at the release commit, and the user reviewed the rendered draft.

The mistake it prevents

Filing a breaking default change under 'Improved', so users upgrade without the one migration step they needed.

~/.agents/skills/release-notes/SKILL.md

--- name: release-notes description: Writes release notes people actually read for a specific version - gathers merged PRs and commits since the last tag, filters out internal noise,… license: MIT ---

Release notes are done when a user can tell in ten seconds whether they must do anything before upgrading, can find the change that matters to them, and every entry describes what they will notice, not what the team did internally.

Release notes describe one version for its users. Keeping a cumulative CHANGELOG.md file is $changelog-writing; turning a release into a marketing post or email is $changelog-to-announcement.

Gather the changes

git describe --tags --abbrev=0                       # last tag
git log --oneline --no-merges v1.8.0..HEAD           # commits since then
gh pr list --state merged --base main --search "merged:>=2026-09-01" \
  --json number,title,labels,author,body --limit 200 # PRs with labels and bodies (network)
gh api repos/{owner}/{repo}/releases/generate-notes -f tag_name=v1.9.0 -f previous_tag_name=v1.8.0 \
  --jq .body                                          # GitHub's auto draft, as raw input only

Read AGENTS.md, CONTRIBUTING.md and previous releases (gh release view v1.8.0) for the house format, tone and section names. Match them unless the user asked for a change.

If the project uses Conventional Commits, types give a first sort (feat, fix, feat!/BREAKING CHANGE:), but commit subjects are written for developers; rewrite them.

Workflow

- [ ] 1. Determine the version range (last tag..release commit) and the audience
- [ ] 2. Collect PRs/commits with labels, bodies and linked issues
- [ ] 3. Drop internal-only changes (table below); keep a list of what was dropped
- [ ] 4. Classify the rest; find breaking changes, deprecations, security fixes first
- [ ] 5. Rewrite each kept entry as user impact
- [ ] 6. Write the summary line and required-action block
- [ ] 7. Verify every claim (flag names, defaults, versions) against the code
- [ ] 8. Create a DRAFT release; publish only after the user confirms

Keep or drop

ChangeIn release notes?
New feature, option, endpoint, commandYes
Behaviour change, new default, removed optionYes, under breaking or changed
Bug fix users could have hitYes, describe the symptom that is gone
Security fixYes, with CVE/GHSA ID and severity when public; follow the disclosure plan
Performance improvement with a measurable effectYes, with the number
Dependency bump that changes supported versions or fixes a CVEYes
Refactors, CI, tests, internal tooling, typo fixes in code commentsNo
Dependency bumps with no user-visible effectNo (or one collapsed line)
Docs changesOnly if significant (new guide)

Structure

Order sections by how much they demand from the reader:

  1. Summary: one or two sentences on what this release is about.
  2. Action required / Breaking changes: what breaks, who is affected, exactly how to migrate, with before/after code.
  3. Security: fixes and advisories.
  4. New: features, with one sentence on why someone would use them and a docs link.
  5. Changed / Improved: behaviour and performance changes.
  6. Fixed: symptom-based bug fixes.
  7. Deprecated: what will be removed, in which version, and the replacement.
  8. Known issues: with workarounds.
  9. Upgrade: the command, and contributors or full changelog link if the project credits them.

Omit empty sections.

Rewriting entries

PR title (input)Release note (output)
fix: handle nil ptr in cfg loaderFixed a crash on startup when config.yaml contains an empty storage: block.
feat(api): add cursor paramList endpoints now accept a cursor parameter for stable pagination over large result sets. See Pagination.
perf: batch inserts in syncInitial sync of large workspaces is about 3x faster (12 min to 4 min for 50k records in our benchmark).
chore!: drop node 18Breaking: Node.js 18 is no longer supported. Upgrade to Node.js 20 or later before installing 3.0.

Rules:

  • Lead with the user-visible effect; mention the mechanism only if it helps them act.
  • Name exact flags, settings, endpoints and versions in code formatting.
  • Bugs: describe the symptom users saw (“exports silently skipped rows with emoji”), so people searching for their problem find it.
  • Numbers instead of adjectives (“40% smaller bundle”, not “much smaller”).
  • Credit external contributors by handle if that is the project’s convention.
  • Never promise future features or dates unless the user supplies and approves them.

Breaking change block

## Action required

**`timeout` is now in seconds, not milliseconds.** Applies to everyone who sets `timeout`
in `client.config`. Values were silently 1000x too long before; requests that relied on
very long timeouts may now fail fast.

```diff
- client = Client(timeout=30000)
+ client = Client(timeout=30)
```

GitHub configuration for better auto drafts

.github/release.yml controls how GitHub groups auto-generated notes:

changelog:
  exclude:
    labels: [skip-changelog, internal, dependencies]
    authors: [dependabot, renovate]
  categories:
    - title: Breaking changes
      labels: [breaking-change]
    - title: New features
      labels: [feature, enhancement]
    - title: Bug fixes
      labels: [bug]
    - title: Other changes
      labels: ["*"]

Auto-generated notes are a starting draft. The rewrite above is still needed.

Publishing

gh release create v1.9.0 --draft --title "v1.9.0" --notes-file release-notes.md --verify-tag
gh release view v1.9.0 --web           # let the user review the rendered draft

Creating a draft is safe. Publishing (gh release edit v1.9.0 --draft=false), pushing a tag, posting to an app store or announcing anywhere is outward-facing: do it only after the user has reviewed the draft and explicitly confirmed. Publishing a GitHub release can trigger deploy or package-publish workflows; check .github/workflows for on: release before suggesting it.

Channel formats

ChannelFormat and limits
GitHub ReleaseFull Markdown, all sections above
Docs site release pageSame content; add anchors per version for linking
App Store “What’s New”Plain text, up to 4,000 characters; 3-5 short bullet-style lines, most valuable first
Google Play “What’s new”Plain text, 500 characters per language
In-product “What’s new”One headline and one sentence per item, max 3 items, link to full notes

Gotchas

  • Copying PR titles verbatim: developer jargon, no impact, no search value.
  • Hiding a breaking change under “Changed”. If anyone must edit code or config to upgrade, it goes in “Action required”.
  • Security fixes described in enough detail to exploit before users can patch. Follow the advisory timing; link the GHSA once published.
  • Mentioning features that were merged but are behind a disabled flag in this release.
  • Version numbers in notes that do not match the tag or package version.

Verification

  • Every entry maps to a merged PR or commit in the range; every PR in the range is either in the notes or on the dropped list.
  • Flag names, defaults and supported versions checked against code at the release commit.
  • Breaking-change migration snippets run, or are marked as untested.
  • Draft rendered and reviewed by the user before any publish step.

Report

**Range:** v1.8.0..v1.9.0 (47 PRs)
**In notes:** 18 (1 breaking, 1 security, 5 new, 4 changed, 7 fixed)
**Dropped as internal:** 29 (list attached)
**Draft:** created as GitHub draft release v1.9.0, not published
**Needs confirmation:** publish the draft; whether to name the reporter of GHSA-xxxx

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Release Notes"
  short_description: "Say what changed for the user, breaking first"
  default_prompt: "$release-notes Write release notes for v2.4.0 from the PRs merged since v2.3.0"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc