From e9ca8db16819fdad78f03d63d674c5cf0bc76c95 Mon Sep 17 00:00:00 2001 From: Brian O'Kelley Date: Thu, 28 May 2026 04:30:39 -0400 Subject: [PATCH] fix(argus): support fork PR reviews safely --- .github/workflows/ai-review.yml | 34 ++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/.github/workflows/ai-review.yml b/.github/workflows/ai-review.yml index 3f780d6f..e1a097b0 100644 --- a/.github/workflows/ai-review.yml +++ b/.github/workflows/ai-review.yml @@ -20,7 +20,7 @@ name: AI PR Review (Argus) # upstream is surfaced weekly by sync-argus-upstream-check.yml. on: - pull_request: + pull_request_target: types: - opened - labeled @@ -40,8 +40,13 @@ jobs: pull-requests: write id-token: write steps: + # This workflow uses pull_request_target so fork PRs can access the + # review App token and Anthropic secret. Never check out the PR head or + # execute PR-controlled code in this job. Keep the workspace pinned to the + # trusted base SHA and inspect the PR through GitHub APIs / gh pr diff. - uses: actions/checkout@v4 with: + ref: ${{ github.event.pull_request.base.sha }} fetch-depth: 0 # ───────────────────────────────────────────────────────────────────── @@ -147,18 +152,11 @@ jobs: echo "No prior bot APPROVED review — running full review." exit 0 fi - if ! git cat-file -e "$PRIOR_SHA" 2>/dev/null; then - git fetch --quiet origin "$PRIOR_SHA" 2>/dev/null || true - fi - if ! git cat-file -e "$PRIOR_SHA" 2>/dev/null; then - echo "skip=false" >> "$GITHUB_OUTPUT" - echo "Prior review SHA $PRIOR_SHA unreachable (likely force-pushed) — running full review." - exit 0 - fi - CHANGED="$(git diff --name-only "$PRIOR_SHA" "$HEAD_SHA")" + CHANGED="$(gh api "/repos/${REPO}/compare/${PRIOR_SHA}...${HEAD_SHA}" \ + --jq '.files[]?.filename' 2>/dev/null || true)" if [ -z "$CHANGED" ]; then - echo "skip=true" >> "$GITHUB_OUTPUT" - echo "No file changes since prior approval at $PRIOR_SHA — skipping." + echo "skip=false" >> "$GITHUB_OUTPUT" + echo "Could not compare $PRIOR_SHA...$HEAD_SHA (likely force-pushed or fork edge case) — running full review." exit 0 fi # Trivial paths in adcp-go — re-pushes touching only these skip re-review. @@ -197,12 +195,18 @@ jobs: env: PR_NUMBER: ${{ github.event.pull_request.number }} PR_BASE_REF: ${{ github.event.pull_request.base.ref }} + BASE_SHA: ${{ github.event.pull_request.base.sha }} REPO: ${{ github.repository }} run: | set -euo pipefail - PROMPT_BODY="$(cat .github/ai-review/expert-adcp-reviewer.md)" + if ! git cat-file -e "${BASE_SHA}:.github/ai-review/expert-adcp-reviewer.md" 2>/dev/null; then + echo "::error::Prompt file does not exist at base SHA ${BASE_SHA}. Self-modification gate should have caught this." + exit 1 + fi + PROMPT_BODY="$(git show "${BASE_SHA}:.github/ai-review/expert-adcp-reviewer.md")" + SENTINEL="ARGUS_$(openssl rand -hex 8)_EOF" { - echo 'ARGUS_PROMPT<> "$GITHUB_OUTPUT" - name: Run Argus PR Review