chore: adopt changelog fragments (changelog.d/) to eliminate CHANGELOG conflicts (closes #53)#54
Merged
Merged
Conversation
…flicts Concurrent PRs each editing the shared `## [Unreleased]` block collide on merge (#50/#51/#52 all did). Replace the hand-edited block with per-PR fragment files under `changelog.d/`, assembled into a versioned section at release time. Each PR adds a unique new file, so PRs never collide. Custom (no Changesets) to preserve the `[propagate]`/`[template-only]`/ `[manual]` tags and the migration-guide + propagation flow. - `scripts/changelog.mjs` — `preview` / `check` / `release <version>`, no deps, pure helpers unit-tested in tests/unit/changelog.test.ts - `changelog.d/` — README + the three current [Unreleased] entries migrated to fragments (#43/#44/#46); CHANGELOG [Unreleased] becomes a pointer note - CI: `pnpm changelog:check` step validates fragments - Docs: docs/agents/releases.md, PR template, AGENTS.md sub-doc index - Scaffold: instances keep scripts/changelog.mjs, get a reset changelog.d/ release-check.yml is unchanged — `release` still produces the `## [X.Y.Z]` section it greps for. Verified: preflight green (42 tests), release dry-run folds + deletes fragments, scaffold dry-run yields a working instance. Closes #53.
Validation alone didn't enforce that PRs add a fragment. Add a `changelog-fragment` CI job that fails a PR which adds no fragment under changelog.d/, with a `skip-changelog` label escape hatch for changes that need no entry (typo fixes, CI tweaks, the release PR itself). - New `changelog-fragment` job in ci.yml (PR-only; skipped when labeled) - `skip-changelog` label added to scripts/labels.mjs + tasks.md + the PR template checklist - changelog.d/ fragment describing the fragments feature itself - releases.md / changelog.d/README.md document the requirement
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #53.
Concurrent PRs that each edit the shared
## [Unreleased]block collide on merge — #50, #51, and #52 all did during this batch. This replaces the hand-edited block with per-PR fragment files underchangelog.d/, assembled into a versioned section at release time. Each PR adds a unique new file, so PRs never collide on the changelog again.Custom, not Changesets — so the existing
[propagate]/[template-only]/[manual]tags, the migration-guide flow, and.constructversion tracking are all preserved. No new dependency.The new workflow
CHANGELOG.md, drop a filechangelog.d/<slug>.<category>.md(category =added/changed/fixed/…), with bullets that carry a propagation tag. Seechangelog.d/README.md.pnpm changelog:previewrenders the pending[Unreleased]section from fragments.pnpm changelog:checkvalidates fragments (now a CI step).pnpm changelog:release <version>folds fragments into a## [X.Y.Z] - DATEsection inCHANGELOG.md(grouped, tags preserved) and deletes them.What's here
scripts/changelog.mjs(no deps; pure helpers unit-tested intests/unit/changelog.test.ts, 11 tests).changelog.d/— README + the three current[Unreleased]entries migrated to fragments ([Task]: Fix the dead label-setup recovery path in scaffold #43/[Task]: CHANGELOG override claim is stale (17/~1.114.3 vs 24/exact) #44/[Task]: Pin the Node version (engines.node + .nvmrc) #46), so nothing is lost.CHANGELOG.md's[Unreleased]becomes a do-not-edit pointer note.Validate changelog fragmentsstep inci.yml.docs/agents/releases.md(fragment + release flow), the PR template checklist, and theAGENTS.mdsub-doc index.scripts/changelog.mjsand get a resetchangelog.d/(README only).release-check.ymlis intentionally untouched —releasestill writes the## [X.Y.Z]section it greps for, so the version-bump rule keeps working.Verification (local)
pnpm preflightgreen — Biome + tsc + 42 tests (incl. the 11 new ones).release 0.3.0dry-run in a throwaway copy: inserted the section above[0.2.0], preserved tags, deleted the 3 consumed fragments (README kept).changelog.mjs,changelog.d/reset to README-only,changelog:checkpasses, and instancepreflightruns the survivingchangelog.test.ts(23 tests).Design choices worth your eyes
[Unreleased]is kept as a heading with a "do not hand-edit" note (vs. removing it entirely) — keeps the file readable andrelease-checkhappy.*.added.md); bullets keep their propagation tags verbatim.🤖 Generated with Claude Code
Generated by Claude Code