|
1038 | 1038 | <nav class="md-nav" aria-label="Custom bump rules"> |
1039 | 1039 | <ul class="md-nav__list"> |
1040 | 1040 |
|
| 1041 | + <li class="md-nav__item"> |
| 1042 | + <a href="#filter-commits-before-bump-and-changelog-generation" class="md-nav__link"> |
| 1043 | + <span class="md-ellipsis"> |
| 1044 | + |
| 1045 | + Filter commits before bump and changelog generation |
| 1046 | + |
| 1047 | + </span> |
| 1048 | + </a> |
| 1049 | + |
| 1050 | +</li> |
| 1051 | + |
1041 | 1052 | <li class="md-nav__item"> |
1042 | 1053 | <a href="#custom-commit-validation-and-error-message" class="md-nav__link"> |
1043 | 1054 | <span class="md-ellipsis"> |
|
2138 | 2149 | <nav class="md-nav" aria-label="Custom bump rules"> |
2139 | 2150 | <ul class="md-nav__list"> |
2140 | 2151 |
|
| 2152 | + <li class="md-nav__item"> |
| 2153 | + <a href="#filter-commits-before-bump-and-changelog-generation" class="md-nav__link"> |
| 2154 | + <span class="md-ellipsis"> |
| 2155 | + |
| 2156 | + Filter commits before bump and changelog generation |
| 2157 | + |
| 2158 | + </span> |
| 2159 | + </a> |
| 2160 | + |
| 2161 | +</li> |
| 2162 | + |
2141 | 2163 | <li class="md-nav__item"> |
2142 | 2164 | <a href="#custom-commit-validation-and-error-message" class="md-nav__link"> |
2143 | 2165 | <span class="md-ellipsis"> |
@@ -2336,6 +2358,103 @@ <h2 id="custom-bump-rules">Custom bump rules<a class="headerlink" href="#custom- |
2336 | 2358 | <p>That's it, your Commitizen now supports custom rules, and you can run.</p> |
2337 | 2359 | <div class="highlight"><pre><span></span><code>cz<span class="w"> </span>-n<span class="w"> </span>cz_strange<span class="w"> </span>bump |
2338 | 2360 | </code></pre></div> |
| 2361 | +<h3 id="filter-commits-before-bump-and-changelog-generation">Filter commits before bump and changelog generation<a class="headerlink" href="#filter-commits-before-bump-and-changelog-generation" title="Permanent link">¶</a></h3> |
| 2362 | +<p>Custom rules can select which commits are relevant before Commitizen calculates a |
| 2363 | +version increment or generates a changelog.</p> |
| 2364 | +<table> |
| 2365 | +<thead> |
| 2366 | +<tr> |
| 2367 | +<th>Method</th> |
| 2368 | +<th>Used by</th> |
| 2369 | +<th>Default behavior</th> |
| 2370 | +</tr> |
| 2371 | +</thead> |
| 2372 | +<tbody> |
| 2373 | +<tr> |
| 2374 | +<td><code>filter_commits</code></td> |
| 2375 | +<td>Shared by the operation-specific methods</td> |
| 2376 | +<td>Return all commits unchanged</td> |
| 2377 | +</tr> |
| 2378 | +<tr> |
| 2379 | +<td><code>filter_commits_before_bump</code></td> |
| 2380 | +<td><code>cz bump</code> and <code>cz version --next USE_GIT_COMMITS</code></td> |
| 2381 | +<td>Call <code>filter_commits</code></td> |
| 2382 | +</tr> |
| 2383 | +<tr> |
| 2384 | +<td><code>filter_commits_before_changelog</code></td> |
| 2385 | +<td><code>cz changelog</code>, including changelogs created by bump</td> |
| 2386 | +<td>Call <code>filter_commits</code></td> |
| 2387 | +</tr> |
| 2388 | +</tbody> |
| 2389 | +</table> |
| 2390 | +<p>Override <code>filter_commits</code> when bump and changelog generation should use the same |
| 2391 | +selection. Override an operation-specific method when their selections should |
| 2392 | +differ. These methods do not affect <code>cz check</code>.</p> |
| 2393 | +<p>For example, a monorepo can use a full commit-message metadata line to associate |
| 2394 | +commits with applications:</p> |
| 2395 | +<div class="highlight"><pre><span></span><code>feat: add shared library |
| 2396 | + |
| 2397 | +Applications: ['AppA', 'AppB'] |
| 2398 | +</code></pre></div> |
| 2399 | +<p>A plugin can retain the built-in Conventional Commits behavior while filtering |
| 2400 | +on that metadata:</p> |
| 2401 | +<div class="highlight"><span class="filename">cz_applications.py</span><pre><span></span><code><span class="kn">import</span><span class="w"> </span><span class="nn">re</span> |
| 2402 | + |
| 2403 | +<span class="kn">from</span><span class="w"> </span><span class="nn">commitizen</span><span class="w"> </span><span class="kn">import</span> <span class="n">git</span> |
| 2404 | +<span class="kn">from</span><span class="w"> </span><span class="nn">commitizen.cz.conventional_commits</span><span class="w"> </span><span class="kn">import</span> <span class="n">ConventionalCommitsCz</span> |
| 2405 | +<span class="kn">from</span><span class="w"> </span><span class="nn">commitizen.exceptions</span><span class="w"> </span><span class="kn">import</span> <span class="n">InvalidConfigurationError</span> |
| 2406 | + |
| 2407 | + |
| 2408 | +<span class="k">class</span><span class="w"> </span><span class="nc">ApplicationsCommitizen</span><span class="p">(</span><span class="n">ConventionalCommitsCz</span><span class="p">):</span> |
| 2409 | +<span class="w"> </span><span class="sd">"""Apply Conventional Commits rules to one configured application.</span> |
| 2410 | + |
| 2411 | +<span class="sd"> Example:</span> |
| 2412 | +<span class="sd"> Configure `app = "AppA"` to keep commits whose `Applications:` metadata</span> |
| 2413 | +<span class="sd"> includes `AppA`.</span> |
| 2414 | +<span class="sd"> """</span> |
| 2415 | + |
| 2416 | + <span class="k">def</span><span class="w"> </span><span class="nf">filter_commits</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">commits</span><span class="p">:</span> <span class="nb">list</span><span class="p">[</span><span class="n">git</span><span class="o">.</span><span class="n">GitCommit</span><span class="p">])</span> <span class="o">-></span> <span class="nb">list</span><span class="p">[</span><span class="n">git</span><span class="o">.</span><span class="n">GitCommit</span><span class="p">]:</span> |
| 2417 | +<span class="w"> </span><span class="sd">"""Keep commits associated with the configured application.</span> |
| 2418 | + |
| 2419 | +<span class="sd"> Args:</span> |
| 2420 | +<span class="sd"> commits: The commits available to the current operation.</span> |
| 2421 | + |
| 2422 | +<span class="sd"> Returns:</span> |
| 2423 | +<span class="sd"> Commits whose full message lists the configured application.</span> |
| 2424 | + |
| 2425 | +<span class="sd"> Raises:</span> |
| 2426 | +<span class="sd"> InvalidConfigurationError: If the plugin's `app` setting is missing.</span> |
| 2427 | +<span class="sd"> """</span> |
| 2428 | + <span class="n">application</span> <span class="o">=</span> <span class="nb">dict</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">settings</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"app"</span><span class="p">)</span> |
| 2429 | + <span class="k">if</span> <span class="ow">not</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">application</span><span class="p">,</span> <span class="nb">str</span><span class="p">)</span> <span class="ow">or</span> <span class="ow">not</span> <span class="n">application</span><span class="p">:</span> |
| 2430 | + <span class="k">raise</span> <span class="n">InvalidConfigurationError</span><span class="p">(</span> |
| 2431 | + <span class="s2">"cz_applications requires a non-empty 'app' setting"</span> |
| 2432 | + <span class="p">)</span> |
| 2433 | + |
| 2434 | + <span class="n">application_line</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span> |
| 2435 | + <span class="sa">rf</span><span class="s2">"""^Applications:\s*\[[^\]]*['"]</span><span class="si">{</span><span class="n">re</span><span class="o">.</span><span class="n">escape</span><span class="p">(</span><span class="n">application</span><span class="p">)</span><span class="si">}</span><span class="s2">['"][^\]]*\]\s*$"""</span><span class="p">,</span> |
| 2436 | + <span class="n">re</span><span class="o">.</span><span class="n">MULTILINE</span><span class="p">,</span> |
| 2437 | + <span class="p">)</span> |
| 2438 | + <span class="k">return</span> <span class="p">[</span><span class="n">commit</span> <span class="k">for</span> <span class="n">commit</span> <span class="ow">in</span> <span class="n">commits</span> <span class="k">if</span> <span class="n">application_line</span><span class="o">.</span><span class="n">search</span><span class="p">(</span><span class="n">commit</span><span class="o">.</span><span class="n">message</span><span class="p">)]</span> |
| 2439 | +</code></pre></div> |
| 2440 | +<p>Expose the class through the plugin package:</p> |
| 2441 | +<div class="highlight"><span class="filename">pyproject.toml</span><pre><span></span><code><span class="k">[project.entry-points.</span><span class="s2">"commitizen.plugin"</span><span class="k">]</span> |
| 2442 | +<span class="n">cz_applications</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"cz_applications:ApplicationsCommitizen"</span> |
| 2443 | +</code></pre></div> |
| 2444 | +<p>Then select the plugin and application in each component's configuration:</p> |
| 2445 | +<div class="highlight"><span class="filename">app-a/.cz.toml</span><pre><span></span><code><span class="k">[tool.commitizen]</span> |
| 2446 | +<span class="n">name</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"cz_applications"</span> |
| 2447 | +<span class="n">app</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"AppA"</span> |
| 2448 | +<span class="n">version</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"1.0.0"</span> |
| 2449 | +<span class="n">tag_format</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s2">"$version-app-a"</span> |
| 2450 | +</code></pre></div> |
| 2451 | +<p><code>app</code> is owned and interpreted by this plugin; it is not a built-in Commitizen |
| 2452 | +setting. TOML keys under <code>[tool.commitizen]</code> are available through |
| 2453 | +<code>self.config.settings</code>. The declarative <code>[tool.commitizen.customize]</code> section |
| 2454 | +cannot override Python methods, so this use case requires a Python plugin.</p> |
| 2455 | +<p>Filtering happens before the existing rule processing. The retained commits are |
| 2456 | +still interpreted by <code>bump_pattern</code> and <code>bump_map</code> for version increments and by |
| 2457 | +<code>changelog_pattern</code> and <code>commit_parser</code> for changelog entries.</p> |
2339 | 2458 | <h3 id="custom-commit-validation-and-error-message">Custom commit validation and error message<a class="headerlink" href="#custom-commit-validation-and-error-message" title="Permanent link">¶</a></h3> |
2340 | 2459 | <p>The commit message validation can be customized by overriding the <code>validate_commit_message</code> and <code>format_error_message</code> |
2341 | 2460 | methods from <code>BaseCommitizen</code>. This allows for a more detailed feedback to the user where the error originates from.</p> |
@@ -2559,7 +2678,7 @@ <h3 id="example">Example<a class="headerlink" href="#example" title="Permanent l |
2559 | 2678 | <span class="md-icon" title="Last update"> |
2560 | 2679 | <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> |
2561 | 2680 | </span> |
2562 | | - <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date" title="November 19, 2025 09:12:08 UTC">November 19, 2025</span> |
| 2681 | + <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-date" title="September 17, 2026 19:44:31 UTC">September 17, 2026</span> |
2563 | 2682 | </span> |
2564 | 2683 |
|
2565 | 2684 |
|
|
0 commit comments