Skip to content

fix(ci): stop the trailer guard failing open on large messages - #596

Merged
ss-o merged 1 commit into
mainfrom
bug-587
Sep 2, 2026
Merged

fix(ci): stop the trailer guard failing open on large messages#596
ss-o merged 1 commit into
mainfrom
bug-587

Conversation

@ss-o

@ss-o ss-o commented Sep 2, 2026

Copy link
Copy Markdown
Member

Fixes the fail-open reported in #587.

Validate Commits matched the disallowed trailer as a pipeline under
set -o pipefail:

git show -s --format='%B' "$sha" | grep -qiE "$DISALLOWED_TRAILER_PATTERN"

grep -q exits on its first match. For a commit message larger than the pipe
buffer, git is still writing at that moment, takes SIGPIPE, and returns
141. pipefail promotes that to the pipeline result, the if sees failure,
and a banned trailer that was actually present is reported as absent.

The fix

grep -c with a numeric test. grep -c reads to the end of its input, so the
writer always finishes and no SIGPIPE arises.

grep -c was chosen over a [[ $message =~ $pattern ]] rewrite deliberately.
Both stop the fail-open, but [[ =~ ]] swaps grep's ERE engine for bash's and
needs shopt -s nocasematch to keep the -i behaviour. The pattern contains
[[:space:]] and \[bot\], and a silently different match here is worse than
the bug being fixed. grep -c keeps the existing engine and flags unchanged.

Verification

Four real commits, each evaluated under both constructs:

Commit message Old (grep -q) New (grep -c)
Small, bot trailer FLAGGED FLAGGED
3 MB, bot trailer clean FLAGGED
3 MB, human Co-authored-by clean clean
3 MB, no trailer clean clean

The second row is the defect and the only behaviour that changes. A human
co-author is still allowed, and a large clean message still passes, so nothing
starts failing that should not.

actionlint and trunk check are clean.

Not included

z-shell/zi carries the same construct and needs the same fix; tracked
separately so each repository's change is reviewable on its own.

#592 proposes a test harness for these patterns. It lands after this fix
rather than with it, so the harness can be shown to catch the pre-fix construct
rather than merely passing against the fixed one.

Closes #587

Validate Commits ran the trailer check as a pipeline under pipefail with
grep -q. grep -q exits on its first match, so for a commit message larger than
the pipe buffer git was still writing, took SIGPIPE, and returned 141. pipefail
made that the pipeline result, and the if turned a real match into a miss. The
banned trailer passed.

Use grep -c with a numeric test. grep -c reads to end of input, so the writer
always finishes and no SIGPIPE arises. It keeps grep's own ERE engine and -i
semantics, unlike a bash =~ rewrite, so the pattern behaves identically.

Verified on four real commits: a 3 MB message carrying a bot trailer reports
clean under the old construct and flagged under the new one, while a small
bot trailer, a large human trailer, and a large clean message are unchanged.

Closes #587
@ss-o
ss-o requested a review from a team as a code owner September 2, 2026 19:08
@ss-o
ss-o merged commit 383a640 into main Sep 2, 2026
8 checks passed
@ss-o
ss-o deleted the bug-587 branch September 2, 2026 19:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(ci): commit-lint trailer guard fails open on large commit messages

1 participant