From 2c194eb0768fe64c6de579105f21de856c2dc96a Mon Sep 17 00:00:00 2001 From: Liang-Chi Hsieh Date: Fri, 29 May 2026 13:20:25 -0700 Subject: [PATCH] [SPARK-57155][INFRA] Fix `update_build_status` check-run pagination and output parsing ### What changes were proposed in this pull request? Two robustness fixes to the scheduled `update_build_status.yml` workflow: 1. List a commit's check-runs with `github.paginate(..., per_page: 100)` instead of a single un-paginated `github.request`, matching `notify_test_workflow.yml`. The default page size is 30, so the target `Build` check could fall off the first page on a SHA that accumulates more check-runs than that (CI matrix, external checks, duplicate `Build` checks from reopened PRs). 2. Wrap `JSON.parse(cr.output.text)` in try/catch and `continue` on failure. A `Build` check created by something other than this mechanism (an older version, a manual run, or another app), or one with empty output text, would otherwise throw inside the loop and abort the whole scheduled run. ### Why are the changes needed? Both issues silently block status updates. If the `Build` check is paginated off the first page, the PR stays stuck in `queued` forever because the updater never sees it. If an unparseable `Build` check is encountered, the uncaught exception aborts the run and blocks updates for every PR queued behind it that cycle. ### Does this PR introduce _any_ user-facing change? No. CI infrastructure only. ### How was this patch tested? Static verification: the embedded `actions/github-script` body passes `node --check`, and the workflow YAML parses. Note `github.paginate` returns a flat array, so the iteration was updated from `checkRuns.data.check_runs` to `checkRuns`. ### Was this patch authored or co-authored using generative AI tooling? Generated-by: Claude Code (Claude Opus 4.8) Co-authored-by: Claude Code --- .github/workflows/update_build_status.yml | 36 ++++++++++++++++++----- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/.github/workflows/update_build_status.yml b/.github/workflows/update_build_status.yml index 26ab78fbee1a..6b16c59ce6ac 100644 --- a/.github/workflows/update_build_status.yml +++ b/.github/workflows/update_build_status.yml @@ -53,17 +53,37 @@ jobs: console.log('SHA: ' + pr.head.sha) console.log(' Mergeable status: ' + pr.mergeable_state) if (pr.mergeable_state == null || maybeReady.includes(pr.mergeable_state)) { - const checkRuns = await github.request('GET /repos/{owner}/{repo}/commits/{ref}/check-runs', { - owner: context.repo.owner, - repo: context.repo.repo, - ref: pr.head.sha - }) + // Paginate with per_page=100 to match notify_test_workflow.yml. The default + // page size is 30, and a SHA can accumulate more check-runs than that (CI + // matrix, external checks, duplicate Build checks from reopened PRs), which + // could push the target Build check off the first page and leave the PR + // stuck in 'queued' forever. + const checkRuns = await github.paginate( + 'GET /repos/{owner}/{repo}/commits/{ref}/check-runs', + { + owner: context.repo.owner, + repo: context.repo.repo, + ref: pr.head.sha, + per_page: 100 + } + ) // Iterator GitHub Checks in the PR - for await (const cr of checkRuns.data.check_runs) { + for await (const cr of checkRuns) { if (cr.name == 'Build' && cr.conclusion != "action_required") { - // text contains parameters to make request in JSON. - const params = JSON.parse(cr.output.text) + // text contains parameters to make request in JSON. A Build check + // created by something other than notify_test_workflow.yml (an older + // version, a manual run, or another app) may have empty or malformed + // output text; skip it instead of aborting the whole scheduled run, + // which would block updates for every PR queued behind it. + let params + try { + params = JSON.parse(cr.output.text) + } catch (error) { + console.error('Skipping Build check ' + cr.id + ' with unparseable output text') + console.error(error) + continue + } // Get the workflow run in the forked repository let run