Changelog to Announcement skill for Codex
From commit-speak to a launch people care about. Codex sorts changelog entries into one headline, supporting changes, fixes and breaking changes, checks each public claim against the release tag, feature flags and plan gating, then writes a single core message that every channel draft derives from. Breaking changes get a separate notice for affected users only, and nothing is published or emailed until you approve the specific draft.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- changelog-to-announcement Installs to ~/.agents/skills/changelog-to-announcement/ for every project on this machine.
curl -fsSL codexskills.dev/cli.mjs -o codex-skills.mjsnode codex-skills.mjs install changelog-to-announcement The CLI also searches, updates and removes skills. Run it with no arguments to pick from a list. Needs Node 20.12+.
curl -fsSL codexskills.dev/install.sh \ | sh -s -- --project changelog-to-announcement Installs to .agents/skills/changelog-to-announcement/ in the current repository. Commit it and everyone who runs Codex there gets it.
curl -fsSLO codexskills.dev/downloads/changelog-to-announcement.zipunzip -o changelog-to-announcement.zip -d ~/.agents/skills/ The archive holds the skill folder with its generated agents/openai.yaml. Unzip into .agents/skills/ to scope it to a repo.
& ([scriptblock]::Create((irm codexskills.dev/install.ps1))) changelog-to-announcement PowerShell 5.1 or 7. Installs to %USERPROFILE%\.agents\skills\. Add -Project for the current repo.
104-line POSIX script. No sudo, no telemetry. Read install.sh
Use it in Codex
Start a prompt with $changelog-to-announcement, 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
Turns a changelog, release tag, merged PR list or git log into launch announcements people read - picks one headline change, rewrites entries as user outcomes, verifies availability and limits against the code, and produces channel-specific drafts for a blog post, customer email, in-app note, social posts and community channels, with breaking changes routed only to affected users. Use when asked to announce a release, write a launch post or update email from CHANGELOG.md or GitHub releases, or summarize what shipped this month for customers.
Use it when
- A release is tagged and needs customer-facing announcements
- You have a changelog or PR list but no story for users
- A release includes breaking changes that must reach the right users
- Marketing needs blog, email and social drafts that agree with each other
Use something else when
- You are writing the changelog entries themselves: use changelog-writing
- You need versioned notes for existing users inside the product docs: use release-notes
- You are planning a full launch campaign across communities: use product-launch
How to check the result
Every claim in the drafts is checked against the release tag, flags and plan config or listed for confirmation, and names, dates and numbers match across all channels.
The mistake it prevents
Announcing a feature that is still behind a flag or limited to one plan as if everyone has it today.
A changelog is a record for people who already care; an announcement must make someone who does not yet care understand what they can do now that they could not before. Done well: one clear headline, every claim true for the plans and versions it names, each channel gets a draft shaped for how it is read, and nothing is published or sent until the user approves.
Gather the source material
cat CHANGELOG.md | sed -n '1,120p' # latest section first
git tag --sort=-creatordate | head -5
git log v2.3.0..v2.4.0 --no-merges --format='%h %s' | head -80
gh release view v2.4.0 --json name,body,publishedAt # needs network + gh auth
gh pr list --state merged --search "merged:>=2026-10-01" --limit 100 --json number,title,labels
Also ask the user for: the audience (developers, admins, end users, buyers), plan or tier
availability, rollout state (GA, beta, percentage rollout, feature flag), launch date and
time zone, and any embargo. If entries come from internal tickets, confirm which items are
public. Writing the changelog itself belongs to $changelog-writing; per-version release
notes for existing users belong to $release-notes; a full launch campaign (Product Hunt,
Hacker News, communities) belongs to $product-launch.
Workflow
- [ ] 1. Sort entries: headline, supporting, fixes, internal (drop), breaking
- [ ] 2. Verify each public claim against code, flags, docs and plan config
- [ ] 3. Write the core message: headline, 3 supporting points, CTA
- [ ] 4. Draft each requested channel from the core message
- [ ] 5. Separate breaking-change notice for affected users only
- [ ] 6. Fact and consistency pass across all drafts
- [ ] 7. Hand drafts to the user; publish or send only on a clear yes
1. Sort the entries
| Bucket | What goes in | Where it appears |
|---|---|---|
| Headline | The single change most users will care about, ideally something they asked for | Title, subject line, first sentence everywhere |
| Supporting | 2-4 notable improvements | Short sections or bullets |
| Fixes and polish | Bug fixes users noticed, performance with numbers | One grouped list, or “and 23 fixes” with a link |
| Breaking or deprecations | Anything that requires user action | Every channel mentions it; affected users get a direct notice |
| Internal | Refactors, CI, dependency bumps without user effect | Dropped |
If nothing qualifies as a headline, make it a roundup (“October: 12 improvements to search and billing”) rather than inflating a minor change.
2. Verify claims before writing them
Changelog lines are written by engineers in a hurry. Before a claim goes public:
- Feature exists in the released tag, not just on main:
git branch -r --contains <sha>or check the tag includes the PR merge commit (git merge-base --is-ancestor <sha> v2.4.0). - Feature flag or rollout:
rg -n "feature_flag_name|isEnabled\(" src/and ask whether it is on for everyone at launch. - Plan gating: check entitlement config; “available on all plans” is a common error.
- Numbers (“3x faster”, “50% smaller”): find the benchmark or metric and its conditions. No source, no number.
- Limits and platform support: max sizes, regions, browsers, OS versions.
- Docs exist for the feature and the link works.
Put anything unverified in a “needs confirmation” list for the user instead of the draft.
3. Core message
Write this once; every channel derives from it so they stay consistent.
Headline: Schedule reports to Slack and email (all paid plans, GA Nov 4)
Outcome: Teams stop exporting dashboards by hand every Monday.
How: Pick a dashboard, choose a schedule and destination; filters are preserved.
Proof: Beta customers replaced ~3 h/week of manual exports (beta survey, n=42).
Supporting: 1) CSV export 4x faster on 1M-row tables 2) Saved filters 3) Dark mode for embeds
Breaking: Legacy /v1/export endpoint removed Jan 15; affects API users of /v1 only.
CTA: Set up your first scheduled report -> docs link
Translate entries from mechanism to outcome:
| Changelog | Announcement |
|---|---|
Added cron field to report config | Send any dashboard on a schedule, to Slack or email |
| Switched CSV writer to streaming | Large CSV exports finish up to 4x faster and no longer time out |
| Fix: tz offset in date filter | Date filters now respect your workspace time zone |
4. Channel drafts
| Channel | Length | Shape |
|---|---|---|
| Blog post | 400-900 words | Problem, headline feature with screenshot or GIF, how to use it in 3 steps, supporting items, fixes link, what is next |
| Customer email | 80-200 words | Subject = outcome; one feature, one CTA button; others as a short list |
| In-app note / what’s new | 1-3 sentences | What it is, where to find it, link; shown to users who can use it |
| X / Bluesky / Threads | under 280 chars or a short thread | Outcome first, one visual, link; no hashtag clutter |
| 80-200 words | Customer problem framing, outcome, one proof point, link | |
| Discord / Slack community | Short post | Friendly, direct, links to docs and feedback thread; answer questions there |
| Docs “What’s new” | Bullets | Dated, links to each feature’s docs page |
Email subject lines: specific and outcome-led (“Send dashboards to Slack on a schedule”), under ~60 characters, no all caps or fake urgency. Preview text extends the subject; it does not repeat it.
Social: lead with the visible result; write the post so it makes sense without the link. Provide alt text for every image or GIF.
5. Breaking changes and deprecations
- Announce in every channel, but send a direct notice to affected users (API users of the endpoint, customers on the old plan) identified by the user’s data, not everyone.
- Include: what changes, the date, who is affected, how to tell if you are affected, exact migration steps or a migration guide link, and where to get help.
- Give lead time proportional to effort: weeks for config changes, months for API removals.
Follow the project’s deprecation policy if one exists (
$semantic-versioning).
Subject: Action needed by Jan 15: /v1/export is being removed
You are receiving this because your workspace called /v1/export in the last 30 days.
On January 15, 2027 the endpoint will stop responding. Switch to /v2/exports (same
fields, paginated): migration guide <link>. Reply to this email if you need more time.
6. Consistency pass
- [ ] Same feature names, plan names, dates and numbers in every draft
- [ ] Every link resolves (docs, blog, migration guide); UTM tags if marketing uses them
- [ ] Availability stated precisely (plans, regions, rollout %, beta label)
- [ ] No internal codenames, ticket IDs, employee names or unreleased roadmap dates
- [ ] Screenshots show the released UI, no real customer data
- [ ] Each draft has exactly one primary call to action
7. Publishing
Publishing a post, sending an email, posting to social or community channels are all
outward-facing. Deliver drafts as files (for example announcements/2026-11-v2.4/blog.md,
email.md, social.md) plus the “needs confirmation” list. Publish, schedule or send only
after the user explicitly approves the specific draft and channel.
Gotchas
- Announcing a feature that is still behind a flag for most users; support gets flooded.
- Leading with the feature with the biggest diff rather than the one users asked for.
- Copying changelog jargon (“idempotent retries for webhook dispatcher”) into customer email.
- Burying a breaking change in a celebratory post; affected users miss it and churn.
- Different numbers in the blog and the email because each was edited separately; derive both from the core message and re-run the consistency pass after edits.
Verification
- Every claim in the drafts is either verified (with the check noted) or listed under “needs confirmation”.
- Each channel draft fits its length guideline and has one call to action.
- Affected-user notice exists for every breaking change and states date, impact and steps.
- Report to the user: drafts produced, open confirmations, suggested send and publish order.
What the zip contains
SKILL.md plus the interface file below. Nothing runs on install.
agents/openai.yaml
Gives the Codex app a display name, a one-line description and a starter prompt for this skill.
interface:
display_name: "Changelog to Announcement"
short_description: "From commit-speak to a launch people care about"
default_prompt: "$changelog-to-announcement Turn the v2.4.0 changelog into a blog post and a customer email" 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.