From c4104219d4251509f7df39019be59551dd22ced1 Mon Sep 17 00:00:00 2001 From: gnacho Date: Tue, 22 Sep 2026 18:47:47 +0200 Subject: [PATCH] ci: reject AI co-author trailers in commit history Squash merges already got a clean body by hand, but merge commits and pushes had no gate, and a manual checklist step failed once (#337). This workflow fails any PR or push to main whose commits carry an AI co-author trailer, scanning trailer lines only. Closes #393 --- .github/workflows/commit-hygiene.yml | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 .github/workflows/commit-hygiene.yml diff --git a/.github/workflows/commit-hygiene.yml b/.github/workflows/commit-hygiene.yml new file mode 100644 index 00000000..43de0cb9 --- /dev/null +++ b/.github/workflows/commit-hygiene.yml @@ -0,0 +1,34 @@ +name: commit-hygiene + +on: + pull_request: + types: [opened, synchronize, reopened] + push: + branches: [main] + +permissions: + contents: read + +jobs: + no-ai-coauthors: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: reject AI co-author trailers + run: | + set -euo pipefail + if [ "${{ github.event_name }}" = "pull_request" ]; then + RANGE="${{ github.event.pull_request.base.sha }}..${{ github.event.pull_request.head.sha }}" + else + RANGE="${{ github.event.before }}..${{ github.event.after }}" + fi + # Only trailer lines are scanned; commit subjects and bodies are free text. + if git log --format="%(trailers)" "$RANGE" \ + | grep -iE '^co-authored-by:.*(claude|anthropic|openai|chatgpt|gpt-|gemini|copilot|grok|deepseek|qwen|kimi)'; then + echo "::error::AI co-author trailers are not allowed in commit history. Amend the commits to remove them." + exit 1 + fi + echo "commit messages clean"