diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 6084c8c15..101063c01 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -310,11 +310,17 @@ def __call__(self) -> None: changelog_file_name = None dry_run = self.arguments["dry_run"] if self.changelog_flag: + # DEFAULT_SETTINGS provides changelog_incremental=None, so .get("changelog_incremental", True) + # would never fall through to the True default. None means "not configured" vs False meaning + # "explicitly disabled". During bump, we default to True (incremental) when not configured. + incremental_setting = self.config.settings.get("changelog_incremental") changelog_args = { "unreleased_version": new_tag_version, "template": self.template, "extras": self.extras, - "incremental": True, + "incremental": incremental_setting + if incremental_setting is not None + else True, "dry_run": dry_run, # governs logic for merge_prerelease "during_version_bump": self.arguments["prerelease"] is None, diff --git a/commitizen/defaults.py b/commitizen/defaults.py index 4865ccc18..7fe329006 100644 --- a/commitizen/defaults.py +++ b/commitizen/defaults.py @@ -38,7 +38,7 @@ class Settings(TypedDict, total=False): change_type_map: dict[str, str] changelog_file: str changelog_format: str | None - changelog_incremental: bool + changelog_incremental: bool | None changelog_merge_prerelease: bool changelog_start_rev: str | None customize: CzSettings @@ -100,7 +100,11 @@ class Settings(TypedDict, total=False): ], "changelog_file": "CHANGELOG.md", "changelog_format": None, # default guessed from changelog_file - "changelog_incremental": False, + # None serves as a sentinel for "not configured by user" (distinct from False = explicitly disabled). + # During `cz bump`, when unset (None), defaults to True (incremental changelog). + # TODO: consider introducing sentinel value for "not configured by user" instead of overloading None, + # to avoid confusion with False. + "changelog_incremental": None, "changelog_start_rev": None, "changelog_merge_prerelease": False, "update_changelog_on_bump": False, diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 6b8d903d6..3d3be7d98 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1502,3 +1502,89 @@ def test_bump_deprecate_files_only(util: UtilFixture): pytest.raises(ExpectedExit), ): util.run_cli("bump", "--yes", "--files-only") + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_changelog_incremental_default_not_set( + util: UtilFixture, changelog_path: Path, config_path: Path +): + with config_path.open("a", encoding="utf-8") as fp: + fp.write("update_changelog_on_bump = true\n") + + util.create_file_and_commit("feat(user): new user") + util.run_cli("bump", "--yes") + assert git.tag_exist("0.2.0") is True + + with changelog_path.open(encoding="utf-8") as f: + content = f.read() + with changelog_path.open("w", encoding="utf-8") as f: + f.write(content.replace("- **user**: new user", "- **user**: new user\n\nMANUAL NOTE")) + util.create_file_and_commit("docs: add manual note to changelog") + + util.create_file_and_commit("feat(admin): new admin") + util.run_cli("bump", "--yes") + assert git.tag_exist("0.3.0") is True + + with changelog_path.open(encoding="utf-8") as f: + out = f.read() + assert "0.3.0" in out + assert "0.2.0" in out + assert "MANUAL NOTE" in out + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_changelog_incremental_set_true( + util: UtilFixture, changelog_path: Path, config_path: Path +): + with config_path.open("a", encoding="utf-8") as fp: + fp.write("update_changelog_on_bump = true\n") + fp.write("changelog_incremental = true\n") + + util.create_file_and_commit("feat(user): new user") + util.run_cli("bump", "--yes") + assert git.tag_exist("0.2.0") is True + + with changelog_path.open(encoding="utf-8") as f: + content = f.read() + with changelog_path.open("w", encoding="utf-8") as f: + f.write(content.replace("- **user**: new user", "- **user**: new user\n\nMANUAL NOTE")) + util.create_file_and_commit("docs: add manual note to changelog") + + util.create_file_and_commit("feat(admin): new admin") + util.run_cli("bump", "--yes") + assert git.tag_exist("0.3.0") is True + + with changelog_path.open(encoding="utf-8") as f: + out = f.read() + assert "0.3.0" in out + assert "0.2.0" in out + assert "MANUAL NOTE" in out + + +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_bump_changelog_incremental_set_false( + util: UtilFixture, changelog_path: Path, config_path: Path +): + with config_path.open("a", encoding="utf-8") as fp: + fp.write("update_changelog_on_bump = true\n") + fp.write("changelog_incremental = false\n") + + util.create_file_and_commit("feat(user): new user") + util.run_cli("bump", "--yes") + assert git.tag_exist("0.2.0") is True + + with changelog_path.open(encoding="utf-8") as f: + content = f.read() + with changelog_path.open("w", encoding="utf-8") as f: + f.write(content.replace("- **user**: new user", "- **user**: new user\n\nMANUAL NOTE")) + util.create_file_and_commit("docs: add manual note to changelog") + + util.create_file_and_commit("feat(admin): new admin") + util.run_cli("bump", "--yes") + assert git.tag_exist("0.3.0") is True + + with changelog_path.open(encoding="utf-8") as f: + out = f.read() + assert "0.3.0" in out + assert "0.2.0" in out + assert "MANUAL NOTE" not in out diff --git a/tests/test_conf.py b/tests/test_conf.py index 923535e0c..fc7f5d4c6 100644 --- a/tests/test_conf.py +++ b/tests/test_conf.py @@ -97,7 +97,7 @@ "style": [["pointer", "reverse"], ["question", "underline"]], "changelog_file": "CHANGELOG.md", "changelog_format": None, - "changelog_incremental": False, + "changelog_incremental": None, "changelog_start_rev": None, "changelog_merge_prerelease": False, "update_changelog_on_bump": False, @@ -137,7 +137,7 @@ "style": [["pointer", "reverse"], ["question", "underline"]], "changelog_file": "CHANGELOG.md", "changelog_format": None, - "changelog_incremental": False, + "changelog_incremental": None, "changelog_start_rev": None, "changelog_merge_prerelease": False, "update_changelog_on_bump": False,