Prepared statements #349
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: "Commit authorship gate" | |
| # Block PRs whose commits are authored by AI agents or LLM provider accounts. | |
| # Per CONTRIBUTING.md, commits must be authored under a human's name and email. | |
| # | |
| # Uses pull_request_target so the check fires even when the contributor's fork | |
| # has Actions disabled or is subject to the first-time contributor approval gate. | |
| # Safe because we only read commit metadata; PR code is never executed. | |
| on: | |
| pull_request_target: | |
| types: [opened, synchronize, reopened] | |
| permissions: | |
| contents: read | |
| jobs: | |
| check-authorship: | |
| name: "Verify commit authorship" | |
| runs-on: "ubuntu-latest" | |
| steps: | |
| # Checkout points at the fork (head.repo) — pull_request_target defaults | |
| # to the base repo, where the PR's head SHA does not exist. | |
| - name: "Checkout PR (metadata only)" | |
| uses: "actions/checkout@v6" | |
| with: | |
| fetch-depth: 0 | |
| repository: ${{ github.event.pull_request.head.repo.full_name }} | |
| ref: ${{ github.event.pull_request.head.sha }} | |
| persist-credentials: false | |
| # The fork doesn't contain the base SHA; fetch it so the diff range resolves. | |
| - name: "Fetch base ref for diff range" | |
| env: | |
| BASE_REPO: ${{ github.event.pull_request.base.repo.clone_url }} | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| run: | | |
| git remote add base "$BASE_REPO" | |
| git fetch --no-tags --depth=1 base "$BASE_SHA" | |
| # DENY list is matched (regex, case-insensitive) against author name and email | |
| # of every commit in the PR. Extend conservatively as new agents appear. | |
| - name: "Scan commit authors" | |
| env: | |
| BASE_SHA: ${{ github.event.pull_request.base.sha }} | |
| HEAD_SHA: ${{ github.event.pull_request.head.sha }} | |
| run: | | |
| set -e | |
| DENY=( | |
| '@anthropic\.com' | |
| '@openai\.com' | |
| '@cursor\.sh' | |
| '@cursor\.so' | |
| '@codeium\.com' | |
| 'copilot.*\[bot\]' | |
| 'copilot.*@.*users\.noreply\.github\.com' | |
| '^claude([-_ ]|$)' | |
| '^chatgpt([-_ ]|$)' | |
| '^gpt-' | |
| ) | |
| FAIL=0 | |
| while IFS=$'\t' read -r sha name email; do | |
| for pattern in "${DENY[@]}"; do | |
| if echo "$name" | grep -iqE "$pattern" || echo "$email" | grep -iqE "$pattern"; then | |
| echo "::error title=AI-authored commit::${sha:0:12} — '$name <$email>' matches '$pattern'" | |
| FAIL=1 | |
| break | |
| fi | |
| done | |
| done < <(git log --format='%H%x09%an%x09%ae' "${BASE_SHA}..${HEAD_SHA}") | |
| if [ "$FAIL" -ne 0 ]; then | |
| echo "" | |
| echo "PRs must be authored by humans. See CONTRIBUTING.md." | |
| exit 1 | |
| fi | |
| echo "All commits authored by human accounts." |