11name : " Plot: Review"
2- run-name : " Review: ${{ github.event.workflow_run.head_branch || github.event. pull_request.head.ref }}"
2+ run-name : " Review: ${{ github.event.pull_request.head.ref }}"
33
4- # Triggers when plot-generator creates a PR (via workflow_run)
4+ # Triggers when a PR is opened/updated from auto/* branches
55# Reviews the implementation quality using AI
66
77on :
8- workflow_run :
9- workflows : ["Plot: Generator"]
10- types : [completed]
8+ pull_request :
9+ types : [opened, synchronize]
10+ branches :
11+ - ' plot/**' # PRs targeting feature branches
1112
1213jobs :
1314 ai-review :
14- # Only run if generator was successful
15- if : github.event.workflow_run.conclusion == 'success'
15+ # Only run for auto/* branches (generated implementations)
16+ if : startsWith( github.event.pull_request.head.ref, 'auto/')
1617 runs-on : ubuntu-latest
1718 permissions :
1819 contents : read
@@ -22,67 +23,28 @@ jobs:
2223 actions : write
2324
2425 steps :
25- - name : Check conditions
26- id : check
27- env :
28- HEAD_REPO : ${{ github.event.workflow_run.head_repository.full_name }}
29- BASE_REPO : ${{ github.repository }}
30- run : |
31- # Security: Skip if workflow run is from a fork (untrusted code)
32- if [[ "$HEAD_REPO" != "$BASE_REPO" ]]; then
33- echo "::notice::Skipping: Workflow run is from fork '$HEAD_REPO', not '$BASE_REPO'"
34- echo "should_run=false" >> $GITHUB_OUTPUT
35- exit 0
36- fi
37-
38- echo "should_run=true" >> $GITHUB_OUTPUT
39-
40- - name : Checkout code
41- if : steps.check.outputs.should_run == 'true'
42- uses : actions/checkout@v6
43- with :
44- fetch-depth : 0
45-
46- - name : Get PR from workflow run
47- if : steps.check.outputs.should_run == 'true'
26+ - name : Extract PR info
4827 id : get_pr
4928 env :
50- GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
29+ HEAD_REF : ${{ github.event.pull_request.head.ref }}
30+ PR_NUMBER : ${{ github.event.pull_request.number }}
5131 run : |
52- HEAD_BRANCH="${{ github.event.workflow_run.head_branch }}"
53-
54- # Get PR for this branch
55- PR_DATA=$(gh pr list --head "$HEAD_BRANCH" --json number,headRefName,baseRefName --limit 1)
56-
57- if [ -z "$PR_DATA" ] || [ "$PR_DATA" = "[]" ]; then
58- echo "::notice::No PR found for branch $HEAD_BRANCH"
59- echo "skip=true" >> $GITHUB_OUTPUT
60- exit 0
61- fi
62-
63- PR_NUMBER=$(echo "$PR_DATA" | jq -r '.[0].number')
64- HEAD_REF=$(echo "$PR_DATA" | jq -r '.[0].headRefName')
65-
66- # Check if auto/ branch (format: auto/{spec-id}/{library})
67- if [[ ! "$HEAD_REF" =~ ^auto/ ]]; then
68- echo "::notice::Not an auto/ branch, skipping AI review"
69- echo "skip=true" >> $GITHUB_OUTPUT
70- exit 0
71- fi
72-
73- # Extract spec-id and library from branch name
32+ # Extract spec-id and library from branch name (auto/{spec-id}/{library})
7433 SPEC_ID=$(echo "$HEAD_REF" | cut -d'/' -f2)
7534 LIBRARY=$(echo "$HEAD_REF" | cut -d'/' -f3)
7635
7736 echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
7837 echo "spec_id=$SPEC_ID" >> $GITHUB_OUTPUT
7938 echo "library=$LIBRARY" >> $GITHUB_OUTPUT
80- echo "skip=false" >> $GITHUB_OUTPUT
8139
82- echo "::notice::Found PR #$PR_NUMBER for $LIBRARY implementation of $SPEC_ID"
40+ echo "::notice::PR #$PR_NUMBER for $LIBRARY implementation of $SPEC_ID"
41+
42+ - name : Checkout code
43+ uses : actions/checkout@v6
44+ with :
45+ fetch-depth : 0
8346
8447 - name : Get main issue number from PR
85- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true'
8648 id : issue
8749 env :
8850 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
@@ -99,19 +61,18 @@ jobs:
9961 echo "issue_number=$ISSUE_NUMBER" >> $GITHUB_OUTPUT
10062
10163 - name : Setup Google Cloud authentication
102- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true'
10364 id : gcs_auth
10465 continue-on-error : true
10566 uses : google-github-actions/auth@v3
10667 with :
10768 credentials_json : ${{ secrets.GCS_SA_KEY }}
10869
10970 - name : Setup gcloud CLI
110- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. gcs_auth.outcome == 'success'
71+ if : steps.gcs_auth.outcome == 'success'
11172 uses : google-github-actions/setup-gcloud@v3
11273
11374 - name : Download plot images from GCS staging
114- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. gcs_auth.outcome == 'success'
75+ if : steps.gcs_auth.outcome == 'success'
11576 run : |
11677 SPEC_ID="${{ steps.get_pr.outputs.spec_id }}"
11778 LIBRARY="${{ steps.get_pr.outputs.library }}"
12586 ls -la plot_images/ 2>/dev/null || echo "No images found"
12687
12788 - name : Check attempt count
128- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true'
12989 id : attempts
13090 env :
13191 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
@@ -150,7 +110,7 @@ jobs:
150110 fi
151111
152112 - name : React with eyes emoji
153- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count != '3'
113+ if : steps.attempts.outputs.count != '3'
154114 env :
155115 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
156116 PR_NUMBER : ${{ steps.get_pr.outputs.pr_number }}
@@ -160,7 +120,7 @@ jobs:
160120
161121 - name : Run Claude AI Quality Review
162122 id : claude_review
163- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count != '3'
123+ if : steps.attempts.outputs.count != '3'
164124 continue-on-error : true
165125 timeout-minutes : 30
166126 uses : anthropics/claude-code-action@v1
@@ -236,7 +196,7 @@ jobs:
236196
237197 - name : Extract and save quality score
238198 id : score
239- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count != '3' && steps.claude_review.outcome == 'success'
199+ if : steps.attempts.outputs.count != '3' && steps.claude_review.outcome == 'success'
240200 env :
241201 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
242202 run : |
@@ -276,15 +236,15 @@ jobs:
276236 cat review_results/${LIBRARY}.json
277237
278238 - name : Upload review result artifact
279- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count != '3' && steps.claude_review.outcome == 'success'
239+ if : steps.attempts.outputs.count != '3' && steps.claude_review.outcome == 'success'
280240 uses : actions/upload-artifact@v5
281241 with :
282242 name : review-${{ steps.get_pr.outputs.spec_id }}-${{ steps.get_pr.outputs.library }}
283243 path : review_results/
284244 retention-days : 7
285245
286246 - name : Handle Claude failure
287- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count != '3' && (steps.claude_review.outcome == 'failure' || steps.claude_review.outcome == 'cancelled')
247+ if : steps.attempts.outputs.count != '3' && (steps.claude_review.outcome == 'failure' || steps.claude_review.outcome == 'cancelled')
288248 env :
289249 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
290250 PR_NUM : ${{ steps.get_pr.outputs.pr_number }}
@@ -306,7 +266,7 @@ jobs:
306266 :robot: *Automated notification*"
307267
308268 - name : Trigger auto-merge if approved
309- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count != '3' && steps.claude_review.outcome == 'success'
269+ if : steps.attempts.outputs.count != '3' && steps.claude_review.outcome == 'success'
310270 env :
311271 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
312272 PR_NUM : ${{ steps.get_pr.outputs.pr_number }}
@@ -322,7 +282,7 @@ jobs:
322282 fi
323283
324284 - name : Mark as failed after 3 attempts
325- if : steps.check.outputs.should_run == 'true' && steps.get_pr.outputs.skip != 'true' && steps. attempts.outputs.count == '3'
285+ if : steps.attempts.outputs.count == '3'
326286 env :
327287 GH_TOKEN : ${{ secrets.GITHUB_TOKEN }}
328288 PR_NUM : ${{ steps.get_pr.outputs.pr_number }}
0 commit comments