Skip to content

feat: consolidate per-package changelogs into root CHANGELOG#316

Merged
artus9033 merged 7 commits into
callstack:mainfrom
burczu:feat/automate-release-creation
May 12, 2026
Merged

feat: consolidate per-package changelogs into root CHANGELOG#316
artus9033 merged 7 commits into
callstack:mainfrom
burczu:feat/automate-release-creation

Conversation

@burczu
Copy link
Copy Markdown
Contributor

@burczu burczu commented May 8, 2026

Summary

  • Adds scripts/consolidate-changelog.ts, run as part of ci:version, which aggregates the latest release entries from each packages/*/CHANGELOG.md into a single root CHANGELOG.md.
  • Deduplicates entries across packages by PR number (falling back to commit hash, then raw text) and drops Updated dependencies noise.
  • Idempotent: if the root CHANGELOG already contains the target version, the script is a no-op. New version blocks are spliced in above existing entries so the newest release stays on top.

The script is invoked automatically by the changesets/action release workflow, so the consolidated root CHANGELOG.md is committed and pushed as part of the auto-generated chore(release): version packages PR — no manual step required.

Test plan

  • Trigger a dry run of yarn ci:version locally with pending changesets and verify root CHANGELOG.md is created/updated correctly.
  • Verify idempotency by running yarn ci:version twice and confirming no duplicate version block is added.
  • Confirm Updated dependencies lines are stripped and PRs are not duplicated across packages.
  • Confirm the next chore(release): version packages PR opened by changesets/action includes the root CHANGELOG.md change.

Adds a script run as part of `ci:version` that aggregates the latest
release entries from each package's CHANGELOG into a single root
CHANGELOG, deduplicating by PR/commit and dropping `Updated dependencies`
noise.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces an automated way to generate and maintain a consolidated root CHANGELOG.md for the monorepo by aggregating the latest release entries from each packages/*/CHANGELOG.md, and wires it into the ci:version workflow used by changesets/action.

Changes:

  • Added scripts/consolidate-changelog.ts to collect and dedupe latest per-package changelog entries into a root CHANGELOG.md, filtering out “Updated dependencies”.
  • Added scripts/package.json to mark the scripts/ folder as ESM so the TypeScript script can be executed via Node.
  • Updated root ci:version script to run the consolidation step after changeset version.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 5 comments.

File Description
scripts/package.json Marks scripts/ as ESM to support running TS scripts with ESM imports.
scripts/consolidate-changelog.ts New changelog consolidation script (parse latest versions, dedupe, write/insert root block).
package.json Runs the new consolidation script as part of ci:version.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread scripts/consolidate-changelog.ts
Comment thread scripts/consolidate-changelog.ts
Comment thread scripts/consolidate-changelog.ts
Comment thread scripts/consolidate-changelog.ts
Comment thread scripts/consolidate-changelog.ts
burczu added 5 commits May 11, 2026 09:21
fs.readdirSync makes no ordering guarantee, which left the
consolidated CHANGELOG's targetVersion selection, dedup
tiebreakers, and within-section entry order dependent on
filesystem iteration order. Sort the discovered paths so the
output is byte-stable across OS/filesystems.
The per-package dedup pass keyed entries by PR number, which
collapsed legitimate distinct changeset entries when a single
PR produced multiple changesets in one package (e.g. PR callstack#275 in
packages/brownfield). Drop the per-package dedup entirely; the
cross-package dedup in consolidate() still handles the
one-PR-shows-up-in-many-packages case correctly.
When every package's release entries are filtered out as
"Updated dependencies", the consolidated map ends up empty but
the script would still emit a bare "## <version>" block with no
content. Treat that case as a no-op and log it.
The previous literal-substring check missed legitimate matches
when the existing root CHANGELOG starts directly with the
version heading, uses CRLF newlines, or has a date/suffix after
the version. Replace with a multiline regex that matches "##"
at any line start, allows any horizontal whitespace, and ends
at a whitespace or end-of-line boundary.
indexOf('\n## ') required a preceding newline, so a root
CHANGELOG that begins directly with a "## <version>" heading
(e.g. after a human strips the "# Changelog" header) was
treated as having no version block, and new content got
appended to the end instead of spliced at the top. Switch to
a multiline regex that matches "## " at any line start,
including line 0.
Comment thread scripts/consolidate-changelog.ts Outdated
Per discussion on PR callstack#316, consumers tracking transitive
dependency bumps (e.g. for security advisories) need this
information in the consolidated root CHANGELOG. Drop the
filter so every package's "Updated dependencies" entries
flow through to the rollup.
@artus9033
Copy link
Copy Markdown
Collaborator

Thanks, let's ship it! 🚢

@artus9033 artus9033 merged commit 388663d into callstack:main May 12, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants