From 83e11abdefeacb75c58074e04616be22133b0031 Mon Sep 17 00:00:00 2001 From: Yu-Ting Hsiung Date: Fri, 13 Feb 2026 00:56:14 +0800 Subject: [PATCH] fix: bump command called changelog command with allow_no_commit=True, but changelog command raised NoCommitsFoundError --- commitizen/commands/bump.py | 4 ++- commitizen/commands/changelog.py | 8 ++++-- tests/commands/test_bump_command.py | 43 +++++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/commitizen/commands/bump.py b/commitizen/commands/bump.py index 6084c8c15..a67571ce0 100644 --- a/commitizen/commands/bump.py +++ b/commitizen/commands/bump.py @@ -332,7 +332,9 @@ def __call__(self) -> None: self.config, {**changelog_args, "file_name": self.file_name}, # type: ignore[typeddict-item] ) - changelog_cmd() + changelog_cmd( + allow_no_commit=bool(self.arguments["allow_no_commit"]) + ) # This is a workaround changelog_file_name = changelog_cmd.file_name updated_files.append(changelog_file_name) diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 5093ed9f2..9e68c3ae5 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -186,7 +186,7 @@ def _export_template(self, dist: str) -> None: text = Path(filename).read_text() Path(dist).write_text(text) - def __call__(self) -> None: + def __call__(self, *, allow_no_commit: bool = False) -> None: commit_parser = self.cz.commit_parser changelog_pattern = self.cz.changelog_pattern start_rev = self.start_rev @@ -255,8 +255,10 @@ def __call__(self) -> None: changelog_meta.unreleased_end = latest_full_release_info.index + 1 commits = git.get_commits(start=start_rev, end=end_rev, args="--topo-order") - if not commits and ( - self.current_version is None or not self.current_version.is_prerelease + if ( + not allow_no_commit + and not commits + and (self.current_version is None or not self.current_version.is_prerelease) ): raise NoCommitsFoundError("No commits found") diff --git a/tests/commands/test_bump_command.py b/tests/commands/test_bump_command.py index 94b40e94e..38a03ef7a 100644 --- a/tests/commands/test_bump_command.py +++ b/tests/commands/test_bump_command.py @@ -1540,3 +1540,46 @@ def test_changelog_merge_preserves_header( out = changelog_path.read_text() file_regression.check(out, extension=".md") + + +@pytest.mark.freeze_time("2025-01-01") +def test_bump_allow_no_commit_issue( + tmp_commitizen_project_initial, + util: UtilFixture, +) -> None: + """Issue #1866: bump command called changelog command with allow_no_commit=True, but changelog command raised NoCommitsFoundError""" + tmp_commitizen_project = tmp_commitizen_project_initial(version="1.0.0") + with (tmp_commitizen_project / "pyproject.toml").open("w") as f: + f.write( + dedent( + r""" + [project] + name = "abc" + version = "4.14.0" + + [tool.commitizen] + name = "cz_customize" + tag_format = "$version" + version_scheme = "semver2" + version_provider = "pep621" + update_changelog_on_bump = true + + [tool.commitizen.customize] + bump_pattern = '^(feat|fix|ci|build|perf|refactor|chore|remove|style|test)' + bump_map = {feat = "MINOR", fix = "PATCH", ci = "PATCH", build = "PATCH", perf = "PATCH", refactor = "PATCH", chore = "PATCH", remove = "PATCH", style = "PATCH", test = "PATCH" } + schema_pattern = "(build|bump|chore|ci|dev|docs|feat|fix|perf|refactor|remove|style|test):(\\s.*)" + commit_parser = "^(?Pbuild|bump|chore|ci|dev|docs|feat|fix|perf|refactor|remove|style|test):\\s(?P.*)?" + # By excluding 'bump', 'ci', 'dev', and 'docs' from + # 'change_type_map', 'change_type_order' and 'changelog_pattern' + # we omit the corresponding commit comments from the CHANGELOG. + # The order of types in the CHANGELOG is dictated by the type_order + change_type_map = {"feat" = "New Features", "fix" = "Bug Fixes", "perf" = "Performance Improvements", "refactor" = "Refactoring", "chore" = "General Improvements", "remove" = "Removed", "style" = "Stylistic Changes", "test" = "Testing", "build" = "Build"} + change_type_order = ["BREAKING CHANGE", "New Features", "Bug Fixes", "Performance Improvements", "Refactoring", "General Improvements", "Removed", "Stylistic Changes", "Testing", "Build"] + changelog_pattern = "^(build|chore|feat|fix|perf|refactor|remove|style|test)" +""" + ) + ) + util.run_cli("bump", "--yes", "--allow-no-commit", "--prerelease", "beta") + util.run_cli( + "bump", "--allow-no-commit", "--prerelease", "rc" + ) # Failed because the bump command called changelog command