Skip to content

Use changelog fragments to avoid PR conflicts #921

@piotr-iohk

Description

@piotr-iohk

Problem or use case

Image

Current agent and PR guidance asks every user-facing feat: and fix: PR to add exactly one entry under ## [Unreleased] in CHANGELOG.md, placing new entries at the top of the relevant Keep a Changelog category.

This creates recurring merge conflicts because multiple open PRs edit the same lines near the top of CHANGELOG.md. After one PR merges, other unmerged PRs often need conflict resolution even when their code changes are unrelated.

We still want polished, reviewed changelog text while the PR author and AI agent have the context for the change. The issue is where that text is stored before release, not the existence of the changelog entry itself.

Proposed solution

Introduce changelog.d/ fragments and stop editing CHANGELOG.md in normal feature/fix PRs.

Suggested structure:

changelog.d/
  next/
    .gitkeep
  hotfix/
    .gitkeep

Normal release fragments go in changelog.d/next/. Hotfix fragments go in changelog.d/hotfix/.

Fragment filenames should use:

<issue-or-pr>.<category>.md

Examples:

changelog.d/next/917.fixed.md
changelog.d/next/905.changed.md
changelog.d/hotfix/931.fixed.md

Allowed categories:

  • added
  • changed
  • deprecated
  • removed
  • fixed
  • security

Each fragment should contain one polished user-facing sentence without a leading bullet and without a PR number.

Example:

Return to Bitkit after Pubky Ring approval, cancellation, or error callbacks.

Release tooling should:

  1. Read fragments from the selected target directory: next for normal releases, hotfix for hotfix releases.
  2. Group entries by category using the category suffix in the filename.
  3. Insert grouped entries into CHANGELOG.md using Keep a Changelog headings.
  4. Append the PR or issue number from the filename when numeric.
  5. Delete only the consumed fragment files.
  6. Keep .gitkeep files.

Normal release example:

./scripts/collect-changelog.sh --target next --version 2.3.0

Hotfix release example:

./scripts/collect-changelog.sh --target hotfix --version 2.2.1

Hotfix releases must not consume or move changelog.d/next/ fragments.

Required repository updates:

  • Add changelog.d/next/.gitkeep and changelog.d/hotfix/.gitkeep.
  • Add a script to collect fragments into CHANGELOG.md.
  • Update the release command to run the collection step instead of expecting CHANGELOG.md to already contain unreleased entries.
  • Update AGENTS.md changelog rules so agents create fragments rather than editing CHANGELOG.md.
  • Update .cursor/rules/rules.main.mdc with the same changelog guidance.
  • Update the PR template changelog comment to mention fragment files.

Acceptance criteria:

  • Feature and fix PRs no longer edit CHANGELOG.md directly.
  • User-facing feature and fix PRs include exactly one changelog fragment.
  • Non-user-facing chore, CI, refactor, test, and docs PRs do not require fragments unless the change is user-facing.
  • Release tooling can consume changelog.d/next/*.md into a normal release changelog section.
  • Release tooling can consume changelog.d/hotfix/*.md into a hotfix release changelog section without touching next fragments.
  • Consumed fragments are removed during the release commit.
  • Generated changelog entries preserve polished wording from the fragment and append the PR number when available.
  • Existing released changelog sections are not modified.

Alternatives considered

  • Use a scheduled workflow to generate changelog entries from merged PRs, but this moves wording review until after merge.
  • Generate entries from PR labels and titles, but PR titles are often less polished than dedicated changelog text.
  • Use Git merge driver union for CHANGELOG.md, but it can silently produce duplicated or malformed entries.
  • Append entries to the bottom of each category, but PRs would still edit the same file and nearby sections.

Additional context

This keeps the current benefit of AI-written, reviewed changelog text while removing the main source of unrelated PR merge conflicts.

The current release command already has a changelog finalization step, so this feature should update that flow to consume fragments before creating the release version section.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions