From 09b7af13717363bc87ac37fb082b7ed359aed2ce Mon Sep 17 00:00:00 2001 From: Michael <13900043+michaelzhang-ai@users.noreply.github.com> Date: Wed, 19 Aug 2026 22:18:30 -0700 Subject: [PATCH] [CI] Surface AMD ROCm 7.2 state in the PR CI-states block (#34813) Co-authored-by: Michael Co-authored-by: Chen --- .github/workflows/pr-states.yml | 54 ++++++++++++++++++++++++++------- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/.github/workflows/pr-states.yml b/.github/workflows/pr-states.yml index 1af84dad4..3a6da1eff 100644 --- a/.github/workflows/pr-states.yml +++ b/.github/workflows/pr-states.yml @@ -5,19 +5,16 @@ name: PR States # # Three triggers, each covering a gap: # - pull_request_target: push / open / label change (all PRs incl forks). -# - workflow_run: initial pr-test* completion (incl fork PRs; the -# notify-job below can't fire on forks — their pull_request -# GITHUB_TOKEN is forced read-only). Does NOT re-fire for rerun -# attempts, which is why workflow_dispatch is needed too. -# - workflow_dispatch: rerun completions for non-fork PRs, dispatched by -# pr-test*'s notify-pr-states job. workflow_dispatch is the only event -# GITHUB_TOKEN can cascade-create. +# - workflow_run: pr-test* requested / completed events (incl fork PRs). +# `requested` is absent on reruns, but `completed` still fires. +# - workflow_dispatch: explicit refreshes for a provided PR number. This +# is the only event here that GITHUB_TOKEN can cascade-create. on: pull_request_target: types: [opened, synchronize, reopened, labeled, unlabeled] workflow_run: - workflows: ["PR Test Base", "PR Test Extra"] + workflows: ["PR Test Base", "PR Test Extra", "PR Test ROCm 7.2 (AMD)"] types: [requested, completed] workflow_dispatch: inputs: @@ -63,6 +60,14 @@ jobs: prNumber = context.payload.pull_request.number; } else if (context.eventName === 'workflow_run') { const wr = context.payload.workflow_run; + // Only pull_request runs are the PR gate. The AMD workflow also + // accepts workflow_dispatch for a single stage, and such a run on + // a PR branch is PR-associated; refreshing off it would rewrite + // the block from a run the rows below deliberately ignore. + if (wr.event !== 'pull_request') { + core.info(`Triggering run event '${wr.event}' is not pull_request; skipping.`); + return; + } if (wr.pull_requests && wr.pull_requests.length > 0) { prNumber = wr.pull_requests[0].number; } else if (wr.head_repository && wr.head_branch) { @@ -119,6 +124,10 @@ jobs: repo: context.repo.repo, workflow_id: workflowFile, head_sha: sha, + // Every row reports the PR gate, so exclude other events for + // this SHA: all three workflows also accept workflow_dispatch, + // and for AMD that is a single stage rather than the full gate. + event: 'pull_request', per_page: 1, }); return data.workflow_runs[0] || null; @@ -140,9 +149,22 @@ jobs: // on just-removed-label to catch removal-after-push. const labelOnOpts = { preSleepMs: LABEL_ON_PRESLEEP_MS, attempts: RETRY_ATTEMPTS, delayMs: RETRY_DELAY_MS }; const labelOffOpts = { preSleepMs: justRemovedLabel ? LABEL_OFF_PRESLEEP_MS : 0, attempts: 1 }; - const ptRun = await findRun('pr-test.yml', hasCI ? labelOnOpts : labelOffOpts); - // pr-test-extra gates on BOTH labels (see check-changes there). - const peRun = await findRun('pr-test-extra.yml', (hasCI && hasExtra) ? labelOnOpts : labelOffOpts); + + // The three lookups are independent, so the added one costs no + // wall-clock time. The AMD lookup never spends the retry budget: + // that workflow has an on.pull_request.paths filter, so a missing + // run is usually legitimate rather than an indexing race, and the + // race resolves itself -- `requested` is in the workflow_run + // subscription above, so a real dispatch refreshes this block. + const [ptRun, peRun, amdRun] = await Promise.all([ + findRun('pr-test.yml', hasCI ? labelOnOpts : labelOffOpts), + // pr-test-extra gates on BOTH labels (see check-changes there). + findRun( + 'pr-test-extra.yml', + (hasCI && hasExtra) ? labelOnOpts : labelOffOpts, + ), + findRun('pr-test-amd-rocm720.yml', labelOffOpts), + ]); // Skipped run = "no real run" -- happens when a label is added // after a commit, because GHA doesn't retrigger on `labeled`. @@ -152,6 +174,10 @@ jobs: const peBlockedByCIText = ':x: **Blocked** -- `run-ci` is required first.'; const notExtraEnabledText = ':warning: **Not enabled** -- add `run-ci-extra` label to opt in.'; const stalePushText = ':warning: **Not run on latest push** -- push again to dispatch.'; + // A missing run usually means the paths filter excluded the PR, + // but pull_request workflows can also be suppressed by GitHub + // (for example, for merge conflicts or skip annotations). + const amdNotTriggeredText = ':heavy_minus_sign: **No AMD PR run found for this commit**.'; // Status icon: body otherwise looks uniformly "dispatched" even // for gate-failed runs (call-gate exits on missing label). @@ -178,6 +204,9 @@ jobs: : !hasExtra ? notExtraEnabledText : stalePushText; + const amdText = isReal(amdRun) + ? runLink(amdRun) + : amdNotTriggeredText; const outerStart = ''; const outerEnd = ''; @@ -185,6 +214,8 @@ jobs: const ptEnd = ''; const peStart = ''; const peEnd = ''; + const amdStart = ''; + const amdEnd = ''; const newBlock = [ outerStart, @@ -193,6 +224,7 @@ jobs: '', `Latest PR Test (Base): ${ptStart}${ptText}${ptEnd}`, `Latest PR Test (Extra): ${peStart}${peText}${peEnd}`, + `Latest PR Test (AMD ROCm 7.2): ${amdStart}${amdText}${amdEnd}`, outerEnd, ].join('\n');