Skip to content

fix(version): attribute changelog entries per package, not per squash commit#94

Draft
exo-mv wants to merge 1 commit into
masterfrom
mv/changelog-per-commit-attribution
Draft

fix(version): attribute changelog entries per package, not per squash commit#94
exo-mv wants to merge 1 commit into
masterfrom
mv/changelog-per-commit-attribution

Conversation

@exo-mv

@exo-mv exo-mv commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • A squash-merged PR that touches multiple packages no longer copies its whole commit message (breaking-change footers, Co-Authored-By trailers, sub-commit bullets) into every touched package's changelog. Each squash commit is decomposed back into its pre-squash commits (fetched from the PR) and re-attributed by file path, so a BREAKING CHANGE lands only in the changelog of the package whose files the breaking commit actually touched.
  • Implemented as an options.transform hook on conventional-changelog-core, so tag detection, range, version header, links, and grouping are unchanged.
  • Applies to every path. The explicit-bumps and static-strategy paths already let this action write changelogs; the conventional-commits path now runs lerna version --no-changelog (lerna still derives the per-package bumps) and routes through the same generator, instead of leaving the leak in lerna's own changelog code.
  • PR-commits fetch extracted to utils/pr-commits and shared with version-dispatch, so changelog and bump attribution agree. Non-squash commits fall back to prior behavior.

Out of scope

On the conventional-commits path, lerna still decides the version bump per package, and it over-attributes a breaking squash commit to every package the commit touched (the motivation for the per-package bumps flow in #82). This PR fixes the changelog there but not the bump — a multi-package conventional release can still mis-bump a consumer. Correct multi-package bumps come from the explicit/version-dispatch flow.

Test plan

  • Unit + real-git integration specs (changelog-transform.spec.ts, update-changelog.spec.ts): the cross-package leak is gone; the legacy path still reproduces it.
  • Live-validated in actions-playground, both paths — one squash touching batcave (breaking) + gadgets (consumer):
    • Explicit bumps: gadgets@1.0.1 changelog has only its own fix; batcave@5.0.0 keeps the breaking note.
    • conventional-commits: gadgets changelog has no BREAKING CHANGES section (leak gone); batcave keeps both breaking notes. (lerna did mis-bump gadgets to major here — the out-of-scope item above.)

🤖 Generated with Claude Code

@exo-mv exo-mv force-pushed the mv/changelog-per-commit-attribution branch from 15be46d to e297d48 Compare June 29, 2026 19:09
… commit

A squash-merged PR collapses its commits into one, so conventional-changelog —
which keys a commit to a package by the files it touched — rendered the whole
squash message (breaking-change footers and Co-Authored-By trailers included)
into the changelog of every package the PR touched. This leaked one package's
BREAKING CHANGE into unrelated packages' changelogs and dumped the squashed
body verbatim.

Re-attribute each squash commit to its package with an `options.transform` hook
on conventional-changelog-core: decompose the commit back into the PR's
pre-squash commits (fetched from the API), keep only those whose files map to
the package being released, and re-parse each on its own so unrelated bodies
never bleed in. Each emitted entry is stamped with the squash commit's hash and
a `(#PR)` reference so links still resolve to the merged commit and PR.

Route every path through this generator. The explicit-`bumps` and static paths
already let this action write changelogs; the conventional-commits path now runs
`lerna version --no-changelog` (lerna still derives the per-package bumps) so it
does too, instead of leaving the leak in lerna's own changelog generation.

The PR-commits fetch is extracted to utils/pr-commits and shared with
version-dispatch, so changelog attribution and bump attribution agree on which
commit touched which package. Non-squash commits fall back to
conventional-changelog's previous behavior unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@exo-mv exo-mv force-pushed the mv/changelog-per-commit-attribution branch from e297d48 to 40cbfe7 Compare June 29, 2026 19:41
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.

1 participant