Skip to content
Merged
Show file tree
Hide file tree
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
32 changes: 32 additions & 0 deletions .github/workflows/claude-blocking-review.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Claude Blocking Review

on:
pull_request:
types: [opened, synchronize, ready_for_review, reopened]

permissions:
contents: read
pull-requests: write
issues: write
id-token: write

jobs:
# Pin to v3.1.0 or later, not a caller-level `if: github.actor !=
# 'dependabot[bot]'` gate. A job-level `if:` that evaluates false means
# this job never dispatches, so a required status check on it never
# reports — it stays permanently pending on Dependabot PRs under
# branch protection that requires the check, blocking auto-merge
# entirely. v3.1.0+ instead skips Dependabot PRs from INSIDE the job,
# so the job still runs and reports a real PASS. See
# smartwatermelon/github-workflows#115/#117 for the incident that
# established this; a caller-level gate was tried and reverted.
claude-review:
# Track floating @v3, not an exact @v3.x.y. Exact tags are immutable, so a
# caller pinned to one silently misses security fixes — that is how 19 repos
# never received the GHSA-8q5r-mmjf-575q remediation. See "Prefer floating
# @v3 over an exact pin" in smartwatermelon/github-workflows README.md.
uses: smartwatermelon/github-workflows/.github/workflows/claude-blocking-review.yml@v3
with:
pr_number: ${{ github.event.pull_request.number }}
secrets:
claude_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
31 changes: 31 additions & 0 deletions .github/workflows/claude.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Claude Code

on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]

jobs:
claude:
# The author_association guard MUST stay here in the caller and must not be
# removed. Without it, any GitHub user can open an issue with injected
# instructions and Claude will execute them. The reusable workflow cannot
# enforce this guard itself — it has to live in the calling job's condition.
if: |
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude') && contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.review.author_association))
permissions:
contents: read
issues: read
pull-requests: read
id-token: write # required by claude-code-action for internal authentication
# Track floating @v3, not an exact @v3.x.y — see "Prefer floating @v3 over
# an exact pin" in smartwatermelon/github-workflows README.md. The v3 line,
# not v1: tags here are repo-wide, and v1 is frozen/deprecated.
uses: smartwatermelon/github-workflows/.github/workflows/claude-assistant.yml@v3
secrets:
claude_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
Loading