Skip to content

fix(changelog): restore history eroded by the path filter#8

Merged
Ripwords merged 2 commits into
mainfrom
fix/restore-changelog-history
Jul 17, 2026
Merged

fix(changelog): restore history eroded by the path filter#8
Ripwords merged 2 commits into
mainfrom
fix/restore-changelog-history

Conversation

@Ripwords

Copy link
Copy Markdown
Owner

Recovers the changelog history that filter_changelog_by_paths had been deleting on every release, and stops it leaving empty headings behind.

Found while testing the release-tooling refactor (#7): releasing from a clone and diffing the result showed CHANGELOG.md | 504 +-------- — 490 deletions.

What was happening

The filter ran over the whole file with a keep-set covering only FROM..HEAD, so every previously-released entry's bullets referenced SHAs outside the range and were dropped. Each release eroded a little more. The ## headings survived (no [sha] to match), so the file kept looking plausible while draining.

Entry at sdk-v0.4.0 before this PR
sdk-v0.4.0 257 bullets 2
sdk-v0.3.0 107 bullets 1
sdk-v0.2.1 4 bullets 1

That gutted file ships in the npm tarball and gets pasted into each GitHub Release. The cause is fixed in #7; this restores the data.

Restored

File before after
packages/core/CHANGELOG.md 9 bullets 65
apps/extension/CHANGELOG.md 8 bullets 205
packages/expo/CHANGELOG.md 7 bullets 29

Root CHANGELOG.md was never filtered — untouched.

Not a verbatim restore, deliberately

Each entry is recovered from its own tag's copy, where it was still intact. But sdk-v0.3.0 and sdk-v0.4.0 predate the filterb1bb22c landed 15 minutes after sdk-v0.4.0 — so their sections were never scoped and carry dashboard-only commits. Restoring those as-is would trade one wrong changelog for another.

So every recovered section gets the scoping rule applied retroactively: a bullet survives only if its commit touched that artifact's paths in that tag's range. The result is what each release would have written had the filter existed and worked. For sdk-v0.4.1/0.4.2 it's a no-op.

Nothing is invented — every line comes from the file as it existed at that tag; the only edit is dropping out-of-scope bullets. Bullets labelled dashboard: that genuinely touched packages/shared (e.g. 368d63b) are kept on purpose: the rule is paths, not the commit's scope label.

One deliberate difference: expo is scoped to packages/{expo,sdk-utils,shared}. The old release-expo.sh also passed packages/recorder, which expo doesn't depend on.

Empty subsections (separate commit)

The filter dropped bullets but left their ### heading, which carries no [sha] to match on — packages/core/CHANGELOG.md shipped 14 of 38 subsections empty (### 🏡 Chore with nothing under it). Subsections are now buffered and emitted only if a bullet survived. After: 0 empty across all three files.

Verification

Unit-tested the rewritten filter against a fixture, covering all five behaviours at once:

Behaviour Result
In-scope bullet kept ✅
Out-of-scope bullets dropped ✅
Subsection whose bullets all dropped heading removed too ✅
### ❤️ Contributors (bullet, no sha) kept ✅
Historical section, sha outside range preserved

And on the restored files: every version heading present, every bullet count up, 0 empty subsections.

Already-published npm tarballs keep their eroded copy — this fixes the repo and every future publish.

🤖 Generated with Claude Code

Ripwords and others added 2 commits July 17, 2026 12:45
The path filter removes bullets but their `### ` heading carries no [sha] to
match on, so it survived alone. packages/core/CHANGELOG.md shipped 14 of its
38 subsections empty — headings like "### 🏡 Chore" with nothing underneath.

Buffer each subsection and emit it only if at least one bullet survived.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Recovers what the whole-file filter deleted over successive releases. Each
entry is taken from its own tag's copy, where it was still intact — only
older entries were eroded by later releases:

    packages/core    9 bullets → 65
    apps/extension   8 bullets → 205
    packages/expo    7 bullets → 29

Not a verbatim restore. sdk-v0.3.0 and sdk-v0.4.0 predate the filter
(b1bb22c landed 15 minutes after sdk-v0.4.0), so their sections were never
scoped and carried dashboard-only commits — restoring those as-is would trade
one wrong changelog for another. Every recovered section gets the scoping rule
applied retroactively, so the result is what each release would have written
had the filter existed and worked. For sdk-v0.4.1/0.4.2 that's a no-op.

Nothing is invented: every line comes from the file as it existed at that tag,
and the only edit is dropping bullets whose commits didn't touch the artifact.
Bullets labelled `dashboard:` that genuinely touched packages/shared are kept
on purpose — the rule is paths, not the commit's scope label.

Expo is scoped to packages/{expo,sdk-utils,shared}; the old release-expo.sh
also passed packages/recorder, which expo doesn't depend on.

The root CHANGELOG.md was never filtered and is untouched. Already-published
npm tarballs keep their eroded copy — this fixes the repo and every future
publish.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@Ripwords
Ripwords merged commit 52ae48b into main Jul 17, 2026
8 checks passed
@Ripwords
Ripwords deleted the fix/restore-changelog-history branch July 17, 2026 04:50
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