Green Light Scan #18
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: Green Light Scan | |
| # Manually runs the greenlight scanner (`just review`): lists open pytorch/pytorch PRs | |
| # from trusted authors and dispatches greenlight-pr-review.yml for each new or changed | |
| # PR. Read-only on ClickHouse; dispatches the reviewer workflow via the App token. | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| pr: | |
| description: "Single pytorch/pytorch PR number to scan (empty = all trusted authors)" | |
| required: false | |
| default: "" | |
| type: string | |
| requester: | |
| description: "Login that requested this review (@greenlight recheck); must be a trusted author" | |
| required: false | |
| default: "" | |
| type: string | |
| max: | |
| description: "Max dispatches this run (empty = no cap)" | |
| required: false | |
| default: "" | |
| type: string | |
| ref: | |
| description: "Ref of greenlight-pr-review.yml to dispatch" | |
| required: false | |
| default: "main" | |
| type: string | |
| timeout_minutes: | |
| description: "In-flight / re-dispatch timeout (minutes)" | |
| required: false | |
| default: "45" | |
| type: string | |
| log_level: | |
| description: "Log verbosity" | |
| required: false | |
| default: "INFO" | |
| type: choice | |
| options: | |
| - DEBUG | |
| - INFO | |
| - WARNING | |
| - ERROR | |
| # Singleton: only one scan runs at a time, and a new dispatch waits rather than | |
| # cancelling an in-flight scan (which could leave dispatch bookkeeping half-done). | |
| concurrency: | |
| group: ${{ github.workflow }}-singleton | |
| cancel-in-progress: false | |
| permissions: | |
| contents: read | |
| id-token: write | |
| defaults: | |
| run: | |
| working-directory: greenlight | |
| # Container base (node:20-bookworm) defaults run steps to dash, which rejects | |
| # `set -o pipefail`; force bash so the existing bash-syntax steps keep working. | |
| shell: bash | |
| jobs: | |
| scan: | |
| runs-on: mt-l-x86iavx512-8-64 | |
| # OSDC ARC (kubernetes-novolume) has no host execution mode: steps run in this | |
| # container, which is the pod that receives the runner's CPU/memory. The base image | |
| # supplies node (for JS actions) + git; mise-action installs Python 3.14, uv, and just. | |
| container: | |
| image: node:20-bookworm | |
| # Protected environment holding the Green Light App key: GREENLIGHT_APP_ID and | |
| # GREENLIGHT_APP_PRIVATE_KEY. The App must be installed on pytorch/test-infra with | |
| # Actions: write and Pull requests: read so the minted token can dispatch the | |
| # reviewer workflow and read PRs across pytorch/pytorch and pytorch/test-infra. | |
| environment: greenlight-record | |
| steps: | |
| - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0 | |
| - uses: jdx/mise-action@dad1bfd3df957f44999b559dd69dc1671cb4e9ea # v4.2.1 | |
| with: | |
| working_directory: greenlight | |
| # Least privilege: the listing scan only reads PRs, so it mints a pull-requests:read token. | |
| # The --pr recheck may post a refusal comment, so it mints pull-requests:write instead. | |
| # Exactly one of these runs per invocation (keyed on whether a PR number was given); both | |
| # keep actions:write to dispatch the reviewer workflow. | |
| - name: Mint Green Light app token (read-only listing scan) | |
| id: app-token-ro | |
| if: inputs.pr == '' | |
| uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 | |
| with: | |
| app-id: ${{ secrets.GREENLIGHT_APP_ID }} | |
| private-key: ${{ secrets.GREENLIGHT_APP_PRIVATE_KEY }} | |
| owner: pytorch | |
| repositories: pytorch,test-infra | |
| permission-pull-requests: read | |
| permission-actions: write | |
| permission-contents: read | |
| permission-members: read | |
| - name: Mint Green Light app token (recheck, can comment) | |
| id: app-token-rw | |
| if: inputs.pr != '' | |
| uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 | |
| with: | |
| app-id: ${{ secrets.GREENLIGHT_APP_ID }} | |
| private-key: ${{ secrets.GREENLIGHT_APP_PRIVATE_KEY }} | |
| owner: pytorch | |
| repositories: pytorch,test-infra | |
| permission-pull-requests: write | |
| permission-actions: write | |
| permission-contents: read | |
| permission-members: read | |
| - name: Sync dependencies | |
| run: just setup | |
| # The scan PUTs an AI_REVIEW_DISPATCHED state row to S3 via boto3 the instant it fires the | |
| # reviewer workflow, so it needs the same OIDC role/arc the reviewer and record jobs use. | |
| - name: Configure AWS credentials via OIDC | |
| uses: aws-actions/configure-aws-credentials@7474bc4690e29a8392af63c5b98e7449536d5c3a # v4.3.1 | |
| with: | |
| role-to-assume: arn:aws:iam::308535385114:role/arc | |
| aws-region: us-east-1 | |
| - name: Scan and dispatch | |
| env: | |
| # Whichever token step ran (exactly one does): read-only for the listing scan, | |
| # pull-requests:write for a --pr recheck so it can post a refusal comment. | |
| PYTORCH_GREENLIGHT_GITHUB_TOKEN: ${{ steps.app-token-ro.outputs.token || steps.app-token-rw.outputs.token }} | |
| # The App's bot login (<slug>[bot]) author-scopes the recheck-refusal comment. Only the | |
| # write token step exposes app-slug, so this is empty on the read-only listing scan. | |
| BOT_LOGIN: ${{ steps.app-token-rw.outputs.app-slug && format('{0}[bot]', steps.app-token-rw.outputs.app-slug) || '' }} | |
| CLICKHOUSE_ENDPOINT: ${{ secrets.CLICKHOUSE_HUD_USER_URL }} | |
| CLICKHOUSE_USERNAME: ${{ secrets.CLICKHOUSE_HUD_USER_USERNAME }} | |
| CLICKHOUSE_PASSWORD: ${{ secrets.CLICKHOUSE_HUD_USER_PASSWORD }} | |
| IN_PR: ${{ inputs.pr }} | |
| IN_REQUESTER: ${{ inputs.requester }} | |
| IN_MAX: ${{ inputs.max }} | |
| IN_REF: ${{ inputs.ref }} | |
| IN_TIMEOUT: ${{ inputs.timeout_minutes }} | |
| IN_LOG_LEVEL: ${{ inputs.log_level }} | |
| run: | | |
| set -euo pipefail | |
| args=() | |
| if [ -n "$IN_PR" ]; then args+=(--pr "$IN_PR"); fi | |
| if [ -n "$IN_REQUESTER" ]; then args+=(--requester "$IN_REQUESTER"); fi | |
| if [ -n "$IN_MAX" ]; then args+=(--max "$IN_MAX"); fi | |
| args+=(--ref "$IN_REF" --timeout-minutes "$IN_TIMEOUT" --log-level "$IN_LOG_LEVEL") | |
| just review "${args[@]}" |