ci: fail pre-commit if commits contain generated trailers#1776
ci: fail pre-commit if commits contain generated trailers#1776
Conversation
Expand filter_commit_message.py with a --check mode that walks commits in PRE_COMMIT_FROM_REF..PRE_COMMIT_TO_REF (HEAD locally) and exits non-zero on any forbidden trailer. Wired as a pre-commit-stage hook so CI catches contributors who lack the commit-msg hook. Workflow now uses fetch-depth: 0 so the PR base SHA is reachable.
Greptile SummaryThis PR adds a The core issue is that Confidence Score: 4/5Mergeable but the stated CI range-check goal is not achieved without an extra_args fix in the workflow. The P1 finding shows the primary design intent (scanning all PR commits in CI) is dead code — pre-commit/action@v3.0.1 uses --all-files by default and never sets PRE_COMMIT_FROM_REF/PRE_COMMIT_TO_REF, so CI always falls back to checking HEAD only. The hook is still incrementally useful, and all other code is clean and correct, but the stated goal requires a one-line extra_args fix in the workflow to activate. bin/hooks/filter_commit_message.py (range-check code path) and .github/workflows/code-cleanup.yml (missing extra_args on the pre-commit action step) Important Files Changed
Sequence DiagramsequenceDiagram
participant Dev as Developer
participant PreCommit as pre-commit framework
participant FilterHook as filter-commit-message
participant CheckHook as check-commit-message
participant CI as CI pre-commit/action
participant Script as filter_commit_message.py
Note over Dev,Script: Local commit with commit-msg hook installed
Dev->>PreCommit: git commit
PreCommit->>CheckHook: pre-commit stage checks HEAD only
CheckHook->>Script: --check to commits_to_check to HEAD
Script-->>CheckHook: OK
PreCommit->>FilterHook: commit-msg stage
FilterHook->>Script: rewrite_file COMMIT_EDITMSG
Script-->>Dev: commit created clean
Note over CI,Script: CI current no extra_args
CI->>PreCommit: pre-commit run --all-files
Note right of PreCommit: FROM_REF and TO_REF NOT set
PreCommit->>CheckHook: always_run
CheckHook->>Script: --check to HEAD only
CheckHook-->>CI: passes or fails on HEAD only
Note over CI,Script: Desired CI with extra_args
CI->>PreCommit: pre-commit run --from-ref base --to-ref head
Note right of PreCommit: FROM_REF and TO_REF ARE set
PreCommit->>CheckHook: pre-commit stage
CheckHook->>Script: --check to all PR commits
CheckHook-->>CI: fails if any commit has forbidden trailer
Reviews (1): Last reviewed commit: "Merge branch 'dev' into ci/check-commit-..." | Re-trigger Greptile |
pre-commit/action@v3.0.1 defaults extra_args to --all-files and never injects from/to refs on its own, so PRE_COMMIT_FROM_REF / PRE_COMMIT_TO_REF were never set in CI and the range walk always fell through to HEAD-only. Pass the PR base/head explicitly via extra_args on both action steps. Side effect: formatter hooks now run on changed files instead of all files, which matches the intent of an auto-commit cleanup workflow.
There was a problem hiding this comment.
Pull request overview
This PR extends the existing commit-msg hook that strips generated trailers from commit messages by adding a CI-enforced check that fails if any commits in the PR contain forbidden “generated” trailers.
Changes:
- Refactored
filter_commit_message.pyinto reusable functions and added a--checkmode that scans commit messages in a commit range (CI) orHEAD(fallback). - Added a new local pre-commit hook (
check-commit-message) to run the--checkmode. - Updated the
code-cleanupGitHub Actions workflow to fetch full history and run pre-commit over a base..head ref range.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
bin/hooks/filter_commit_message.py |
Adds --check mode to scan commits (range-aware in CI via env vars) and refactors filtering logic. |
.pre-commit-config.yaml |
Adds check-commit-message hook at pre-commit stage to enforce the check. |
.github/workflows/code-cleanup.yml |
Ensures full git history and passes --from-ref/--to-ref to pre-commit in CI. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- No-op the --check path when PRE_COMMIT_FROM_REF/TO_REF are unset, so the local pre-commit-stage hook can't block commits or amends on the state of an existing bad HEAD; locally the commit-msg hook is in charge. The check only fires meaningfully in CI where the workflow passes the explicit range. - Wrap git rev-list / git log calls in try/except so a missing ref or shallow-clone failure surfaces as a one-line hook error instead of a Python traceback. - Rename the hook to "Check commit messages for generated signatures" since it walks the full PR range, not just HEAD.
Summary
we have a
filter-commit-messagehook that runs oncommit-msgstage that rewrites commit msgs locallyadded also
check-commit-messagethat runs in apre-commitstage that just fails you if the forbidden suffix is there.pre-commitstage is ran in CI so will block on CI level