ops: anchor attribution trailer lint to actual git trailer lines
The previous regex matched any line containing both 'co-authored-by' and 'claude'/'anthropic' anywhere on the line, which flagged prose *about* the trailer, not just the trailer itself. This caught the commit that introduced the lint (subject: "ops: add CI lint for Co-Authored-By/Claude/Anthropic trailers") as a false positive. Anchor the match to `^[[:space:]]*co-authored-by:` so it only fires on an actual trailer line (Key: value at line start), not a mention in a commit subject or body. Add a --self-test mode with fixtures covering three genuine-trailer spellings, an ordinary message, and the PR's own subject line as the prose-mention regression case. Refs #4432
This commit is contained in:
parent
f45cecf08c
commit
9e618b3b90
1 changed files with 41 additions and 4 deletions
|
|
@ -2,14 +2,51 @@
|
|||
# Flags Co-Authored-By trailers with Claude/Anthropic attribution in PR commits.
|
||||
# The hive convention in /knowledge/hive-rules.md forbids these trailers.
|
||||
#
|
||||
# Pattern is loose (case-insensitive, matches `claude`, `anthropic`, or
|
||||
# `noreply@anthropic.com` anywhere after `co-authored-by`) to cover variants
|
||||
# like `Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>`.
|
||||
# Pattern is anchored to an actual git trailer line — `^[[:space:]]*co-authored-by:`
|
||||
# — not any mention of the phrase, then requires the value name `claude`,
|
||||
# `anthropic`, or `noreply@anthropic.com`. Matching is case-insensitive and
|
||||
# per-line (git trailers are one `Key: value` per line) to cover variants like
|
||||
# `Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>` while letting a
|
||||
# commit subject/body that merely *discusses* the trailer (e.g. this script's
|
||||
# own "add CI lint for Co-Authored-By/Claude/Anthropic trailers") pass.
|
||||
#
|
||||
# Scope is the PR's commits (BASE..HEAD), not entire history — old commits
|
||||
# must not fail the build.
|
||||
#
|
||||
# Run with --self-test to check the pattern against fixtures instead of
|
||||
# scanning git history.
|
||||
set -eu
|
||||
|
||||
trailer_re='^[[:space:]]*co-authored-by:.*(claude|anthropic|noreply@anthropic\.com)'
|
||||
|
||||
if [ "${1:-}" = "--self-test" ]; then
|
||||
fail=0
|
||||
|
||||
assert_match() {
|
||||
if ! printf '%s\n' "$2" | grep -qiE "$trailer_re"; then
|
||||
echo "self-test FAILED (expected match): $1" >&2
|
||||
fail=1
|
||||
fi
|
||||
}
|
||||
assert_no_match() {
|
||||
if printf '%s\n' "$2" | grep -qiE "$trailer_re"; then
|
||||
echo "self-test FAILED (expected no match): $1" >&2
|
||||
fail=1
|
||||
fi
|
||||
}
|
||||
|
||||
assert_match "bare trailer" 'Co-Authored-By: Claude'
|
||||
assert_match "full trailer with email" 'Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>'
|
||||
assert_match "lowercase trailer" 'co-authored-by: claude'
|
||||
assert_no_match "ordinary message" 'fix: correct off-by-one in parser'
|
||||
assert_no_match "prose mention of the trailer" 'ops: add CI lint for Co-Authored-By/Claude/Anthropic trailers'
|
||||
|
||||
if [ "$fail" -eq 0 ]; then
|
||||
echo "self-test OK"
|
||||
fi
|
||||
exit "$fail"
|
||||
fi
|
||||
|
||||
if [ -n "${GITHUB_BASE_REF:-}" ]; then
|
||||
base="origin/${GITHUB_BASE_REF}"
|
||||
else
|
||||
|
|
@ -35,7 +72,7 @@ fi
|
|||
hits=""
|
||||
for sha in $commits; do
|
||||
msg="$(git log -1 --format='%B' "$sha")"
|
||||
if printf '%s\n' "$msg" | grep -qiE 'co-authored-by.*claude|co-authored-by.*anthropic|co-authored-by.*noreply@anthropic\.com'; then
|
||||
if printf '%s\n' "$msg" | grep -qiE "$trailer_re"; then
|
||||
subject="$(git log -1 --format='%s' "$sha")"
|
||||
hits="${hits}${sha}|${subject}
|
||||
"
|
||||
|
|
|
|||
Loading…
Reference in a new issue