feat: detect duplicate/similar commit subjects#30
Merged
Conversation
Previously used __dirname which pointed to the action's own dist/ directory, so the config file was never found in the consuming repo. Closes #28 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a `duplicate_threshold` action input (0.0–1.0). When set, all commit subject pairs are compared using the Sørensen–Dice bigram coefficient. The conventional-commit prefix (type(scope):) is stripped before comparison so that commits differing only in scope but sharing an identical description are still flagged. Pairs whose similarity meets or exceeds the threshold are reported in the PR comment and cause the action to fail. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Extracts similarity helpers into src/similarity.js so they can be imported by tests without pulling in GitHub Actions dependencies. Adds jest and 16 test cases covering prefix stripping, scope normalisation, double-colon typo, multiline messages, symmetry, and the real-world duplicate example from the feature spec. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds hasDoubleColon() to src/similarity.js which detects the pattern type(scope): : description using a single regex on the first line. The check is wired into the per-commit report loop so violations increment countErrors and appear inline alongside commitlint errors. Controlled by the new check_double_colon action input (default: true). 10 new unit tests cover type-only, type+scope, breaking-change (!), no-space variant (fix::), colon-in-description false-positive, multiline messages, and case-insensitivity. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs npm test (jest) on Node 18 before the action self-test job. The self-test now depends on unit-tests passing first. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
✅🙏🏻 Conventional Commit 🥳 🎉🤖 Beep boop! Congrats, it like all your commit messages conform to the Conventional Commit spec! 👏👏👏 Your PR can be closed. Coffee is for closers, so here's a coffee for you: ☕️ Commit Message Lint Report
|
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.
Summary
duplicate_thresholdinput (0.0–1.0, disabled by default) toaction.ymltype(scope):) before comparing sofeat(website): fooandfeat(campaign): fooare correctly flagged as identicalfeat(auto-giving): : description) via+on the colon groupHow it works
(i, j)is comparednormalizeSubjecttakes first line only, strips prefix, lowercases, collapses punctuation/whitespacediceSimilaritycomputes the Dice coefficient over character bigramsduplicatePairscore.setFailedis called ifduplicatePairs.length > 0Usage
Test plan
feat(website): enable fooandfeat(campaign): enable fooand threshold0.5→ fails, shows duplicate sectionduplicate_threshold(default'') → feature disabled, no behaviour changeduplicate_threshold: '1.0'→ only exact-duplicate subjects after normalisation fail🤖 Generated with Claude Code