Files
vercel__next.js/.github/workflows/automated_code_review.yml
Marcos Hernanz 439163392d Add automated code review workflow (#96359)
## Summary

Adds one protected `pull_request_target` workflow for advisory automated
review of non-draft, member-authored PRs.

The existing Vercel reviewer runs Codex, Claude, and synthesis with
read-only GitHub access. This base-owned workflow treats that result as
untrusted, validates it, and owns the only GitHub mutation.

## Write boundary

- no checkout, PR code execution, dependency installation, Actions
secrets, or shell interpolation
- globally empty permissions; the job has only OIDC and pull-request
read
- exact repository, event, author association, PR state, base SHA, and
head SHA validation
- final read-only PR revalidation immediately before publishing
- HTML comments stripped, mentions neutralized, token patterns redacted,
and output capped at 48 KB
- a write token is minted only after validation
- exactly one top-level comment `POST` or `PATCH`
- existing comments are eligible only when attributed to one of gh-sts's
immutable `general` GitHub App IDs and begin with the fixed marker
- both actions are pinned to immutable commit SHAs

The workflow intentionally runs once on `opened` or `ready_for_review`;
it does not run on `synchronize`.

## Validation

- `actionlint`
- Prettier
- syntax validation of all three embedded `github-script` programs
- upstream commit verification for both pinned actions
- independent Codex and Claude autoreview

The workflow remains inert until the matching gh-sts policy is approved.
2026-07-31 17:32:32 -04:00

64 lines
2.2 KiB
YAML

name: Automated Code Review
# This privileged workflow runs only from protected canary. It checks out the
# base commit that triggered the workflow, never pull-request code. Vercel
# computes an untrusted review; this workflow validates it and owns the sole
# GitHub mutation.
on:
pull_request_target:
types: [opened, ready_for_review]
permissions: {}
concurrency:
group: automated-code-review-${{ github.event.pull_request.number }}
cancel-in-progress: false
jobs:
review:
if: >-
github.repository == 'vercel/next.js' &&
github.event.pull_request.author_association == 'MEMBER' &&
github.event.pull_request.draft == false
runs-on: ubuntu-latest
timeout-minutes: 55
permissions:
contents: read
id-token: write
pull-requests: read
steps:
- name: Checkout trusted workflow code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
ref: ${{ github.sha }}
persist-credentials: false
sparse-checkout: .github/scripts/automated_code_review.js
sparse-checkout-cone-mode: false
- name: Prepare review comment
id: prepare
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with:
script: |
const { prepareReviewComment } = require("./.github/scripts/automated_code_review.js");
await prepareReviewComment({ core, github, context });
- name: Mint comment token
if: steps.prepare.outputs.publish == 'true'
id: gh-sts
uses: vercel/gh-sts-action@c30f0b7a16e0766c4ffbc0d210b54d0e75053fd2 # v1.0.2
with:
repos: vercel/next.js
permissions: '{"pull_requests":"write"}'
- name: Publish one review comment
if: steps.prepare.outputs.publish == 'true'
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
env:
READ_TOKEN: ${{ github.token }}
with:
github-token: ${{ steps.gh-sts.outputs.token }}
script: |
const { publishReviewComment } = require("./.github/scripts/automated_code_review.js");
await publishReviewComment({ core, github });