Repository: orhun/git-cliff (language: python)

Issue:
Support bumping version based on configurable custom pattern
### Is there an existing issue or pull request for this?

- [X] I have searched the existing issues and pull requests

### Feature description

This is already implemented in `next-version` here: https://github.com/MarcoIeni/release-plz/pull/1511



### Desired solution

What we need to do is add these new fields (`custom_major_increment_regex` and `custom_minor_increment_regex`) to the bump configuration in `git-cliff`.

### Alternatives considered

None.

### Additional context

See https://git-cliff.org/docs/configuration/bump


Discussion / hints:

Fix patch:
diff --git a/Cargo.lock b/Cargo.lock
index 759095f732..6b7d46737f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1498,11 +1498,12 @@ dependencies = [
 
 [[package]]
 name = "next_version"
-version = "0.2.17"
+version = "0.2.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7beae5e84c3330a90f0f89eae10f5cd4c17c3be0f119ab36d94fd908c7b8c8fb"
+checksum = "a0c2cdfd777d2aef50e83560295f35b11a934efdaae1eb92c807c6b4844b435b"
 dependencies = [
  "conventional_commit_parser",
+ "regex",
  "semver",
 ]
 
diff --git a/git-cliff-core/Cargo.toml b/git-cliff-core/Cargo.toml
index 83cb02bb1e..c7634d2d98 100644
--- a/git-cliff-core/Cargo.toml
+++ b/git-cliff-core/Cargo.toml
@@ -57,7 +57,7 @@ tera = "1.20.0"
 indexmap = { version = "2.2.6", optional = true }
 toml = "0.8.14"
 lazy-regex = "3.1.0"
-next_version = "0.2.17"
+next_version = "0.2.18"
 semver = "1.0.23"
 document-features = { version = "0.2.8", optional = true }
 reqwest = { version = "0.12.5", default-features = false, features = [
diff --git a/git-cliff-core/src/config.rs b/git-cliff-core/src/config.rs
index 1a142ab721..eea73925e2 100644
--- a/git-cliff-core/src/config.rs
+++ b/git-cliff-core/src/config.rs
@@ -200,6 +200,24 @@ pub struct Bump {
 	///
 	/// When set, the version will be set to this value if no tags are found.
 	pub initial_tag: Option<String>,
+
+	/// Configure a custom regex pattern for major version increments.
+	///
+	/// This will check only the type of the commit against the given pattern.
+	///
+	/// ### Note
+	///
+	/// `commit type` according to the spec is only `[a-zA-Z]+`
+	pub custom_major_increment_regex: Option<String>,
+
+	/// Configure a custom regex pattern for minor version increments.
+	///
+	/// This will check only the type of the commit against the given pattern.
+	///
+	/// ### Note
+	///
+	/// `commit type` according to the spec is only `[a-zA-Z]+`
+	pub custom_minor_increment_regex: Option<String>,
 }
 
 /// Parser for grouping commits.
diff --git a/git-cliff-core/src/release.rs b/git-cliff-core/src/release.rs
index 4d3f9308f1..118134cef4 100644
--- a/git-cliff-core/src/release.rs
+++ b/git-cliff-core/src/release.rs
@@ -99,13 +99,28 @@ impl<'a> Release<'a> {
 						}
 					}
 				}
-				let next_version = VersionUpdater::new()
+				let mut next_version = VersionUpdater::new()
 					.with_features_always_increment_minor(
 						config.features_always_bump_minor.unwrap_or(true),
 					)
 					.with_breaking_always_increment_major(
 						config.breaking_always_bump_major.unwrap_or(true),
-					)
+					);
+				if let Some(custom_major_increment_regex) =
+					&config.custom_major_increment_regex
+				{
+					next_version = next_version.with_custom_major_increment_regex(
+						custom_major_increment_regex,
+					)?;
+				}
+				if let Some(custom_minor_increment_regex) =
+					&config.custom_minor_increment_regex
+				{
+					next_version = next_version.with_custom_minor_increment_regex(
+						custom_minor_increment_regex,
+					)?;
+				}
+				let next_version = next_version
 					.increment(
 						&semver?,
 						self.commits
@@ -256,9 +271,11 @@ mod test {
 			let release = build_release(version, commits);
 			let next_version =
 				release.calculate_next_version_with_config(&Bump {
-					features_always_bump_minor: Some(false),
-					breaking_always_bump_major: Some(false),
-					initial_tag:                None,
+					features_always_bump_minor:   Some(false),
+					breaking_always_bump_major:   Some(false),
+					initial_tag:                  None,
+					custom_major_increment_regex: None,
+					custom_minor_increment_regex: None,
 				})?;
 			assert_eq!(expected_version, &next_version);
 		}
@@ -277,9 +294,11 @@ mod test {
 			let release = build_release(version, commits);
 			let next_version =
 				release.calculate_next_version_with_config(&Bump {
-					features_always_bump_minor: Some(true),
-					breaking_always_bump_major: Some(false),
-					initial_tag:                None,
+					features_always_bump_minor:   Some(true),
+					breaking_always_bump_major:   Some(false),
+					initial_tag:                  None,
+					custom_major_increment_regex: None,
+					custom_minor_increment_regex: None,
 				})?;
 			assert_eq!(expected_version, &next_version);
 		}
@@ -298,9 +317,11 @@ mod test {
 			let release = build_release(version, commits);
 			let next_version =
 				release.calculate_next_version_with_config(&Bump {
-					features_always_bump_minor: Some(false),
-					breaking_always_bump_major: Some(true),
-					initial_tag:                None,
+					features_always_bump_minor:   Some(false),
+					breaking_always_bump_major:   Some(true),
+					initial_tag:                  None,
+					custom_major_increment_regex: None,
+					custom_minor_increment_regex: None,
 				})?;
 			assert_eq!(expected_version, &next_version);
 		}
@@ -319,9 +340,11 @@ mod test {
 			assert_eq!(
 				"0.1.0",
 				empty_release.calculate_next_version_with_config(&Bump {
-					features_always_bump_minor: Some(features_always_bump_minor),
-					breaking_always_bump_major: Some(breaking_always_bump_major),
-					initial_tag:                None,
+					features_always_bump_minor:   Some(features_always_bump_minor),
+					breaking_always_bump_major:   Some(breaking_always_bump_major),
+					initial_tag:                  None,
+					custom_major_increment_regex: None,
+					custom_minor_increment_regex: None,
 				})?
 			);
 		}
diff --git a/website/docs/configuration/bump.md b/website/docs/configuration/bump.md
index ec39a56088..5f0f5bc3e9 100644
--- a/website/docs/configuration/bump.md
+++ b/website/docs/configuration/bump.md
@@ -33,3 +33,51 @@ When `false`, a breaking change commit will trigger:
 Configures the initial version of the project.
 
 When set, the version will be set to this value if no tags are found.
+
+### custom_major_increment_regex & custom_minor_increment_regex
+
+Configures additional commit types that should increment the major or minor accordingly.
+
+They should be used rarely, only in the case you have a spacial case for incrementing versions.
+
+Expects a valid regex pattern.
+
+For example:
+
+```toml
+[bump]
+features_always_bump_minor = true
+breaking_always_bump_major = true
+custom_major_increment_regex = "major"
+custom_minor_increment_regex = "minor|more"
+```
+
+with this history:
+
+```
+5189568 (HEAD -> main) major: 1
+0b17b48 (tag: 0.1.0) initial commit
+```
+
+will result in:
+
+```bash
+git-cliff --bumped-version
+
+1.0.0
+```
+
+or, with history:
+
+```
+47206d0 (HEAD -> main) more: 1
+0b17b48 (tag: 0.1.0) initial commit
+```
+
+will result in:
+
+```bash
+git-cliff --bumped-version
+
+0.2.0
+```


Test patch:
diff --git a/.github/fixtures/test-bump-version-custom-minor/cliff.toml b/.github/fixtures/test-bump-version-custom-minor/cliff.toml
new file mode 100644
index 0000000000..b75904247f
--- /dev/null
+++ b/.github/fixtures/test-bump-version-custom-minor/cliff.toml
@@ -0,0 +1,32 @@
+[changelog]
+# template for the changelog footer
+header = """
+# Changelog\n
+All notable changes to this project will be documented in this file.\n
+"""
+# template for the changelog body
+# https://keats.github.io/tera/docs/#introduction
+body = """
+{% if version %}\
+    ## [{{ version | trim_start_matches(pat="v") }}]
+{% else %}\
+    ## [unreleased]
+{% endif %}\
+{% for group, commits in commits | group_by(attribute="group") %}
+    ### {{ group | upper_first }}
+    {% for commit in commits %}
+        - {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
+    {% endfor %}
+{% endfor %}\n
+"""
+# template for the changelog footer
+footer = """
+<!-- generated by git-cliff -->
+"""
+# remove the leading and trailing whitespace from the templates
+trim = true
+
+[bump]
+features_always_bump_minor = true
+breaking_always_bump_major = true
+custom_minor_increment_regex = "minor|more"
diff --git a/.github/fixtures/test-bump-version-custom-minor/commit.sh b/.github/fixtures/test-bump-version-custom-minor/commit.sh
new file mode 100755
index 0000000000..8d9f2776f6
--- /dev/null
+++ b/.github/fixtures/test-bump-version-custom-minor/commit.sh
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+set -e
+
+GIT_COMMITTER_DATE="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add feature 1"
+GIT_COMMITTER_DATE="2021-01-23 01:23:45" git commit --allow-empty -m "feat: add feature 2"
+git tag v0.1.0
+
+GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "minor: add minor"
+GIT_COMMITTER_DATE="2021-01-23 01:23:46" git commit --allow-empty -m "fix: fix feature 2"
diff --git a/.github/fixtures/test-bump-version-custom-minor/expected.md b/.github/fixtures/test-bump-version-custom-minor/expected.md
new file mode 100644
index 0000000000..6705546123
--- /dev/null
+++ b/.github/fixtures/test-bump-version-custom-minor/expected.md
@@ -0,0 +1,22 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+## [0.2.0]
+
+### Fix
+
+- Fix feature 2
+
+### Minor
+
+- Add minor
+
+## [0.1.0]
+
+### Feat
+
+- Add feature 1
+- Add feature 2
+
+<!-- generated by git-cliff -->
diff --git a/.github/workflows/test-fixtures.yml b/.github/workflows/test-fixtures.yml
index 0afbefd0d9..a338046926 100644
--- a/.github/workflows/test-fixtures.yml
+++ b/.github/workflows/test-fixtures.yml
@@ -38,6 +38,8 @@ jobs:
           - fixtures-name: test-split-commits
           - fixtures-name: test-bump-version
             command: --bump
+          - fixtures-name: test-bump-version-custom-minor
+            command: --bump
           - fixtures-name: test-bumped-version
             command: --bumped-version
           - fixtures-name: test-footer-template