Skip to content

chore(DENG-11021): complete certain tier 2 backfills #921

chore(DENG-11021): complete certain tier 2 backfills

chore(DENG-11021): complete certain tier 2 backfills #921

Workflow file for this run

# Automated code review using Claude
# Triggers:
# - Once automatically when a PR is opened or marked ready for review
# - On demand by commenting "@claude" on a PR (non-fork PRs only)
name: Claude Code Review
on:
pull_request:
types: [opened, ready_for_review]
issue_comment:
types: [created]
concurrency:
group: claude-review-${{ github.event.pull_request.number || github.event.issue.number }}-${{ github.event_name }}
cancel-in-progress: true
jobs:
review:
if: |
(
github.event_name == 'pull_request' &&
github.event.pull_request.draft == false &&
github.event.pull_request.head.repo.fork != true &&
github.event.pull_request.user.type != 'Bot'
) || (
github.event_name == 'issue_comment' &&
github.event.issue.pull_request != null &&
contains(github.event.comment.body, '@claude') &&
github.event.comment.user.type != 'Bot'
)
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Check PR is not from a fork
if: github.event_name == 'issue_comment'
id: fork-check
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
# Fail closed: on any API error or unexpected result, default to 'true' (treat as a
# fork) so the secret-bearing steps below run only on a confirmed non-fork.
IS_FORK=$(gh api repos/${{ github.repository }}/pulls/${{ github.event.issue.number }} --jq '.head.repo.fork' || echo 'true')
echo "is_fork=${IS_FORK:-true}" >> "$GITHUB_OUTPUT"
- name: Checkout repository
if: github.event_name == 'pull_request' || steps.fork-check.outputs.is_fork == 'false'
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
# issue_comment defaults to the default branch, so check out the PR head instead
ref: ${{ github.event_name == 'issue_comment' && format('refs/pull/{0}/head', github.event.issue.number) || github.ref }}
fetch-depth: 1
persist-credentials: false
- name: Minimize previous Claude reviews
if: github.event_name == 'pull_request' || steps.fork-check.outputs.is_fork == 'false'
env:
GH_TOKEN: ${{ github.token }}
REPO_OWNER: ${{ github.repository_owner }}
REPO_NAME: ${{ github.event.repository.name }}
PR_NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
run: |
set -euo pipefail
# Filter on the `<!-- claude-review -->` marker that the prompt asks Claude to embed
# in the review body, so we don't accidentally minimize reviews from other bots.
ids=$(gh api graphql \
-f query='
query($owner: String!, $repo: String!, $pr: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $pr) {
reviews(last: 100) {
nodes {
id
isMinimized
author { login }
body
comments(first: 100) { nodes { id isMinimized } }
}
}
}
}
}' \
-f owner="$REPO_OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" \
| jq -r '.data.repository.pullRequest.reviews.nodes[]
| select(.author.login == "github-actions"
and (.body | test("<!-- claude-review -->")))
| (
(select(.isMinimized | not) | .id),
(.comments.nodes[] | select(.isMinimized | not) | .id)
)')
for id in $ids; do
echo "Minimizing $id"
gh api graphql \
-f query='mutation($id: ID!) { minimizeComment(input: {subjectId: $id, classifier: OUTDATED}) { clientMutationId } }' \
-f id="$id"
done
- name: Unset runner tokens before agent step
if: github.event_name == 'pull_request' || steps.fork-check.outputs.is_fork == 'false'
# Prevents a prompt injection in the agent step below from using these to touch the Actions
# cache/artifacts API or mint an OIDC token.
run: |
echo "ACTIONS_RUNTIME_TOKEN=" >> "$GITHUB_ENV"
echo "ACTIONS_ID_TOKEN_REQUEST_TOKEN=" >> "$GITHUB_ENV"
echo "ACTIONS_ID_TOKEN_REQUEST_URL=" >> "$GITHUB_ENV"
- name: Run Claude Code Review
if: github.event_name == 'pull_request' || steps.fork-check.outputs.is_fork == 'false'
# Mozilla org allowlist permits either "anthropics/claude-code-action@v1" (mutable tag)
# or a specific older SHA (73367208d0bc0c529b8b3fb223cbd4a8f63586e4, between v1.0.66 and v1.0.67).
# Using @v1 to stay current.
uses: anthropics/claude-code-action@v1 # zizmor: ignore[unpinned-uses]
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# Pass GITHUB_TOKEN explicitly so the action doesn't try to mint an OIDC token
# (which would require `id-token: write`). Comments will be authored by github-actions[bot].
github_token: ${{ github.token }}
trigger_phrase: "@claude"
include_fix_links: false
prompt: |
REPO: ${{ github.repository }}
PR NUMBER: ${{ github.event.pull_request.number || github.event.issue.number }}
Review this pull request for code quality, best practices, and potential issues.
Refer to docs/reference/recommended_practices.md for SQL conventions and best practices.
Also consult .github/reviewer_checklist.md and address items applicable to this PR.
Label each finding with a Conventional Comments label: `issue`, `suggestion`, or
`nitpick`. Don't use the `praise` label or the `(blocking)` decorator - humans decide
what's blocking.
State the concrete problem and the fix, and match your wording to the label: don't
hedge an `issue` ("maybe", "you may want to") or inflate a `nitpick` into a demand.
Anchor each comment to a changed line; flag unchanged code only when a change breaks
or depends on it. Comment only when you're confident the issue is real. Don't post
comments that:
- Praise the code or restate what it does. If a change is correct, say nothing.
- Ask for verification ("Check if...", "Ensure that..."). Verify it yourself or don't raise it.
- Flag style preferences not backed by a documented standard.
Post a single GitHub review using these tools in order:
1. `mcp__github__create_pending_pull_request_review` to start a pending review.
2. `mcp__github__add_comment_to_pending_review` for each inline finding, prefixed with its label.
3. `mcp__github__submit_pending_pull_request_review` to finalize. Required parameters:
- `event`: must be `"COMMENT"`. Never `APPROVE` or `REQUEST_CHANGES` - those statuses are reserved for human reviewers.
- `body`: a few sentences of overall context. Open with a factual description of what the PR does, not a characterization.
Do not include a bulleted list restating the inline findings - those belong inline only. Always include the literal
string `<!-- claude-review -->` in this body. It's a hidden HTML comment used to auto-collapse this review on rerun.
If any of those tools fail, fall back to posting a single consolidated top-level comment via `gh pr comment` so the run isn't silent.
claude_args: |
--max-budget-usd 6.00
--allowedTools mcp__github__create_pending_pull_request_review,mcp__github__add_comment_to_pending_review
--allowedTools mcp__github_inline_comment__create_inline_comment
--allowedTools mcp__github__submit_pending_pull_request_review,mcp__github__delete_pending_pull_request_review
--allowedTools mcp__github__get_pull_request_reviews,mcp__github__get_pull_request_review_comments,mcp__github__add_reply_to_pull_request_comment
--allowedTools mcp__github__get_pull_request,mcp__github__get_pull_request_diff,mcp__github__get_pull_request_files,mcp__github__get_file_contents
--allowedTools mcp__github__get_workflow_run,mcp__github__list_workflow_runs,mcp__github__list_workflow_jobs
--allowedTools "Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr comment:*),Read,Grep,Glob"
- name: Log Claude permission denials
if: ${{ always() && (github.event_name == 'pull_request' || steps.fork-check.outputs.is_fork == 'false') }}
env:
LOG: ${{ runner.temp }}/claude-execution-output.json
run: |
set -euo pipefail
if [[ ! -f "$LOG" ]]; then
echo "No execution log at $LOG; skipping denial check."
exit 0
fi
DENIALS=$(jq '[.[] | select(.type == "result") | .permission_denials // []] | add' "$LOG")
COUNT=$(jq 'length' <<< "$DENIALS")
if [[ "$COUNT" -eq 0 ]]; then
echo "No permission denials detected."
exit 0
fi
TOOLS=$(jq -r 'map(.tool_name) | unique | join(",")' <<< "$DENIALS")
echo "::warning::Claude had $COUNT permission denial(s) — review may be incomplete. Denied tools: $TOOLS"
echo "::group::Permission denial details"
jq -r '.[] | "- \(.tool_name): \(.tool_input | tojson)"' <<< "$DENIALS"
echo "::endgroup::"