Skip to content

Fix changelog entry insertion when no package title is present in the CHANGELOG.md file#1859

Merged
Andarist merged 8 commits into
changesets:mainfrom
mixelburg:fix/changelog-insertion-order-when-no-title
Mar 2, 2026
Merged

Fix changelog entry insertion when no package title is present in the CHANGELOG.md file#1859
Andarist merged 8 commits into
changesets:mainfrom
mixelburg:fix/changelog-insertion-order-when-no-title

Conversation

@mixelburg
Copy link
Copy Markdown
Contributor

Problem

When a CHANGELOG.md file starts directly with a version heading (e.g. ## 1.3.0) rather than a package title heading (e.g. # my-package), newly generated version entries are inserted after the first line (the existing version heading), not before it.

This produces a changelog like:

## 1.3.0

## 1.4.0      <- new entry wrongly follows the old heading

### Minor Changes

- New feature

### Minor Changes  <- old 1.3.0 content now appears under 1.4.0

- Old feature

This is the bug reported in #1056. The Andarist comment in that issue suggests detecting whether the top heading matches a version, which is what this PR does.

Root Cause

In packages/apply-release-plan/src/index.ts, the prependFile function always inserts new content after the first line of the file. This works when the first line is a package title (# my-package), but breaks when the first line is already a version heading.

Fix

The prependFile function now detects whether the first line is a version heading (using /^#{1,6}\s+\d+\.\d+/). When it is, the new changelog entry is prepended before the entire existing content:

const firstLine = fileData.split('\n')[0];
const isVersionHeading = /^#{1,6}\s+\d+\.\d+/.test(firstLine);

if (isVersionHeading) {
  // File starts with a version heading (no package title) - prepend before everything
  newChangelog = data.trimStart() + '\n\n' + fileData;
} else {
  // File starts with a package title - insert after first line (existing behavior)
  const index = fileData.indexOf('\n');
  newChangelog = index === -1 ? fileData + data : fileData.slice(0, index) + data + fileData.slice(index + 1);
}

Test

Added a test that:

  1. Creates a CHANGELOG.md starting with ## 1.0.0 (no package title)
  2. Applies a release plan that bumps from 1.0.0 to 1.1.0
  3. Asserts that ## 1.1.0 appears before ## 1.0.0 in the output

Fixes #1056

…on headings

When a CHANGELOG.md file starts directly with a version heading (e.g. ## 1.3.0)
rather than a package title heading (e.g. # my-package), new version entries were
incorrectly inserted after the existing version heading line instead of before it.
This caused changelogs like:

  ## 1.3.0         <- existing
  ## 1.4.0         <- new entry, wrongly placed under old heading
  ### Minor Changes
  ...
  ### Minor Changes <- old content appears to be under new heading
  ...

The fix detects whether the first line of the changelog is a version heading using
/^#{1,6}\s+\d+\.\d+/ regex. When it is, the new entry is prepended before the
entire file content instead of after the first line.

Fixes changesets#1056
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Feb 26, 2026

🦋 Changeset detected

Latest commit: f98b50f

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@changesets/apply-release-plan Patch
@changesets/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@codecov
Copy link
Copy Markdown

codecov Bot commented Feb 27, 2026

Codecov Report

❌ Patch coverage is 83.33333% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 81.84%. Comparing base (e462d89) to head (f98b50f).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
packages/apply-release-plan/src/index.ts 83.33% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1859      +/-   ##
==========================================
- Coverage   81.86%   81.84%   -0.02%     
==========================================
  Files          55       55              
  Lines        2360     2396      +36     
  Branches      706      724      +18     
==========================================
+ Hits         1932     1961      +29     
- Misses        423      429       +6     
- Partials        5        6       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Andarist Andarist changed the title fix(apply-release-plan): insert changelog entry before existing version headings Fix changelog entry insertion when no package title is present in the CHANGELOG.md file Mar 2, 2026
@Andarist Andarist enabled auto-merge March 2, 2026 11:20
@Andarist Andarist added this pull request to the merge queue Mar 2, 2026
Merged via the queue into changesets:main with commit 1772598 Mar 2, 2026
5 of 6 checks passed
@github-actions github-actions Bot mentioned this pull request Mar 2, 2026
nnecec pushed a commit to nnecec/changesets-docs that referenced this pull request Apr 16, 2026
… `CHANGELOG.md` file (changesets#1859)

* fix(apply-release-plan): insert changelog entry before existing version headings

When a CHANGELOG.md file starts directly with a version heading (e.g. ## 1.3.0)
rather than a package title heading (e.g. # my-package), new version entries were
incorrectly inserted after the existing version heading line instead of before it.
This caused changelogs like:

  ## 1.3.0         <- existing
  ## 1.4.0         <- new entry, wrongly placed under old heading
  ### Minor Changes
  ...
  ### Minor Changes <- old content appears to be under new heading
  ...

The fix detects whether the first line of the changelog is a version heading using
/^#{1,6}\s+\d+\.\d+/ regex. When it is, the new entry is prepended before the
entire file content instead of after the first line.

Fixes changesets#1056

* make room for those tests

* simplify test

* tweak

* tweak

* bring back trimming

* add changeset

* dont use the `void`

---------

Co-authored-by: Maks Pikov <[email protected]>
Co-authored-by: Mateusz Burzyński <[email protected]>
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.

Changelog generation inserts entries for new release under the heading of the last release (so it reads: 1.3.0 -> 1.4.0)

2 participants