fix(bump): use VersionIncrement ordering for bump detection - #2097
Open
bearomorphism wants to merge 5 commits into
Open
bearomorphism wants to merge 5 commits into
bearomorphism wants to merge 5 commits into
Conversation
Contributor
🔍 Commitizen bump previewMerging this PR will produce the following bump: |
|
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Intent
I remember I have a PR in commitizen about BumpRule which is aiming to redesign bump_pattern thing. Break it down to a smaller first PR. I'd like to get rid of find_increment first. Delete it if we can use max on the list of computed version increments. I want to make VersionIncrement comparable more precisely. The computed increment values should preserve existing bump_pattern and bump_map custom-plugin behavior, commit filtering, major-version-zero handling, and current no-increment behavior without redesigning the rest of BumpRule.
What Changed
find_incrementhelper with comparableVersionIncrementutilities that derive the highest bump directly from commit messages and bump-map matches.bumpandversioncommands to use the shared increment logic while preserving filtered-commit handling, major-version-zero rules, custombump_mapordering, and the existing no-increment behavior.tests/test_version_increment.py, added command tests for invalid custombump_mapvalues, and documented thatbump_mapcan useNone/nullto match without bumping.Risk Assessment
✅ Low: The change is narrowly scoped to replacing increment selection with comparable enums, and the review did not find any remaining source-visible regressions against the required bump-pattern, bump-map, filtering, major-version-zero, or no-increment behaviors.
Testing
I drove seven live scenarios against isolated git repositories and the real Commitizen runtime, capturing CLI/helper transcripts in the evidence directory; all exercised behaviors matched the author intent, with no live failures and no untested runtime gaps for this change.
cz bump --allow-no-commitafter a docs-only commit and get a PATCH bump instead of a no-increment failurecz bump --yes --allow-no-commitwith a custom matchedMINORRbump_map value and get an invalid-increment error with no fallback tagcz bump --yes --allow-no-commitwith a custom matched stringNONEbump_map value and get the legacy invalid-increment error with no fallback tagcz bump --yeson a multiline custom commit whose first matching line is MAJOR and a later line is invalid, and still get a MAJOR bumpcz version --project --next USE_GIT_COMMITSwithmajor_version_zero = trueand a breaking commit, and see0.2.0cz version --project --next USE_GIT_COMMITSwith a plugin filter that keeps only AppA commits, and see the filtered PATCH version1.0.1VersionIncrement.get_highest_by_messagesand observe resultMAJORwith one bump-pattern compileEvidence: docs-only allow-no-commit falls back to PATCH
Evidence: invalid custom MINORR bump_map value is rejected
Evidence: string NONE bump_map value is rejected
Evidence: multiline MAJOR commit short-circuits later invalid line
Evidence: USE_GIT_COMMITS respects major_version_zero
Evidence: USE_GIT_COMMITS respects filter_commits_before_bump hook
Evidence: multi-message scan returns MAJOR with one bump-pattern compile
Pipeline
Updates from git push no-mistakes
✅ **intent** - passed
✅ No issues found.
✅ **Rebase** - passed
✅ No issues found.
🔧 **Review** - 2 issues found → auto-fixed (3) ✅
commitizen/version_increment.py:33- This refactor no longer preserves the existing custombump_mapbehavior the intent requires ("The computed increment values should preserve existing bump_pattern and bump_map custom-plugin behavior").from_value()now coerces any unrecognized bump-map value toNONE, so a custom rule such asbump_map = {'^new': 'MINORR'}plus a matching commit now silently producesNONEinstead of failing as the oldfind_increment()did atVERSION_TYPES.index('MINORR'). Incz bump, that can degrade intoNoneIncrementExitor even a PATCH bump under--allow-no-commit, which is a wrong result without an error.commitizen/version_increment.py:66-from_message()recompiles the samebump_patternfor every commit message. The deletedfind_increment()compiled the regex once per scan, socz bumpandcz version --next USE_GIT_COMMITSnow do one extra regex compilation per commit since the last tag. On large histories this is an avoidable performance regression; hoist the compiled pattern to the outer helper and reuse it across messages.🔧 Fix applied.
1 error still open:
commitizen/version_increment.py:95-from_message()no longer preserves the old short-circuit-on-MAJOR behavior within a single multiline commit. With a custom rule such asbump_pattern = "^(break|oops)",bump_map = {"break": "MAJOR", "oops": "MINORR"}, and a commit message like"break: api\n\noops: typo", the previousfind_increment()stopped scanning that commit as soon as the first line producedMAJOR, so the bump succeeded. This refactor keeps scanning later lines, so the same commit now raisesValueErroronMINORR. That is a concrete regression in the existing custombump_pattern/bump_mapbehavior the intent requires to preserve.🔧 Fix applied.
1 error still open:
commitizen/version_increment.py:64- This fix round now accepts the string"NONE"as a matchedbump_mapoutput viareturn cls[value], which changes custom-plugin behavior instead of preserving it. Withbump_pattern = "^(docs)",bump_map = {"docs": "NONE"}, and a commit likedocs: update guide, the oldfind_increment()failed atVERSION_TYPES.index("NONE"); this refactor now returnsVersionIncrement.NONE, yielding a silent no-bump (or a PATCH under--allow-no-commit) without error. That contradicts the required intent to "preserve existing bump_pattern and bump_map custom-plugin behavior ... and current no-increment behavior without redesigning the rest of BumpRule." Because this extra acceptance was introduced by the review-round fix machinery rather than required for the minimal repair, the smallest honest remedy is to revert that new"NONE"acceptance and keep only the pre-existing no-increment cases (None/ unmatched rules).🔧 Fix applied.
✅ Re-checked - no issues remain.
🔧 **Test** - 1 issue found → no changes applied ✅
bump_mapinvalid value matched duringcz bump --allow-no-commitfails instead of silently patch-bumpingbump_mapstring valueNONEis still rejected duringcz bump --allow-no-commit1.0.0even if a later line maps to an invalid incrementcz version --project --next USE_GIT_COMMITShonorsmajor_version_zeroand turns a breaking change on0.xinto a minor bumpcz version --project --next USE_GIT_COMMITSpreserves no-increment behavior for docs-only commits by leaving the version unchangedfilter_commits_before_bumphook still limits bothcz version --next USE_GIT_COMMITSandcz bumpto the filtered commitslive=falseand relied only on a targeted pytest regression for an internal implementation detail. To support a pass und…python -m commitizen bump --yes --allow-no-commitin an isolated git repo configured withbump_map = { new = "MINORR", fix = "PATCH" }after seeding tag0.1.1python -m commitizen bump --yes --allow-no-commitin an isolated git repo configured withbump_map = { docs = "NONE", fix = "PATCH" }after seeding tag0.1.1python -m commitizen bump --yesin an isolated git repo with custombump_pattern = "^(break|oops)"and a multiline commit messagebreak: api\n\noops: typopython -m commitizen version --project --next USE_GIT_COMMITSin an isolated git repo withmajor_version_zero = trueand afeat!: breaking changecommit after tag0.1.0python -m commitizen version --project --next USE_GIT_COMMITSin an isolated git repo with a docs-only commit after tag1.0.0python -m commitizen version --project --next USE_GIT_COMMITSandpython -m commitizen bump --yesin an isolated git repo using a live custom plugin discovered from a temporary.dist-infoentry point that filters commits before bumpinguv run pytest tests/test_version_increment.py::test_get_highest_by_messages_compiles_pattern_once tests/test_version_increment.py::test_get_highest_by_messages_rejects_string_none_mapping tests/test_version_increment.py::test_from_message_stops_after_major_match tests/test_version_increment.py::test_get_highest_by_messages_raises_for_invalid_bump_map_value tests/commands/test_bump_command.py::test_bump_allow_no_commit_with_invalid_custom_bump_map_raises tests/commands/test_bump_command.py::test_bump_allow_no_commit_with_string_none_bump_map_raises tests/commands/test_bump_command.py::test_bump_filters_commits_before_finding_increment tests/commands/test_version_command.py::test_version_next_use_git_commits_filters_before_finding_increment tests/commands/test_version_command.py::test_version_next_use_git_commits_major_version_zero🔧 No changes applied.
✅ Re-checked - no issues remain.
cz bump --allow-no-commitafter a docs-only commit and get a PATCH bump instead of a no-increment failurecz bump --yes --allow-no-commitwith a custom matchedMINORRbump_map value and get an invalid-increment error with no fallback tagcz bump --yes --allow-no-commitwith a custom matched stringNONEbump_map value and get the legacy invalid-increment error with no fallback tagcz bump --yeson a multiline custom commit whose first matching line is MAJOR and a later line is invalid, and still get a MAJOR bumpcz version --project --next USE_GIT_COMMITSwithmajor_version_zero = trueand a breaking commit, and see0.2.0cz version --project --next USE_GIT_COMMITSwith a plugin filter that keeps only AppA commits, and see the filtered PATCH version1.0.1VersionIncrement.get_highest_by_messagesand observe resultMAJORwith one bump-pattern compilePYTHONPATH="$PWD" uv run --project "$PWD" python -m commitizen bump --yesandPYTHONPATH="$PWD" uv run --project "$PWD" python -m commitizen bump --allow-no-commitin isolated git repos using conventional commits andcz_customizeconfigs to exercise no-increment fallback, invalid custom bump_map values, and multiline custom MAJOR handlingPYTHONPATH="$PWD" uv run --project "$PWD" python -m commitizen version --project --next USE_GIT_COMMITSin an isolated git repo withmajor_version_zero = trueand a breaking commitPYTHONPATH="$PWD" uv run --project "$PWD" python - <<'PY' ... commitizen.cli.main() ... PYin an isolated git repo after temporarily registering a filtered plugin incommitizen.factory.registryto verifyfilter_commits_before_bumpaffectsUSE_GIT_COMMITSversion calculationPYTHONPATH="$PWD" uv run --project "$PWD" python - <<'PY' ... VersionIncrement.get_highest_by_messages(...) ... PYwith temporarycommitizen.version_increment.re.compileinstrumentation to verify the highest increment staysMAJORwhile the bump pattern compiles once✅ **Document** - passed
✅ No issues found.
✅ **Lint** - passed
✅ No issues found.
✅ **Push** - passed
✅ No issues found.