| name | write-changelog |
| description | Add or update entries in the repo's hand-maintained CHANGELOG.md, and stamp the "Unreleased" section with a version and date when cutting a release. Use when asked to update the changelog, document a change for release notes, record a breaking change, or prepare CHANGELOG.md for a new version. |
Write Changelog
CHANGELOG.md at the repo root is the single changelog for all four
published packages (@authgear/core, @authgear/web,
@authgear/react-native, @authgear/capacitor) — they share one version
number, bumped together via npm run set-version <version>.
This file used to be regenerated by git-chglog from commit messages, but
that tool was never wired into CI or any script (nothing in this repo ran
it automatically) and the file went stale for a long time before anyone
noticed. It is now maintained by hand, one entry at a time, as changes
land — not generated in bulk right before a release.
Everything from <a name="v2.11.0"></a> downward is the old
git-chglog-generated history. Leave it untouched: don't reformat it,
don't try to make old entries match the new style.
Write For The Reader Deciding Whether To Upgrade
The single biggest failure mode is writing too much. A changelog entry is
not a PR description, not a migration guide, and not a record of how the
work was done — it's a scannable answer to "does this affect me, and if
so, what do I do about it?" Before adding a bullet, cut anything that
isn't one of those two things.
Concretely:
- Only state what changed. Never state what didn't. If a reasonable
question is "did X change?" and the answer is no, that's a reason to
not write a bullet, not a reason to write "X did not change." An
early draft of the entry below had a whole bullet reassuring readers
that minimum React Native/Android/iOS/toolchain versions were
unchanged — it was deleted, not shortened, once that became clear.
- Don't explain internal process, tooling, or how a change was
verified, unless the reader needs that to decide what to do. "We
switched changelog tools" is not something a consumer of
@authgear/react-native cares about, even though it's true and even
though it prompted real investigation — that story belongs in this
skill file or in commit messages, not in CHANGELOG.md.
- Don't hedge with unverified caveats as padding. If you genuinely
didn't test something and it's relevant, say so in one clause, not a
paragraph. If it's not relevant enough to change what the reader does,
cut it.
- A bullet should survive being read once, quickly, right before
someone runs their own upgrade. If it takes re-reading to extract
the actionable part, it's too long.
Here's the actual entry this repo settled on, after trimming a much
longer draft that explained the migration's history, listed several
unchanged version floors, and included an unverified compatibility
caveat — none of which survived:
- **react-native:** No longer ships pre-generated native code. Native
bindings are now generated by your app's own React Native build via
standard autolinking/codegen. No JS API changes. If your app's
native build bypasses autolinking, verify a clean build still
generates `AuthgearReactNativeSpec` before upgrading.
One bullet. States what changed, states the one thing worth checking,
and stops.
When To Add An Entry
Add an entry as part of the same piece of work that makes the change —
not as an afterthought before tagging a release. If you just finished a
change that a consumer of any of the four packages would care about
(a new API, a fixed bug, a breaking change, a dependency bump that
changes runtime behavior), add a bullet under ## [Unreleased] before
considering the work done.
Skip entries for changes with no consumer-visible effect: internal
refactors, test-only changes, CI/tooling changes that don't touch a
published package, doc typo fixes. This applies even to changes that
took real work or investigation — effort spent isn't a reason to
document something a consumer can't observe. (Dropping git-chglog
itself is exactly this kind of change: real work, zero entry, because
no consumer of a published package is affected by which tool maintains
this file.)
Format
CHANGELOG.md follows Keep a Changelog
style. The top of the file always looks like this:
# Changelog
## [Unreleased]
### Breaking Changes
- **react-native:** Short summary of what changed and why. Explain what a
consumer needs to do differently, not just what the code diff was.
### Added
- **web:** Short summary.
### Fixed
- **capacitor:** Short summary.
Rules:
- Categories, in this order when present:
Breaking Changes, Added,
Changed, Fixed, Removed, Security. Omit any category with no
entries — don't leave empty headers.
- Scope prefix: start each bullet with the affected package in bold —
**core:**, **web:**, **react-native:**, **capacitor:** — or
**deps:** for dependency-only changes, or no prefix if it affects all
packages equally (e.g. a repo-wide tooling change).
- Write for the consumer, not for git log. "Bump lodash to 4.17.21"
is a worse entry than "Fixed a prototype-pollution vulnerability in a
transitive dependency." Say what changed in behavior/API, and for
breaking changes, say what the consumer needs to do about it.
- Breaking changes need a migration note, not just a description:
what changed, and exactly what to check or do differently.
- Before writing a breaking-change entry, check whether these changed:
minimum supported React Native/Android/iOS version,
peerDependencies
ranges, toolchain requirements (Node/Gradle/Xcode/Ruby), public
JS/TS API surface. Mention only the ones that actually changed. Checking
is for your own diligence, not a reason to report "unchanged" — see
"Write For The Reader" above.
- Keep bullets to a few lines. This file is scanned, not read end to end.
Cutting A Release
When actually tagging a release (not before):
- Decide the version number based on
## [Unreleased]'s contents — any
Breaking Changes entries mean a major bump (this project is past
1.0, so breaking changes always bump the major version); otherwise
follow normal semver judgment for the rest.
- Rename
## [Unreleased] to
## [vX.Y.Z](https://github.com/authgear/authgear-sdk-js/compare/vPREVIOUS...vX.Y.Z) (YYYY-MM-DD),
using today's date and the actual previous released tag.
- Add a fresh empty
## [Unreleased] section above it for the next round
of changes.
- Run
npm run set-version X.Y.Z to sync the version across all
packages/*/package.json, lock files, and
packages/authgear-core/src/index.ts's VERSION constant.
- Commit, tag
vX.Y.Z, and push the tag — CI publishes to npm from the
tag (see .github/workflows/ci.yaml's publish job and
scripts/npm-publish.sh).
Correcting An Entry Already Under Unreleased
If a later change in the same release cycle supersedes or fixes an
already-logged Unreleased entry, edit that bullet directly rather than
appending a second entry about the same change. The changelog should
describe the net effect for someone who only reads it once, right before
upgrading — not a diary of how the work happened.