Claude #546
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
| # Copyright (c) Facebook, Inc. and its affiliates. | |
| # | |
| # Licensed under the Apache License, Version 2.0 (the "License"); | |
| # you may not use this file except in compliance with the License. | |
| # You may obtain a copy of the License at | |
| # | |
| # http://www.apache.org/licenses/LICENSE-2.0 | |
| # | |
| # Unless required by applicable law or agreed to in writing, software | |
| # distributed under the License is distributed on an "AS IS" BASIS, | |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| # See the License for the specific language governing permissions and | |
| # limitations under the License. | |
| # Claude — skill-based PR assistant (replaces claude-review.yml) | |
| # | |
| # This workflow uses izaitsevfb/claude-code-action (a fork that fixes | |
| # forked-PR handling) with Claude Skills instead of inline prompts. | |
| # Review logic lives in .claude/skills/pr-review/SKILL.md. | |
| # | |
| # Supported commands (comment on a PR): | |
| # @claude /pr-review [context] — thorough code review | |
| # @claude /query <question> — ask about the PR or codebase | |
| # | |
| # Differences from claude-review.yml (the legacy workflow): | |
| # - Uses claude-code-action (higher-level) instead of claude-code-base-action | |
| # - Review/query instructions are in Skills, not inline heredocs | |
| # - Trigger phrase is @claude (not /claude-review or /claude-query) | |
| # - Tag mode handles PR context, diff, and comment posting automatically | |
| # | |
| # Security model: | |
| # - Hardcoded user allowlist gates workflow execution | |
| # - Read-only tools enforced via --allowedTools | |
| # - Fork PRs handled securely by the action fork | |
| name: Claude | |
| on: | |
| # Tag mode: action detects @claude in comments and responds inline | |
| issue_comment: | |
| types: [created] | |
| # Agent mode: manual trigger for testing (log-only when dry_run is true) | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: PR number to review | |
| required: true | |
| type: number | |
| model: | |
| description: Claude model to use | |
| required: false | |
| type: choice | |
| options: | |
| - claude-opus-4-6 | |
| - claude-opus-4-1-20250805 | |
| - claude-sonnet-4-20250514 | |
| - claude-4-0-sonnet-20250805 | |
| default: claude-opus-4-6 | |
| additional_context: | |
| description: Additional instructions for the review (e.g. focus on memory safety) | |
| required: false | |
| type: string | |
| default: '' | |
| dry_run: | |
| description: Log review output only — do not post a comment on the PR | |
| required: false | |
| type: boolean | |
| default: false | |
| # Restrict default permissions — jobs declare only what they need | |
| permissions: | |
| contents: read | |
| jobs: | |
| claude-assistant: | |
| name: Claude Assistant | |
| runs-on: ubuntu-latest | |
| permissions: | |
| contents: read | |
| pull-requests: write | |
| issues: write | |
| actions: read | |
| id-token: write | |
| # Gate: workflow_dispatch always runs; issue_comment requires PR context, | |
| # @claude mention, and an authorized user | |
| if: >- | |
| github.event_name == 'workflow_dispatch' || | |
| ( | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '@claude') && | |
| contains(fromJSON('["kgpai", "mbasmanova", "pedroerp", "yuhta", "kagamiori", "bikramSingh91", "kevinwilfong", "xiaoxmeng", "kKPulla", "juwentus1234", "penescu", "srsuryadev", "jainxrohit", "pratikpugalia"]'), github.event.comment.user.login) | |
| ) | |
| steps: | |
| # For workflow_dispatch, checkout the PR merge ref so Claude has the | |
| # PR code. For issue_comment, default ref is fine — the action handles | |
| # diff fetching internally. | |
| - uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0 | |
| with: | |
| fetch-depth: 1 | |
| ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/pull/{0}/merge', inputs.pr_number) || '' }} | |
| persist-credentials: false | |
| # Build prompt and claude_args in bash to avoid format() curly-brace | |
| # issues with user-supplied additional_context, and to keep the logic | |
| # readable. Outputs are only set for workflow_dispatch; for | |
| # issue_comment (tag mode), prompt stays empty so the action uses | |
| # tag mode and CLAUDE.md provides skill routing. | |
| - name: Build prompt and args | |
| id: config | |
| if: github.event_name == 'workflow_dispatch' | |
| env: | |
| INPUT_PR_NUMBER: ${{ inputs.pr_number }} | |
| INPUT_MODEL: ${{ inputs.model }} | |
| INPUT_DRY_RUN: ${{ inputs.dry_run }} | |
| INPUT_ADDITIONAL_CONTEXT: ${{ inputs.additional_context }} | |
| run: | | |
| # --- Prompt --- | |
| PROMPT="Review the PR currently checked out in the Velox project current workspace. Use the /pr-review skill." | |
| if [ "$INPUT_DRY_RUN" = "true" ]; then | |
| PROMPT="$PROMPT Output the review to the workflow log only. Do NOT post any comments on the PR." | |
| else | |
| PROMPT="$PROMPT Post the final output as a comment on the original PR ${INPUT_PR_NUMBER}." | |
| fi | |
| if [ -n "$INPUT_ADDITIONAL_CONTEXT" ]; then | |
| PROMPT="$PROMPT Additional reviewer instructions: ${INPUT_ADDITIONAL_CONTEXT}" | |
| fi | |
| # Write multi-line safe output | |
| { | |
| echo "prompt<<PROMPT_EOF" | |
| echo "$PROMPT" | |
| echo "PROMPT_EOF" | |
| } >> "$GITHUB_OUTPUT" | |
| # --- Allowed tools --- | |
| TOOLS="Skill" | |
| # Comment-posting tools only when NOT dry_run | |
| if [ "$INPUT_DRY_RUN" != "true" ]; then | |
| TOOLS="$TOOLS,Bash(gh pr comment:*)" | |
| TOOLS="$TOOLS,mcp__github_inline_comment__create_inline_comment" | |
| fi | |
| # Read-only PR tools (always available for workflow_dispatch) | |
| TOOLS="$TOOLS,Bash(gh pr diff:*),Bash(gh pr view:*)" | |
| # Codebase exploration tools | |
| TOOLS="$TOOLS,Read,Glob,Grep" | |
| ARGS="--model ${INPUT_MODEL:-claude-opus-4-6} --allowedTools ${TOOLS}" | |
| echo "claude_args=$ARGS" >> "$GITHUB_OUTPUT" | |
| - name: Run Claude Code | |
| uses: izaitsevfb/claude-code-action@ececd56fb999d06b4dd2477437bc408938295d76 # forked-pr-fix | |
| with: | |
| trigger_phrase: "@claude" | |
| # prompt is only set for workflow_dispatch (agent mode). | |
| # For issue_comment (tag mode), prompt must be empty so the action | |
| # uses tag mode; CLAUDE.md provides skill routing instead. | |
| prompt: ${{ steps.config.outputs.prompt || '' }} | |
| anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }} | |
| # Tool access (workflow_dispatch uses computed args from setup step): | |
| # - Skill: invoke /pr-review and /query skills | |
| # - Read,Glob,Grep: codebase exploration (used by skills) | |
| # - mcp__github_inline_comment: post inline comments (excluded in dry_run) | |
| # - Bash(gh pr comment/diff/view): gh CLI for PR data (comment excluded in dry_run) | |
| claude_args: ${{ steps.config.outputs.claude_args || '--model claude-opus-4-6 --allowedTools Skill,mcp__github_inline_comment__create_inline_comment,Read,Glob,Grep' }} | |
| settings: '{"alwaysThinkingEnabled": true}' | |
| # Notify unauthorized users who try to invoke @claude | |
| unauthorized-notice: | |
| name: Unauthorized Notice | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| pull-requests: write | |
| if: >- | |
| github.event_name == 'issue_comment' && | |
| github.event.issue.pull_request && | |
| contains(github.event.comment.body, '@claude') && | |
| !contains(fromJSON('["kgpai", "mbasmanova", "pedroerp", "yuhta", "kagamiori", "bikramSingh91", "kevinwilfong", "xiaoxmeng", "kKPulla", "juwentus1234", "penescu", "srsuryadev", "jainxrohit", "pratikpugalia"]'), github.event.comment.user.login) | |
| steps: | |
| - name: Post unauthorized notice | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: context.issue.number, | |
| body: `👋 @${context.payload.comment.user.login}, \`@claude\` commands are currently restricted to a small group of users during this initial rollout.\n\nIf you'd like a Claude review, please ask a maintainer to run this command.` | |
| }); |