Repository navigation
Resolve CHANGELOG-only conflicts in open PRs automatically - #144
Merged
Merged
Conversation
NinjaLikesCheez
added this pull request to stack #145
October 19, 2026 07:39
When main's CHANGELOG.md changes (or a Release cuts it), a workflow merges main into each open same-repo PR that edits it. If CHANGELOG.md is the only conflict, scripts/changelog-merge.ts does a structured three-way merge of [Unreleased]: both sides' entries kept, each section once, entries after a release land in the new [Unreleased]. It refuses (and comments why) when both sides changed the same entry, a released entry was edited, or the file isn't plain Keep a Changelog. Only main's resolver runs; PR code never does. just changelog-merge / changelog-merge-driver do the same locally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Changelog-only pushes skip just check, so a test that reads CHANGELOG.md could go stale without running. Use a fixture shaped like it instead. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NinjaLikesCheez
force-pushed
the
ci/changelog-auto-merge
branch
from
October 19, 2026 07:51
f5283f0 to
b4655ab
Compare
A branch entry was only checked against main's [Unreleased], so one that had landed through another PR and been released since came back as unreleased. Check the released versions too. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Stacked on #143. Review and merge that first; this PR's base then moves to
main.Why
When one PR merges, every other open PR that added a CHANGELOG entry conflicts in
CHANGELOG.md, usually nowhere else, and the fix is nearly always "keep both". After a release, every open PR conflicts, because[Unreleased]was emptied.What it does
scripts/changelog-merge.ts: a structured three-way merge ofCHANGELOG.md, not git's lineunion(which can duplicate### Fixed, or interleave entries that span several lines). Given base / branch (PR) / main:[Unreleased]changes. Entries the branch added go at the end of their section, and a missing section is created in Keep a Changelog order, never twice. An entry both sides added is kept once. An entry the branch reworded or removed is changed only if main still has it untouched.[Unreleased]is empty or new, and the branch's added entries land there, not in the version that was cut.###heading, or prose that isn't a list entry.github/workflows/changelog-merge.yml: runs onpushtomaintouchingCHANGELOG.md. It also runs onworkflow_runafter Release, because the bump commit is pushed withGITHUB_TOKENand so doesn't firepush. Plusworkflow_dispatch. For each open, same-repo PR that editsCHANGELOG.md, it doesgit merge --no-commit origin/mainin a worktree:CHANGELOG.md→ resolve, commit, push (never forced), and commentThere's one comment per PR, edited in place. The job summary lists each PR's outcome.
Local:
just changelog-mergein a stopped merge or rebase (a rebase is detected, so the sides swap correctly).just changelog-merge-driverregisters it as a git merge driver for this clone only, via.git/info/attributes, so nothing is committed.Edge cases and how they're handled
[Unreleased]; editing a released entry → refuse### Fixedalready on a side (a bad earlier merge)CHANGELOG.mdgit merged (no install, build or hooks;.gitattributescan't name a driver without our config)GITHUB_TOKENdon't trigger CICHANGELOG_BOT_CLIENT_ID/CHANGELOG_BOT_PRIVATE_KEYare set; otherwise falls back and the comment says CI needs a re-push or close/reopen.github/workflows/changesGITHUB_TOKENcan't push that ("workflows" permission); the App has it. Without the App the push is refused and loggedSetup needed (maintainer)
Create a GitHub App with Contents, Pull requests and Workflows: read and write, and install it on
pixelbar/pixel. Then set the repo variableCHANGELOG_BOT_CLIENT_IDand the secretCHANGELOG_BOT_PRIVATE_KEY. The runbook's "Changelog conflicts" section covers it. It works without the App, with the caveats above.Verified
--gitin a real merge, a real rebase, and as a merge driver (including leaving conflict markers on refusal).just checkandjust docs-buildpass, and actionlint is clean.maininCHANGELOG.mdonly. I resolved that with this resolver (6 Fixed entries from main + this stack's Changed entry, one heading each) and pushed.main.🤖 Generated with Claude Code