From 37117eed24c32a16afee64ffc67fd690c0bb6201 Mon Sep 17 00:00:00 2001 From: Derek Misler Date: Mon, 2 Feb 2026 13:03:03 -0500 Subject: [PATCH] Automatically run PR reviewer if author is org member --- .github/workflows/pr-review.yml | 72 +++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 3 deletions(-) diff --git a/.github/workflows/pr-review.yml b/.github/workflows/pr-review.yml index ff23a0ccf..cc86c3db1 100644 --- a/.github/workflows/pr-review.yml +++ b/.github/workflows/pr-review.yml @@ -5,6 +5,9 @@ on: types: [created] pull_request_review_comment: types: [created] + # Auto-trigger when PR becomes ready for review (supports forks) + pull_request_target: + types: [ready_for_review, opened] permissions: contents: read @@ -13,7 +16,69 @@ permissions: jobs: # ========================================================================== - # MAIN REVIEW PIPELINE + # AUTOMATIC REVIEW FOR DOCKER EMPLOYEES + # Triggers when a PR is marked ready for review or opened (non-draft) + # Only runs for Docker org members (supports fork-based workflow) + # ========================================================================== + auto-review: + if: | + github.event_name == 'pull_request_target' && + !github.event.pull_request.draft + runs-on: ubuntu-latest + + steps: + - name: Check if PR author is Docker org member + id: membership + uses: actions/github-script@f28e40c7f34bde8b3046d885e986cb6290c5673b # v7 + with: + github-token: ${{ secrets.ORG_MEMBERSHIP_TOKEN }} + script: | + const org = 'docker'; + const username = context.payload.pull_request.user.login; + + try { + await github.rest.orgs.checkMembershipForUser({ + org: org, + username: username + }); + core.setOutput('is_member', 'true'); + console.log(`✅ ${username} is a Docker org member - proceeding with auto-review`); + } catch (error) { + if (error.status === 404 || error.status === 302) { + core.setOutput('is_member', 'false'); + console.log(`⏭️ ${username} is not a Docker org member - skipping auto-review`); + } else if (error.status === 401) { + core.setFailed( + '❌ ORG_MEMBERSHIP_TOKEN secret is missing or invalid.\n\n' + + 'This secret is required to check Docker org membership for auto-reviews.\n\n' + + 'To fix this:\n' + + '1. Create a classic PAT with read:org scope at https://github.com/settings/tokens/new\n' + + '2. Add it as a repository secret named ORG_MEMBERSHIP_TOKEN:\n' + + ' gh secret set ORG_MEMBERSHIP_TOKEN --repo docker/cagent' + ); + } else { + core.setFailed(`Failed to check org membership: ${error.message}`); + } + } + + # Safe to checkout PR head because review-pr only READS files (no code execution) + - name: Checkout PR head + if: steps.membership.outputs.is_member == 'true' + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 + with: + fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha }} + + - name: Run PR Review Team + if: steps.membership.outputs.is_member == 'true' + uses: docker/cagent-action/review-pr@latest + with: + anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} + pr-number: ${{ github.event.pull_request.number }} + + # ========================================================================== + # MANUAL REVIEW PIPELINE + # Triggers when someone comments /review on a PR # ========================================================================== run-review: if: github.event.issue.pull_request && contains(github.event.comment.body, '/review') @@ -31,12 +96,13 @@ jobs: anthropic-api-key: ${{ secrets.ANTHROPIC_API_KEY }} # ========================================================================== - # LEARN FROM FEEDBACK - Process replies to agent review comments + # LEARN FROM FEEDBACK + # Processes replies to agent review comments for continuous improvement # ========================================================================== learn-from-feedback: - # Triggers when someone REPLIES to a review comment (for learning from feedback) if: github.event_name == 'pull_request_review_comment' && github.event.comment.in_reply_to_id runs-on: ubuntu-latest + steps: - name: Checkout repository uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8