Skip to content

feat(branch): add require_description_grammar for strict branch descriptions - #581

Open
shenxianpeng wants to merge 4 commits into
mainfrom
feat/require-description-grammar
Open

shenxianpeng wants to merge 4 commits into
mainfrom
feat/require-description-grammar

Conversation

@shenxianpeng

@shenxianpeng shenxianpeng commented Sep 16, 2026 •

Copy link
Copy Markdown
Member

Why

conventional_branch checks the <type>/ prefix and accepts anything after the /. So feature/Add_Login, feature/new--login and fix/header_bug all pass, even though CC201's error text points at the spec they violate.

What

This adds an opt-in [branch] require_description_grammar, default false. When it is on, the description must also match the Conventional Branch grammar. The regex is the description part of grammar.regex in conventionalbranch.org's spec.json: lowercase alphanumeric words joined by single hyphens, with dots allowed inside a word.

[branch]
require_description_grammar = true
$ commit-check -b --require-description-grammar=true     # on feature/Add_Login
CC201 branch check failed ==> feature/Add_Login
Suggest: Use <type>/<description> with an allowed type and a lowercase, hyphen-separated description (e.g. feature/add-login), or add the branch to allow_branch_names in config

It is off by default. Dependabot names its grouped updates like dependabot/npm_and_yarn/lodash-4.17.21, with a second / and underscores, and the grammar rejects that. With the option off, the built regex is byte-for-byte the same as before. With it on, allow_branch_names = ["dependabot/.+"] or ignore_authors = ["dependabot[bot]"] exempts the bot.

Changes

  • rule_builder.py: the grammar constant, swapped in for .+ when the option is on, plus a suggestion that describes the expected format.
  • config_merger.py and main.py: the default, CCHK_REQUIRE_DESCRIPTION_GRAMMAR and --require-description-grammar, like every other key.
  • README.md: one row in the configuration reference, as readme_test requires. The full explanation will go on commit-check.com with the release.
  • .github/copilot-instructions.md: one bullet.

Tests

TestBranchDescriptionGrammar checks that:

  • conformant names pass;
  • non-conformant ones are rejected, Dependabot's grouped names included;
  • with the option off, the regex is unchanged;
  • allow_branch_names still lets a bot through;
  • the suggestion describes the format.

The config merger tests cover the default, the env var and the flag. The full suite passes: 1112 tests. End to end, feature/Add_Login passes by default, fails with the flag, and feature/add-login passes with the env var.

After release

commit-check.com's docs-sync test checks every runtime option against configuration.md, so the site needs a row and a short section for this option in the same change that brings it to the released version.

… Branch validation

conventional_branch checks the <type>/ prefix and accepts anything after
the "/" as a bare ".+", so feature/Add_Login, fix/header_bug and
release/v1.-2.0 all pass today although CC201's own error text names the
Conventional Branch specification they violate.

Add [branch] require_description_grammar, off by default, which also holds
the description to the spec's grammar: lowercase alphanumeric segments
joined by single hyphens, dots allowed inside a segment. With the option
off the built regex is byte-for-byte what it was, so Dependabot's own
grouped-update names (dependabot/npm_and_yarn/lodash-4.17.21) keep
validating as before -- which is why this is opt-in rather than a
tightening of the default.

fix_branch_description() gives the failure a concrete correction when one
is unambiguous (feature/Add_Login -> feature/add-login) and declines when
it would be a guess (a second "/", shell punctuation, nothing left after
stripping). BranchValidator composes it with fix_branch_type so a branch
with both halves wrong gets one suggestion; the existing regex re-check
still gates whether any suggestion is offered.
@shenxianpeng
shenxianpeng requested a review from a team as a code owner September 16, 2026 14:07
@github-actions github-actions Bot added the enhancement New feature or request label Sep 16, 2026
@coderabbitai

coderabbitai Bot commented Sep 16, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 476b7f78-1e94-4701-b5b4-2c8dd40317ae

📥 Commits

Reviewing files that changed from the base of the PR and between 3947e1e and 8ada1f6.

📒 Files selected for processing (11)
  • .github/copilot-instructions.md
  • README.md
  • commit_check/config_merger.py
  • commit_check/engine.py
  • commit_check/fixes.py
  • commit_check/main.py
  • commit_check/rule_builder.py
  • tests/config_merger_test.py
  • tests/engine_fixes_test.py
  • tests/fixes_test.py
  • tests/rule_builder_test.py

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The pull request adds an opt-in branch.require_description_grammar setting. It supports configuration through defaults, environment variables, and CLI arguments. Strict validation, description normalization, branch suggestions, documentation, and tests are included.

Changes

Branch description grammar

Layer / File(s) Summary
Configuration and documentation
commit_check/config_merger.py, commit_check/main.py, README.md, .github/copilot-instructions.md, tests/config_merger_test.py
The new option defaults to false and is available through the CLI and CCHK_REQUIRE_DESCRIPTION_GRAMMAR. Documentation describes the grammar, exemptions, and configuration reference.
Strict branch validation
commit_check/rule_builder.py, tests/rule_builder_test.py
The branch regex uses lowercase alphanumeric segments with optional dots and single hyphens when strict grammar is enabled.
Description normalization and suggestions
commit_check/fixes.py, commit_check/engine.py, tests/fixes_test.py, tests/engine_fixes_test.py
fix_branch_description normalizes correctable descriptions. BranchValidator combines description and type fixes, then validates the result before suggesting a rename. Tests cover valid and unresolvable inputs.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~25 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant CLIConfig
  participant BranchValidator
  participant fix_branch_description
  participant BranchRegex
  CLIConfig->>BranchValidator: provide require_description_grammar
  BranchValidator->>fix_branch_description: normalize branch description
  fix_branch_description-->>BranchValidator: return corrected description or None
  BranchValidator->>BranchRegex: validate combined suggestion
  BranchRegex-->>BranchValidator: accept or reject suggestion
Loading

Merge Risk: ⚪ Minimal · up to 8ada1

The opt-in grammar setting and branch rename suggestions behave as intended; no actionable merge risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 32 functions across 9 files. (2 skipped: … Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely identifies the main change: adding the opt-in require_description_grammar setting for strict branch descriptions.
Full details: Docstring Coverage

Explanation

Docstring coverage is 18.75% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 32 functions across 9 files. (2 skipped: 2 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/require-description-grammar

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@shenxianpeng shenxianpeng changed the title feat(branch): add require_description_grammar for strict Conventional Branch validation feat(branch): add require_description_grammar for strict branch descriptions Sep 16, 2026
@codecov

codecov Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.00%. Comparing base (e1d20fd) to head (11a456c).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #581   +/-   ##
=======================================
  Coverage   98.99%   99.00%           
=======================================
  Files          14       14           
  Lines        2198     2203    +5     
=======================================
+ Hits         2176     2181    +5     
  Misses         22       22           

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

`^[-.]+|[-.]+$` anchors each alternative on one side only, which is the
shape of a mistake (Sonar S5850) even where it is deliberate. str.strip
says the same thing plainly and drops a regex.

Copy link
Copy Markdown
Member Author

On CodeRabbit's Docstring Coverage pre-merge warning (18.75% vs an 80% threshold) — I checked it rather than waving it through, and I don't think it should start a change here.

Of the 15 functions this PR adds, 14 are test methods and 1 is production code:

File Documented / added
commit_check/fixes.py (fix_branch_description) 1 / 1
tests/fixes_test.py 0 / 4
tests/engine_fixes_test.py 0 / 4
tests/rule_builder_test.py 0 / 6

The one production function carries a full docstring. The percentage is driven entirely by test methods, and the files they land in are the ones that already document tests by class rather than by method — on main, tests/fixes_test.py is 0/41 (0.0%), tests/engine_fixes_test.py is 2/48 (4.2%), and tests/rule_builder_test.py is 43/85 (50.6%). Across the whole suite it is 524/910 (57.6%), i.e. the 80% bar isn't this repo's practice anywhere.

The new tests follow that same shape: each new test class carries a docstring saying what it covers (TestBranchDescriptionGrammar, TestBranchDescriptionFix), with self-describing method names under it. Adding a docstring to each of the 14 would raise the metric while making these files read differently from the tests beside them, so I've left them as they are.

Happy to add them if you'd rather have the threshold satisfied — just say so.


Generated by Claude Code

@codspeed

codspeed Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 601 untouched benchmarks
⏩ 126 skipped benchmarks1


Comparing feat/require-description-grammar (11a456c) with main (e1d20fd)

Open in CodSpeed

Footnotes

  1. 126 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports. ↩

The option itself is a regex swap in the branch rule, plus the key, its
CCHK_* variable and its flag. The rest of this PR had grown around it:

- fix_branch_description, its composition with fix_branch_type in the
  branch validator and 76 lines of tests are gone. A rejected
  description now gets a suggestion that says what the description must
  look like, which is what a reader needs to fix it; an automatic rename
  can follow if people ask for one.
- The README keeps one row in the configuration reference, which
  readme_test requires; the explanation belongs on commit-check.com with
  the rest of the reference, now that the README is a landing page.
- The comments, the --help text and the copilot-instructions bullet are
  one line each.
- The tests are one class: conformant names pass, non-conformant ones
  (Dependabot's grouped names among them) are rejected, the regex is
  byte-for-byte unchanged with the option off, allow_branch_names still
  readmits a bot, and the suggestion names the format.
@sonarqubecloud

Copy link
Copy Markdown

This branch has not been deployed

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

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants