From a67b765dc72eaea930dafb3c75873203f1e522f2 Mon Sep 17 00:00:00 2001 From: Sal Date: Wed, 2 Sep 2026 20:07:53 +0100 Subject: [PATCH] fix(ci): stop the trailer guard failing open on large messages 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 --- .github/workflows/commit-lint.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/commit-lint.yml b/.github/workflows/commit-lint.yml index 85298e575..5f13500d6 100644 --- a/.github/workflows/commit-lint.yml +++ b/.github/workflows/commit-lint.yml @@ -80,7 +80,12 @@ jobs: checked=0 while IFS= read -r sha; do - if git show -s --format='%B' "$sha" | grep -qiE "$DISALLOWED_TRAILER_PATTERN"; then + # grep -c, not grep -q. Under pipefail, grep -q exits on its first + # match while git is still writing, git takes SIGPIPE and returns + # 141, and the pipeline result turns a real match into a miss for + # any message larger than the pipe buffer. grep -c reads to the end, + # so the writer always finishes (z-shell/.github#587). + if [ "$(git show -s --format='%B' "$sha" | grep -ciE "$DISALLOWED_TRAILER_PATTERN")" -gt 0 ]; then echo "::error::Bot/agent Co-authored-by trailer found (${sha:0:7}): remove before merging. A human co-author is fine; only bot/AI-agent identities are banned (AGENTS.md). A squash merge without an explicit --subject/--body can also reintroduce one — see runbooks/branch-protection.md." errors=$((errors + 1)) fi