diff --git a/.github/workflows/claude-code.yml b/.github/workflows/claude-code.yml new file mode 100644 index 0000000000..55151d9f55 --- /dev/null +++ b/.github/workflows/claude-code.yml @@ -0,0 +1,117 @@ +name: Claude Code + +# AI-assisted PR reviews and interactive @claude mentions. +# +# The actual Claude Code execution runs in eng-dev-ecosystem on +# protected runners whose IPs are allowlisted by the Databricks +# account IP ACL. This workflow is a thin trigger that dispatches +# to eng-dev-ecosystem via the DECO workflow trigger GitHub App. + +on: + pull_request: + types: [opened] + + issue_comment: + types: [created] + + pull_request_review_comment: + types: [created] + +jobs: + # Automatic review on PR open. For re-reviews, comment "@claude review". + # Restrict to collaborators/members/owners to prevent untrusted users + # (e.g. external fork PRs) from consuming model serving resources. See: + # https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/ + review: + if: | + github.event_name == 'pull_request' && + contains(fromJson('["COLLABORATOR","MEMBER","OWNER"]'), github.event.pull_request.author_association) + concurrency: + group: claude-review-${{ github.event.pull_request.number }} + cancel-in-progress: true + runs-on: + group: databricks-deco-testing-runner-group + labels: ubuntu-latest-deco + environment: test-trigger-is + permissions: + contents: read + + steps: + - name: Generate GitHub App token + id: token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.DECO_WORKFLOW_TRIGGER_APP_ID }} + private-key: ${{ secrets.DECO_WORKFLOW_TRIGGER_PRIVATE_KEY }} + owner: databricks-eng + repositories: eng-dev-ecosystem + + - name: Trigger Claude Code review + run: | + gh workflow run cli-claude-code.yml \ + -R databricks-eng/eng-dev-ecosystem \ + --ref main \ + -F pull_request_number=${{ github.event.pull_request.number }} \ + -F event_type=review + env: + GH_TOKEN: ${{ steps.token.outputs.token }} + + # Interactive @claude mentions (PRs only, trusted authors only). + # Restrict to collaborators/members/owners to prevent untrusted users from + # triggering Claude with write access to the repo. See: + # https://securitylab.github.com/resources/github-actions-preventing-pwn-requests/ + assist: + if: | + github.event.comment.user.type != 'Bot' && + contains(fromJson('["COLLABORATOR","MEMBER","OWNER"]'), github.event.comment.author_association) && + ( + (github.event_name == 'issue_comment' && github.event.issue.pull_request && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) + ) + runs-on: + group: databricks-deco-testing-runner-group + labels: ubuntu-latest-deco + environment: test-trigger-is + permissions: + contents: read + + steps: + - name: Generate GitHub App token + id: token + uses: actions/create-github-app-token@v2 + with: + app-id: ${{ secrets.DECO_WORKFLOW_TRIGGER_APP_ID }} + private-key: ${{ secrets.DECO_WORKFLOW_TRIGGER_PRIVATE_KEY }} + owner: databricks-eng + repositories: eng-dev-ecosystem + + - name: Determine PR number + id: pr + run: | + if [ -n "$ISSUE_NUMBER" ]; then + echo "number=$ISSUE_NUMBER" >> "$GITHUB_OUTPUT" + else + echo "number=$PR_NUMBER" >> "$GITHUB_OUTPUT" + fi + env: + ISSUE_NUMBER: ${{ github.event.issue.number }} + PR_NUMBER: ${{ github.event.pull_request.number }} + + - name: Trigger Claude Code assist + uses: actions/github-script@v7 + with: + github-token: ${{ steps.token.outputs.token }} + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: 'databricks-eng', + repo: 'eng-dev-ecosystem', + workflow_id: 'cli-claude-code.yml', + ref: 'main', + inputs: { + pull_request_number: '${{ steps.pr.outputs.number }}', + event_type: 'assist', + comment_body: process.env.COMMENT_BODY + } + }); + env: + COMMENT_BODY: ${{ github.event.comment.body }} diff --git a/.github/workflows/claude.yml b/.github/workflows/claude.yml new file mode 100644 index 0000000000..a7f76a022b --- /dev/null +++ b/.github/workflows/claude.yml @@ -0,0 +1,84 @@ +name: Claude + +# AI-assisted PR reviews and interactive @claude mentions. +# This workflow delegates to the reusable claude-code.yml workflow +# which handles authentication and execution. + +on: + pull_request: + types: [opened, synchronize, reopened] + + issue_comment: + types: [created] + + pull_request_review_comment: + types: [created] + +jobs: + review: + if: github.event_name == 'pull_request' + uses: ./.github/workflows/claude-code.yml + with: + prompt: | + Review this PR. Focus on correctness, error handling, and adherence to the project's Go conventions documented in CLAUDE.md. + + You MUST post all code-specific feedback as inline comments using the mcp__github_inline_comment__create_inline_comment tool. For each issue you find, call this tool with the file path, line number, and your comment. Always set confirmed: true. Do NOT put code-level feedback in a summary comment. + + After posting all inline comments, write a brief summary to a temporary file and post it with: pr-comment --body-file . The summary should only list the number of inline comments posted and a one-line overview. If you have no issues to raise, just post a short comment saying the PR looks good. + allowed_tools: | + mcp__github_inline_comment__create_inline_comment + Bash(pr-diff) + Bash(pr-diff *) + Bash(pr-view) + Bash(pr-view *) + Bash(pr-comment *) + Bash(git log) + Bash(git log *) + Bash(git diff) + Bash(git diff *) + Bash(git show *) + Bash(grep *) + Read + Write + Glob + Grep + claude_args: '--max-turns 100 --allowedTools "mcp__github_inline_comment__create_inline_comment"' + + assist: + if: | + (github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) || + (github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) + uses: ./.github/workflows/claude-code.yml + with: + allowed_tools: | + mcp__github_ci__get_ci_status + mcp__github_ci__get_workflow_run_details + mcp__github_ci__download_job_log + Bash(make lint) + Bash(make test) + Bash(make fmt) + Bash(make schema) + Bash(go build *) + Bash(go test *) + Bash(go vet) + Bash(go vet *) + Bash(git add *) + Bash(git commit *) + Bash(pr-push) + Bash(pr-push *) + Bash(git diff) + Bash(git diff *) + Bash(git log) + Bash(git log *) + Bash(git status) + Bash(git show *) + Bash(pr-comment *) + Bash(pr-view) + Bash(pr-view *) + Bash(grep *) + Read + Edit + Write + Glob + Grep + claude_args: "--max-turns 100"