diff --git a/.github/workflows/bumpversion.yml b/.github/workflows/bumpversion.yml index aab3b0ab4a..0fc1bb129b 100644 --- a/.github/workflows/bumpversion.yml +++ b/.github/workflows/bumpversion.yml @@ -58,7 +58,7 @@ jobs: env: NEW_VERSION: ${{ steps.bump-version.outputs.new_version }} run: | - cz changelog --dry-run "${NEW_VERSION}" > .changelog.md + cz changelog --no-incremental --dry-run "${NEW_VERSION}" > .changelog.md - name: Release if: steps.bump-version.outputs.bumped == 'true' env: diff --git a/commitizen/cli.py b/commitizen/cli.py index 3ee03d99ce..8c261d5e95 100644 --- a/commitizen/cli.py +++ b/commitizen/cli.py @@ -413,11 +413,13 @@ def __call__( }, { "name": "--incremental", - "action": "store_true", - "default": False, + "action": argparse.BooleanOptionalAction, + "default": None, "help": ( "Generate changelog from the last created version, " - "useful if the changelog has been manually modified." + "useful if the changelog has been manually modified. " + "Use `--no-incremental` to override a `changelog_incremental` " + "setting enabled in the configuration." ), }, { diff --git a/commitizen/commands/changelog.py b/commitizen/commands/changelog.py index 7dbc28ac54..a697923652 100644 --- a/commitizen/commands/changelog.py +++ b/commitizen/commands/changelog.py @@ -32,7 +32,7 @@ class ChangelogArgs(TypedDict, total=False): current_version: str dry_run: bool file_name: str | None - incremental: bool + incremental: bool | None merge_prerelease: bool rev_range: str start_rev: str @@ -78,9 +78,16 @@ def __init__(self, config: BaseConfig, arguments: ChangelogArgs) -> None: self.changelog_format = get_changelog_format(self.config, self.file_name) - self.incremental = bool( - arguments.get("incremental") - or self.config.settings.get("changelog_incremental") + # `--incremental`/`--no-incremental` on the CLI always takes precedence over + # the `changelog_incremental` setting. When neither flag is passed, the + # argument is `None` and we fall back to the config value. This lets a + # one-off invocation (e.g. `cz changelog --no-incremental `) opt + # out of an incremental default enabled in the configuration. + incremental_arg = arguments.get("incremental") + self.incremental = ( + incremental_arg + if incremental_arg is not None + else bool(self.config.settings.get("changelog_incremental")) ) self.dry_run = bool(arguments.get("dry_run")) diff --git a/docs/commands/changelog.md b/docs/commands/changelog.md index 8b7a7a4d48..8db83826c1 100644 --- a/docs/commands/changelog.md +++ b/docs/commands/changelog.md @@ -115,6 +115,16 @@ This flag can be set in the configuration file with the key `changelog_increment changelog_incremental = true ``` +Pass `--no-incremental` on the command line to disable incremental generation +for a single run, even when `changelog_incremental = true` is set in the +configuration. This is useful, for example, when generating a one-off +changelog for a specific `rev_range`, since `--incremental` cannot be combined +with a `rev_range`. + +```bash +cz changelog --no-incremental "v1.0.0..v1.1.0" +``` + ### `--start-rev` Start from a given git rev to generate the changelog. Commits before that rev will not be considered. This is especially useful for long-running projects adopting conventional commits, where old commit messages might fail to be parsed for changelog generation. diff --git a/docs/images/cli_help/cz_changelog___help.svg b/docs/images/cli_help/cz_changelog___help.svg index 00031d48f6..375878d37e 100644 --- a/docs/images/cli_help/cz_changelog___help.svg +++ b/docs/images/cli_help/cz_changelog___help.svg @@ -1,4 +1,4 @@ - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + - + - + - - $ cz changelog --help -usage: cz changelog [-h][--dry-run][--file-name FILE_NAME] -[--unreleased-version UNRELEASED_VERSION][--incremental] -[--start-rev START_REV][--merge-prerelease] -[--version-scheme {pep440,semver,semver2}] -[--export-template EXPORT_TEMPLATE][--template TEMPLATE] -[--extra EXTRA][--tag-format TAG_FORMAT] - - -Generate changelog (note that it will overwrite existing files) - -positional arguments: -  rev_range             Generate changelog for the given version (e.g., 1.5.3) -                        or version range (e.g., 1.5.3..1.7.9). - -options: -  -h, --help            show this help message and exit -  --dry-run             Show changelog to stdout. -  --file-name FILE_NAME -                        File name of changelog (default: 'CHANGELOG.md'). -  --unreleased-version UNRELEASED_VERSION -                        Set the value for the new version (use the tag value), -                        instead of using unreleased versions. -  --incremental         Generate changelog from the last created version, -                        useful if the changelog has been manually modified. -  --start-rev START_REV -                        Start rev of the changelog. If not set, it will -                        generate changelog from the beginning. -  --merge-prerelease    Collect all changes from prereleases into the next -                        non-prerelease. If not set, it will include -                        prereleases in the changelog. -  --version-scheme {pep440,semver,semver2} -                        Choose version scheme. -  --export-template EXPORT_TEMPLATE -                        Export the changelog template into this file instead -                        of rendering it. -  --template TEMPLATE, -t TEMPLATE -                        Changelog template file name (relative to the current -                        working directory). -  --extra EXTRA, -e EXTRA -                        Changelog extra variables (in the form 'key=value'). -  --tag-format TAG_FORMAT -                        The format of the tag, wrap around simple quotes. - + + $ cz changelog --help +usage: cz changelog [-h][--dry-run][--file-name FILE_NAME] +[--unreleased-version UNRELEASED_VERSION] +[--incremental | --no-incremental][--start-rev START_REV] +[--merge-prerelease] +[--version-scheme {pep440,semver,semver2}] +[--export-template EXPORT_TEMPLATE][--template TEMPLATE] +[--extra EXTRA][--tag-format TAG_FORMAT] + + +Generate changelog (note that it will overwrite existing files) + +positional arguments: +  rev_range             Generate changelog for the given version (e.g., 1.5.3) +                        or version range (e.g., 1.5.3..1.7.9). + +options: +  -h, --help            show this help message and exit +  --dry-run             Show changelog to stdout. +  --file-name FILE_NAME +                        File name of changelog (default: 'CHANGELOG.md'). +  --unreleased-version UNRELEASED_VERSION +                        Set the value for the new version (use the tag value), +                        instead of using unreleased versions. +  --incremental, --no-incremental +                        Generate changelog from the last created version, +                        useful if the changelog has been manually modified. +                        Use `--no-incremental` to override a +                        `changelog_incremental` setting enabled in the +                        configuration. +  --start-rev START_REV +                        Start rev of the changelog. If not set, it will +                        generate changelog from the beginning. +  --merge-prerelease    Collect all changes from prereleases into the next +                        non-prerelease. If not set, it will include +                        prereleases in the changelog. +  --version-scheme {pep440,semver,semver2} +                        Choose version scheme. +  --export-template EXPORT_TEMPLATE +                        Export the changelog template into this file instead +                        of rendering it. +  --template, -t TEMPLATE +                        Changelog template file name (relative to the current +                        working directory). +  --extra, -e EXTRA     Changelog extra variables (in the form 'key=value'). +  --tag-format TAG_FORMAT +                        The format of the tag, wrap around simple quotes. + diff --git a/tests/commands/test_changelog_command.py b/tests/commands/test_changelog_command.py index 469f9e88e1..3af00d01c0 100644 --- a/tests/commands/test_changelog_command.py +++ b/tests/commands/test_changelog_command.py @@ -464,6 +464,32 @@ def test_changelog_incremental_with_revision(util: UtilFixture): util.run_cli("changelog", "--incremental", "0.2.0") +@pytest.mark.usefixtures("tmp_commitizen_project") +def test_changelog_no_incremental_overrides_config_with_revision( + config_path: Path, util: UtilFixture +): + """--no-incremental must override a config-enabled `changelog_incremental`. + + Regression test for a one-off `cz changelog ` invocation + (e.g. used to build release notes for a specific version) that previously + always raised `NotAllowed` once `changelog_incremental = true` was set, + with no CLI-side way to opt out. + """ + with config_path.open("a", encoding="utf-8") as f: + f.write("changelog_incremental = true\n") + + util.create_file_and_commit("feat: new file") + util.create_tag("0.2.0") + + # Config-enabled incremental mode still conflicts with a rev_range... + with pytest.raises(NotAllowed): + util.run_cli("changelog", "0.2.0") + + # ...unless explicitly overridden with --no-incremental. + with pytest.raises(DryRunExit): + util.run_cli("changelog", "--no-incremental", "--dry-run", "0.2.0") + + @pytest.mark.usefixtures("chdir") def test_changelog_in_non_git_project(util: UtilFixture): with pytest.raises(NotAGitProjectError): diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_changelog_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_changelog_.txt index 2d1135af74..7bea3466bb 100644 --- a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_changelog_.txt +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_10_changelog_.txt @@ -1,6 +1,7 @@ usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] - [--unreleased-version UNRELEASED_VERSION] [--incremental] - [--start-rev START_REV] [--merge-prerelease] + [--unreleased-version UNRELEASED_VERSION] + [--incremental | --no-incremental] [--start-rev START_REV] + [--merge-prerelease] [--version-scheme {pep440,semver,semver2}] [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] [--extra EXTRA] [--tag-format TAG_FORMAT] @@ -20,8 +21,12 @@ options: --unreleased-version UNRELEASED_VERSION Set the value for the new version (use the tag value), instead of using unreleased versions. - --incremental Generate changelog from the last created version, + --incremental, --no-incremental + Generate changelog from the last created version, useful if the changelog has been manually modified. + Use `--no-incremental` to override a + `changelog_incremental` setting enabled in the + configuration. --start-rev START_REV Start rev of the changelog. If not set, it will generate changelog from the beginning. diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_changelog_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_changelog_.txt index 2d1135af74..7bea3466bb 100644 --- a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_changelog_.txt +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_11_changelog_.txt @@ -1,6 +1,7 @@ usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] - [--unreleased-version UNRELEASED_VERSION] [--incremental] - [--start-rev START_REV] [--merge-prerelease] + [--unreleased-version UNRELEASED_VERSION] + [--incremental | --no-incremental] [--start-rev START_REV] + [--merge-prerelease] [--version-scheme {pep440,semver,semver2}] [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] [--extra EXTRA] [--tag-format TAG_FORMAT] @@ -20,8 +21,12 @@ options: --unreleased-version UNRELEASED_VERSION Set the value for the new version (use the tag value), instead of using unreleased versions. - --incremental Generate changelog from the last created version, + --incremental, --no-incremental + Generate changelog from the last created version, useful if the changelog has been manually modified. + Use `--no-incremental` to override a + `changelog_incremental` setting enabled in the + configuration. --start-rev START_REV Start rev of the changelog. If not set, it will generate changelog from the beginning. diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_changelog_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_changelog_.txt index 2d1135af74..7bea3466bb 100644 --- a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_changelog_.txt +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_12_changelog_.txt @@ -1,6 +1,7 @@ usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] - [--unreleased-version UNRELEASED_VERSION] [--incremental] - [--start-rev START_REV] [--merge-prerelease] + [--unreleased-version UNRELEASED_VERSION] + [--incremental | --no-incremental] [--start-rev START_REV] + [--merge-prerelease] [--version-scheme {pep440,semver,semver2}] [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] [--extra EXTRA] [--tag-format TAG_FORMAT] @@ -20,8 +21,12 @@ options: --unreleased-version UNRELEASED_VERSION Set the value for the new version (use the tag value), instead of using unreleased versions. - --incremental Generate changelog from the last created version, + --incremental, --no-incremental + Generate changelog from the last created version, useful if the changelog has been manually modified. + Use `--no-incremental` to override a + `changelog_incremental` setting enabled in the + configuration. --start-rev START_REV Start rev of the changelog. If not set, it will generate changelog from the beginning. diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_changelog_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_changelog_.txt index 50ab468d64..85d31048aa 100644 --- a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_changelog_.txt +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_13_changelog_.txt @@ -1,6 +1,7 @@ usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] - [--unreleased-version UNRELEASED_VERSION] [--incremental] - [--start-rev START_REV] [--merge-prerelease] + [--unreleased-version UNRELEASED_VERSION] + [--incremental | --no-incremental] [--start-rev START_REV] + [--merge-prerelease] [--version-scheme {pep440,semver,semver2}] [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] [--extra EXTRA] [--tag-format TAG_FORMAT] @@ -20,8 +21,12 @@ options: --unreleased-version UNRELEASED_VERSION Set the value for the new version (use the tag value), instead of using unreleased versions. - --incremental Generate changelog from the last created version, + --incremental, --no-incremental + Generate changelog from the last created version, useful if the changelog has been manually modified. + Use `--no-incremental` to override a + `changelog_incremental` setting enabled in the + configuration. --start-rev START_REV Start rev of the changelog. If not set, it will generate changelog from the beginning. diff --git a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_changelog_.txt b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_changelog_.txt index 50ab468d64..85d31048aa 100644 --- a/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_changelog_.txt +++ b/tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_14_changelog_.txt @@ -1,6 +1,7 @@ usage: cz changelog [-h] [--dry-run] [--file-name FILE_NAME] - [--unreleased-version UNRELEASED_VERSION] [--incremental] - [--start-rev START_REV] [--merge-prerelease] + [--unreleased-version UNRELEASED_VERSION] + [--incremental | --no-incremental] [--start-rev START_REV] + [--merge-prerelease] [--version-scheme {pep440,semver,semver2}] [--export-template EXPORT_TEMPLATE] [--template TEMPLATE] [--extra EXTRA] [--tag-format TAG_FORMAT] @@ -20,8 +21,12 @@ options: --unreleased-version UNRELEASED_VERSION Set the value for the new version (use the tag value), instead of using unreleased versions. - --incremental Generate changelog from the last created version, + --incremental, --no-incremental + Generate changelog from the last created version, useful if the changelog has been manually modified. + Use `--no-incremental` to override a + `changelog_incremental` setting enabled in the + configuration. --start-rev START_REV Start rev of the changelog. If not set, it will generate changelog from the beginning.