SK: 2832 Added Claude Code setup for Java #12
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: Claude PR Review | |
| on: | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'src/**/*.java' | |
| workflow_dispatch: | |
| inputs: | |
| pr_number: | |
| description: 'PR number to re-run review on' | |
| required: false | |
| permissions: | |
| pull-requests: write | |
| contents: read | |
| jobs: | |
| sdk-review: | |
| name: SDK Review (patterns + smell + security) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 20 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Install Claude CLI | |
| run: npm install -g @anthropic-ai/claude-code | |
| - name: Check for non-generated Java changes | |
| id: check | |
| run: | | |
| CHANGED=$(git diff --name-only origin/${{ github.base_ref }}...HEAD \ | |
| | grep '\.java$' | grep -v 'generated') | |
| if [ -z "$CHANGED" ]; then | |
| echo "has_changes=false" >> $GITHUB_OUTPUT | |
| else | |
| echo "has_changes=true" >> $GITHUB_OUTPUT | |
| LINES=$(git diff origin/${{ github.base_ref }}...HEAD -- '*.java' \ | |
| | grep -c '^[+-][^+-]' 2>/dev/null || echo 1) | |
| echo "changed_lines=$LINES" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Verify Claude CLI | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| run: | | |
| echo "Claude version: $(claude --version)" | |
| set +e | |
| TEST=$(claude --dangerously-skip-permissions --output-format json -p "Reply with only the word: WORKING" 2>&1) | |
| EXIT=$? | |
| set -e | |
| echo "Exit code: $EXIT" | |
| echo "Output: $TEST" | |
| - name: Run code review | |
| if: steps.check.outputs.has_changes == 'true' | |
| id: review | |
| continue-on-error: true | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" | |
| GITHUB_BASE_REF: ${{ github.base_ref }} | |
| GITHUB_ACTIONS: "true" | |
| run: | | |
| RAW=$(claude --dangerously-skip-permissions --output-format json --model claude-sonnet-4-6 -p "/code-review" 2>&1) | |
| RESULT=$(echo "$RAW" | jq -r '.result // "_Review failed to produce output._"') | |
| INPUT_TOK=$(echo "$RAW" | jq '[.modelUsage[].inputTokens // 0] | add // 0') | |
| OUTPUT_TOK=$(echo "$RAW" | jq '[.modelUsage[].outputTokens // 0] | add // 0') | |
| CACHED_TOK=$(echo "$RAW" | jq '[.modelUsage[].cacheReadInputTokens // 0] | add // 0') | |
| COST=$(echo "$RAW" | jq -r '.total_cost_usd // 0') | |
| LINES="${{ steps.check.outputs.changed_lines }}" | |
| echo "result<<EOF" >> $GITHUB_OUTPUT | |
| echo "$RESULT" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| { | |
| echo "## Token Usage — SDK Review" | |
| echo "| Metric | Value |" | |
| echo "|--------|-------|" | |
| echo "| Input tokens | $INPUT_TOK |" | |
| echo "| Output tokens | $OUTPUT_TOK |" | |
| echo "| Cache hits | $CACHED_TOK |" | |
| echo "| Total cost | \$$COST |" | |
| echo "| Changed lines | $LINES |" | |
| } >> $GITHUB_STEP_SUMMARY | |
| - name: Post review comment | |
| if: steps.check.outputs.has_changes == 'true' | |
| uses: actions/github-script@v7 | |
| env: | |
| REVIEW_BODY: ${{ steps.review.outputs.result }} | |
| with: | |
| script: | | |
| const review = process.env.REVIEW_BODY || '_Review output unavailable._'; | |
| await github.rest.issues.createComment({ | |
| ...context.repo, | |
| issue_number: context.payload.pull_request.number, | |
| body: `## Claude SDK Review\n\n${review}` | |
| }); | |
| security-review: | |
| name: Security Review (serviceaccount changes) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Check for serviceaccount changes | |
| id: filter | |
| uses: dorny/paths-filter@v3 | |
| with: | |
| filters: | | |
| serviceaccount: | |
| - 'src/**/serviceaccount/**/*.java' | |
| - name: Install Claude CLI | |
| if: steps.filter.outputs.serviceaccount == 'true' | |
| run: npm install -g @anthropic-ai/claude-code | |
| - name: Get changed serviceaccount files | |
| if: steps.filter.outputs.serviceaccount == 'true' | |
| id: sa-files | |
| run: | | |
| FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD \ | |
| | grep 'serviceaccount' | grep '\.java$' | tr '\n' ' ') | |
| echo "files=$FILES" >> $GITHUB_OUTPUT | |
| - name: Run security audit | |
| if: steps.filter.outputs.serviceaccount == 'true' && steps.sa-files.outputs.files != '' | |
| id: security | |
| continue-on-error: true | |
| env: | |
| ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} | |
| CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC: "1" | |
| GITHUB_BASE_REF: ${{ github.base_ref }} | |
| GITHUB_ACTIONS: "true" | |
| SA_FILES: ${{ steps.sa-files.outputs.files }} | |
| run: | | |
| RAW=$(claude --dangerously-skip-permissions --output-format json --model claude-sonnet-4-6 \ | |
| -p "/code-security $SA_FILES") | |
| RESULT=$(echo "$RAW" | jq -r '.result // "_Audit failed to produce output._"') | |
| INPUT_TOK=$(echo "$RAW" | jq '[.modelUsage[].inputTokens // 0] | add // 0') | |
| OUTPUT_TOK=$(echo "$RAW" | jq '[.modelUsage[].outputTokens // 0] | add // 0') | |
| CACHED_TOK=$(echo "$RAW" | jq '[.modelUsage[].cacheReadInputTokens // 0] | add // 0') | |
| COST=$(echo "$RAW" | jq -r '.total_cost_usd // 0') | |
| echo "result<<EOF" >> $GITHUB_OUTPUT | |
| echo "$RESULT" >> $GITHUB_OUTPUT | |
| echo "EOF" >> $GITHUB_OUTPUT | |
| { | |
| echo "## Token Usage — Security Audit" | |
| echo "| Metric | Value |" | |
| echo "|--------|-------|" | |
| echo "| Input tokens | $INPUT_TOK |" | |
| echo "| Output tokens | $OUTPUT_TOK |" | |
| echo "| Cache hits | $CACHED_TOK |" | |
| echo "| Total cost | \$$COST |" | |
| } >> $GITHUB_STEP_SUMMARY | |
| - name: Post security comment | |
| if: steps.filter.outputs.serviceaccount == 'true' && steps.sa-files.outputs.files != '' | |
| uses: actions/github-script@v7 | |
| env: | |
| AUDIT_BODY: ${{ steps.security.outputs.result }} | |
| SA_FILES: ${{ steps.sa-files.outputs.files }} | |
| with: | |
| script: | | |
| const audit = process.env.AUDIT_BODY || '_Audit output unavailable._'; | |
| const files = process.env.SA_FILES; | |
| await github.rest.issues.createComment({ | |
| ...context.repo, | |
| issue_number: context.payload.pull_request.number, | |
| body: `## Claude Security Audit (serviceaccount)\n\n${audit}\n\n---\n_Files audited: \`${files}\`_` | |
| }); |