Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions .github/workflows/no-coauthor-trailers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
# Shared by both steps so the self-test actually exercises the same
# pattern the real check uses, not an independent hardcoded copy that
# could silently drift and keep passing after PATTERN regresses.
PATTERN: '(?m)^Co-authored-by:\s*.+<.+@.+>\s*$'
PATTERN: '(?m)^(Co-authored-by:\s*.+<.+@.+>|[^\w\n]*Generated with\s+\S.*)\s*$'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep Generated-with matching on one line

Because \s+ also consumes newlines, a PR description or commit message containing a heading such as ## Generated with, followed by an ordinary paragraph, matches this pattern even though no attribution appears on that line. This causes the required check to reject legitimate prose; restrict the whitespace after with to horizontal whitespace so the required non-space content must occur on the same line.

Useful? React with πŸ‘Β / πŸ‘Ž.

steps:
- name: Self-test (negative control β€” must run before the real check)
run: |
Expand All @@ -34,8 +34,17 @@ jobs:
echo '{"commit":{"message":"docs: explain why Co-authored-by trailers are rejected"}}' \
| jq -e '.commit.message | test(env.PATTERN; "i") | not' >/dev/null \
|| { echo "::error::self-test failed: prose mention was incorrectly matched"; exit 1; }
echo '{"commit":{"message":"body\n\nπŸ€– Generated with [Claude Code](https://claude.com/claude-code)"}}' \
| jq -e '.commit.message | test(env.PATTERN; "i")' >/dev/null \
|| { echo "::error::self-test failed: known-bad Generated with line was NOT matched"; exit 1; }
echo '{"commit":{"message":"body\n\nGenerated with Claude Code"}}' \
| jq -e '.commit.message | test(env.PATTERN; "i")' >/dev/null \
|| { echo "::error::self-test failed: plain Generated with line was NOT matched"; exit 1; }
echo '{"commit":{"message":"docs: reject Generated with attribution lines in PRs"}}' \
| jq -e '.commit.message | test(env.PATTERN; "i") | not' >/dev/null \
|| { echo "::error::self-test failed: prose mention of Generated with was incorrectly matched"; exit 1; }

- name: Check commits and PR description for Co-Authored-By trailers
- name: Check commits and PR description for Co-Authored-By trailers and Generated with lines
env:
GH_TOKEN: ${{ github.token }}
REPO: ${{ github.repository }}
Expand All @@ -56,8 +65,8 @@ jobs:
--jq 'select(.body != null) | select(.body | test(env.PATTERN; "i")) | "PR body"')

if [ -n "$commit_violations" ] || [ -n "$body_violation" ]; then
echo "::error::Co-Authored-By trailer found."
echo "::error::Co-Authored-By trailer or 'Generated with' attribution line found."
[ -n "$commit_violations" ] && echo "Commits: $commit_violations β€” amend/rebase and force-push."
[ -n "$body_violation" ] && echo "PR description contains a trailer β€” edit the PR body to remove it."
[ -n "$body_violation" ] && echo "PR description contains one β€” edit the PR body to remove the line."
exit 1
fi
Loading