Skip to content

feat(bump): add --merge-prerelease flag#1968

Open
bearomorphism wants to merge 1 commit intocommitizen-tools:masterfrom
bearomorphism:feat/1934-bump-merge-prerelease-flag
Open

feat(bump): add --merge-prerelease flag#1968
bearomorphism wants to merge 1 commit intocommitizen-tools:masterfrom
bearomorphism:feat/1934-bump-merge-prerelease-flag

Conversation

@bearomorphism
Copy link
Copy Markdown
Collaborator

@bearomorphism bearomorphism commented May 9, 2026

Description

Closes #1934.

Why

cz changelog already exposes a --merge-prerelease flag that overrides the changelog_merge_prerelease config setting for a single invocation. The same flag is missing on cz bump, even though cz bump --changelog runs the same changelog generator under the hood. Users who want prerelease entries to live as separate sections in their changelog by default, but be merged into the release entry on the actual release bump, currently have to either edit pyproject.toml for one bump and revert it, or run cz bump followed by a separate cz changelog --merge-prerelease.

The original issue calls for parity:

It would be great to enable/disable changelog_merge_prerelease when calling cz bump in combination with update_changelog_on_bump = true/--changelog.

What changed

File Change
commitizen/cli.py New --merge-prerelease argument under the bump subcommand (mirrors the one under changelog).
commitizen/commands/bump.py BumpArgs gains merge_prerelease: bool | None; Bump.__call__ forwards it into changelog_args only when explicitly set.
docs/commands/bump.md New ### --merge-prerelease section.
tests/commands/test_bump_command.py New parameterised test_changelog_cli_flag_merge_prerelease[rc|alpha|beta] that exercises the flag without setting the config.
tests/commands/test_bump_command/test_changelog_cli_flag_merge_prerelease_*.md Three regression fixtures (one per prerelease variant).
tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_*_bump_.txt Regenerated cz bump --help snapshots (one per supported Python).

How it works

  1. The argparse argument uses action="store_true", default=None. The None default is intentional: it lets Bump.__call__ distinguish "user did not pass the flag" from "user passed --no-merge-prerelease-equivalent" without a separate negation flag. When the flag is absent the embedded Changelog invocation falls back to self.config.settings["changelog_merge_prerelease"] exactly as before — no behaviour change.
  2. In Bump.__call__, merge_prerelease is injected into changelog_args only when is not None. Because Changelog.__init__ evaluates arguments.get("merge_prerelease") or self.config.settings["changelog_merge_prerelease"], omitting the key from changelog_args correctly preserves the legacy behaviour.
  3. Both code paths in Bump.__call__ that construct a Changelog (the changelog_to_stdout path and the regular file path) receive the changelog_args dict, so the new flag is effective in both modes.
  4. The flag has no effect unless cz bump actually generates a changelog (--changelog, --changelog-to-stdout, or update_changelog_on_bump = true); a no-op flag without --changelog matches cz changelog's behaviour and avoids surprises.

Backward compatibility

  • All existing config combinations behave identically when the flag is absent.
  • BumpArgs.merge_prerelease: bool | None is additive on a total=False TypedDict.
  • The full pre-existing bump test suite (134 non-GPG tests) and cz bump --help snapshot tests pass unchanged after regeneration.

Checklist

Was generative AI tooling used to co-author this PR?

  • Yes (please specify the tool below)

Generated-by: Claude following the guidelines

Code Changes

  • Add test cases to all the changes you introduce
  • Run uv run poe all locally to ensure this change passes linter check and tests (poe lint clean; 134 non-GPG bump tests + 14 common-command help-text tests pass; the 4 GPG-signing test errors on Windows are pre-existing and unrelated to this change)
  • Manually test the changes (see "Steps to Test" below for the exact commands)
  • Update the documentation for the changes

Documentation Changes

  • Added a ### --merge-prerelease section to docs/commands/bump.md
  • Help-text snapshots regenerated via uv run poe test:regen
  • Run uv run poe doc locally to ensure the documentation pages render correctly
  • Check and fix any broken links (internal or external)

Expected Behavior

Scenario Outcome
cz bump --changelog (no flag, changelog_merge_prerelease = false — default) Prereleases keep their own sections in the changelog (legacy behaviour).
cz bump --changelog --merge-prerelease Prereleases between previous and new non-prerelease are collapsed into the new entry.
cz bump --changelog with changelog_merge_prerelease = true in config Prereleases are merged (legacy behaviour).
cz bump --merge-prerelease (no --changelog, no update_changelog_on_bump) Flag is a no-op; no changelog is generated.
cz bump --changelog-to-stdout --merge-prerelease Stdout changelog also has prereleases merged.

Steps to Test This Pull Request

git fetch fork feat/1934-bump-merge-prerelease-flag
git checkout fork/feat/1934-bump-merge-prerelease-flag

# 1. Targeted regression test (3 new + 6 pre-existing parametrised cases).
uv run pytest tests/commands/test_bump_command.py -k merge_prerelease -v
# expected: 9 passed

# 2. Full bump-command suite (sanity check that nothing else broke).
uv run pytest tests/commands/test_bump_command.py -k 'not signed' -q
# expected: 134 passed (GPG-signing tests are excluded on Windows)

# 3. Help snapshots updated correctly.
uv run pytest tests/commands/test_common_command.py -q
# expected: 14 passed

# 4. End-to-end smoke (optional, requires a temp git repo):
mkdir -p /tmp/cz-1968 && cd /tmp/cz-1968 && git init -q
echo '[tool.commitizen]\nname = "cz_conventional_commits"\nversion = "0.1.0"\nupdate_changelog_on_bump = true\ntag_format = "v$version"' > pyproject.toml
git add . && git -c user.email=a@b -c user.name=t commit -qm "feat: a"
uv run cz bump --yes -pr alpha   # -> v0.2.0a0
git -c user.email=a@b -c user.name=t commit --allow-empty -qm "fix: b"
uv run cz bump --yes --changelog --merge-prerelease   # collapses 0.2.0a0 entry
cat CHANGELOG.md     # 0.2.0 should contain both feat:a and fix:b under it

Additional Context

Surfaced while triaging open issues in #1965. Reviewed by an internal claude-sonnet-4.6 code-review pass and by GitHub Copilot; both reported no findings.

Closes commitizen-tools#1934.

Adds a `--merge-prerelease` CLI flag to `cz bump` that mirrors the
existing flag of `cz changelog`. When passed, it overrides the
`changelog_merge_prerelease` setting for a single bump invocation,
which is useful when you want to keep prerelease entries in the
changelog by default but collapse them on a release bump.

The implementation adds the flag to `commitizen/cli.py`, threads it
through the `BumpArgs` TypedDict, and forwards it to the embedded
`Changelog` invocation in `commands/bump.py`. The pre-existing
`Changelog` argument plumbing (`merge_prerelease` -> `tag_rules.
merge_prereleases`) is unchanged.

Also adds a parameterised test that proves the CLI flag enables
merging even when the config setting is left at its default
(`false`), reusing the existing fixture content.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented May 9, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.23%. Comparing base (4b93a50) to head (e87930c).
⚠️ Report is 3 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master    #1968   +/-   ##
=======================================
  Coverage   98.23%   98.23%           
=======================================
  Files          61       61           
  Lines        2779     2783    +4     
=======================================
+ Hits         2730     2734    +4     
  Misses         49       49           

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

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a --merge-prerelease CLI flag to cz bump to mirror cz changelog --merge-prerelease, enabling users to collapse prerelease changelog entries into the next non-prerelease entry for a single bump invocation while preserving config-driven behavior when the flag is absent.

Changes:

  • Introduce merge_prerelease: bool | None to bump arguments and forward it to the embedded Changelog call only when explicitly set.
  • Add regression tests and fixtures validating merged prerelease behavior across rc|alpha|beta.
  • Update bump command documentation and help-text snapshots to include the new flag.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
commitizen/cli.py Adds cz bump --merge-prerelease argument with tri-state default (None) and help text.
commitizen/commands/bump.py Plumbs merge_prerelease through to Changelog invocation when provided.
docs/commands/bump.md Documents --merge-prerelease usage and its relationship to changelog_merge_prerelease.
tests/commands/test_bump_command.py Adds a parameterized test ensuring the CLI flag merges prereleases during a release bump.
tests/commands/test_bump_command/test_changelog_cli_flag_merge_prerelease_{rc,alpha,beta}_.md Adds expected changelog outputs for the new test.
tests/commands/test_common_command/test_command_shows_description_when_use_help_option_py_3_{10,11,12,13,14}bump.txt Updates help snapshots to include the new option and description.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enable "--merge-prerelease" behavior in "cz bump" command

2 participants