Skip to content

Commit 4ed2653

Browse files
fix(bump): preserve existing changelog header when changelog_merge_prerelease is used with cz bump --changelog (#1850)
* test: Add a failing test Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com> * fix(bump): Preserve existing changelog header when `changelog_merge_prerelease` is used with `cz bump --changelog` Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com> * fix(bump): Preserve existing changelog header when `changelog_merge_prerelease` is used with `cz bump --changelog`, and no prereleases exist Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com> * test: Remove redundant assertions Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com> * refactor: Inline condition and rely on comments to explain the logic Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com> * test: Remove another redundant assertion * test: Use a single parametrized test Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com> --------- Signed-off-by: Edgar Ramírez Mondragón <edgarrm358@gmail.com>
1 parent 2cfb8c6 commit 4ed2653

File tree

5 files changed

+129
-14
lines changed

5 files changed

+129
-14
lines changed

commitizen/commands/changelog.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,16 +227,32 @@ def __call__(self) -> None:
227227
latest_full_release_info = self.changelog_format.get_latest_full_release(
228228
self.file_name
229229
)
230-
if latest_full_release_info.index:
231-
changelog_meta.unreleased_start = 0
230+
# Determine if there are prereleases to merge:
231+
# - Only prereleases in changelog (no full release found), OR
232+
# - First version in changelog is before first full release (prereleases exist)
233+
if latest_full_release_info.index is not None and (
234+
latest_full_release_info.name is None
235+
or (
236+
changelog_meta.latest_version_position is not None
237+
and changelog_meta.latest_version_position
238+
< latest_full_release_info.index
239+
)
240+
):
241+
# Use the existing unreleased_start if available (from get_metadata()).
242+
# Otherwise, use the position of the first version entry (prerelease)
243+
# to preserve the changelog header.
244+
if changelog_meta.unreleased_start is None:
245+
changelog_meta.unreleased_start = (
246+
changelog_meta.latest_version_position
247+
)
232248
changelog_meta.latest_version_position = latest_full_release_info.index
233249
changelog_meta.unreleased_end = latest_full_release_info.index - 1
234250

235-
start_rev = latest_full_release_info.name or ""
236-
if not start_rev and latest_full_release_info.index:
237-
# Only pre-releases in changelog
238-
changelog_meta.latest_version_position = None
239-
changelog_meta.unreleased_end = latest_full_release_info.index + 1
251+
start_rev = latest_full_release_info.name or ""
252+
if not start_rev:
253+
# Only pre-releases in changelog
254+
changelog_meta.latest_version_position = None
255+
changelog_meta.unreleased_end = latest_full_release_info.index + 1
240256

241257
commits = git.get_commits(start=start_rev, end=end_rev, args="--topo-order")
242258
if not commits and (

tests/commands/test_bump_command.py

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,11 +1494,57 @@ def test_changelog_config_flag_merge_prerelease_only_prerelease_present(
14941494
file_regression.check(out, extension=".md")
14951495

14961496

1497+
@pytest.mark.parametrize(
1498+
("prerelease", "merge"),
1499+
[
1500+
pytest.param(True, "true", id="with_prerelease_merge"),
1501+
pytest.param(True, "false", id="with_prerelease_no_merge"),
1502+
pytest.param(False, "true", id="without_prerelease"),
1503+
],
1504+
)
14971505
@pytest.mark.usefixtures("tmp_commitizen_project")
1498-
def test_bump_deprecate_files_only(util: UtilFixture):
1499-
util.create_file_and_commit("feat: new file")
1500-
with (
1501-
pytest.warns(DeprecationWarning, match=r".*--files-only.*deprecated"),
1502-
pytest.raises(ExpectedExit),
1503-
):
1504-
util.run_cli("bump", "--yes", "--files-only")
1506+
@pytest.mark.freeze_time("2025-01-01")
1507+
def test_changelog_merge_preserves_header(
1508+
mocker: MockFixture,
1509+
util: UtilFixture,
1510+
changelog_path: Path,
1511+
config_path: Path,
1512+
file_regression: FileRegressionFixture,
1513+
prerelease: bool,
1514+
merge: str,
1515+
):
1516+
"""Test that merge_prerelease preserves existing changelog header."""
1517+
with config_path.open("a") as f:
1518+
f.write(f"changelog_merge_prerelease = {merge}\n")
1519+
f.write("update_changelog_on_bump = true\n")
1520+
f.write("annotated_tag = true\n")
1521+
1522+
# Create initial version with changelog that has a header
1523+
util.create_file_and_commit("irrelevant commit")
1524+
mocker.patch("commitizen.git.GitTag.date", "1970-01-01")
1525+
git.tag("0.1.0")
1526+
1527+
# Create a changelog with a header manually
1528+
changelog_path.write_text(
1529+
dedent("""\
1530+
# Changelog
1531+
1532+
All notable changes to this project will be documented here.
1533+
1534+
## 0.1.0 (1970-01-01)
1535+
""")
1536+
)
1537+
1538+
util.create_file_and_commit("feat: add new output")
1539+
util.create_file_and_commit("fix: output glitch")
1540+
1541+
if prerelease:
1542+
util.run_cli("bump", "--prerelease", "alpha", "--yes")
1543+
1544+
util.create_file_and_commit("feat: new feature right before the bump")
1545+
util.run_cli("bump", "--changelog")
1546+
1547+
with changelog_path.open() as f:
1548+
out = f.read()
1549+
1550+
file_regression.check(out, extension=".md")
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented here.
4+
5+
## 0.2.0 (2025-01-01)
6+
7+
### Feat
8+
9+
- new feature right before the bump
10+
- add new output
11+
12+
### Fix
13+
14+
- output glitch
15+
16+
## 0.1.0 (1970-01-01)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented here.
4+
5+
## 0.2.0 (2025-01-01)
6+
7+
### Feat
8+
9+
- new feature right before the bump
10+
11+
## 0.2.0a0 (2025-01-01)
12+
13+
### Feat
14+
15+
- add new output
16+
17+
### Fix
18+
19+
- output glitch
20+
21+
## 0.1.0 (1970-01-01)
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Changelog
2+
3+
All notable changes to this project will be documented here.
4+
5+
## 0.2.0 (2025-01-01)
6+
7+
### Feat
8+
9+
- new feature right before the bump
10+
- add new output
11+
12+
### Fix
13+
14+
- output glitch
15+
16+
## 0.1.0 (1970-01-01)

0 commit comments

Comments
 (0)