Skip to content

Commit 3ba53df

Browse files
authored
Fix pr-status script missing failed jobs on page 2+ of API results (#91087)
## Summary `getFailedJobs()` in `scripts/pr-status.js` used jq's `select(.conclusion == "failure")` filter during GitHub API pagination. When a page had 100 jobs but none were failures, jq returned empty output, and the `if (!output.trim()) break` check terminated the pagination loop early — never fetching page 2+ where actual failures existed. For example, on PR #90755 (129 total jobs), all 100 jobs on page 1 were success/skipped, while the 2 failures (`test unit windows (22) / build` and `thank you, next`) were on page 2 (jobs 101-129). The script reported "Found 0 failed jobs" when there were actually 2. ## Fix `getFailedJobs()` now delegates to `getAllJobs()` (which fetches all jobs without jq filtering, so pagination works correctly) and filters for failures in JavaScript afterward. This is simpler and avoids the class of bug where jq pre-filtering interacts badly with pagination. ## Test Plan - Ran `node scripts/pr-status.js 90755` before fix: reported 0 failed jobs - Ran `node scripts/pr-status.js 90755` after fix: correctly reported 2 failed jobs (`test unit windows (22) / build` and `thank you, next`)
1 parent 5e965bb commit 3ba53df

1 file changed

Lines changed: 8 additions & 28 deletions

File tree

scripts/pr-status.js

Lines changed: 8 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -217,34 +217,14 @@ function getRunMetadata(runId) {
217217
}
218218

219219
function getFailedJobs(runId) {
220-
const failedJobs = []
221-
let page = 1
222-
223-
while (true) {
224-
const jqQuery = '.jobs[] | select(.conclusion == "failure") | {id, name}'
225-
let output
226-
try {
227-
output = exec(
228-
`gh api "repos/vercel/next.js/actions/runs/${runId}/jobs?per_page=100&page=${page}" --jq '${jqQuery}'`
229-
)
230-
} catch {
231-
break
232-
}
233-
234-
if (!output.trim()) break
235-
236-
const jobs = output
237-
.split('\n')
238-
.filter((line) => line.trim())
239-
.map((line) => JSON.parse(line))
240-
241-
failedJobs.push(...jobs)
242-
243-
if (jobs.length < 100) break
244-
page++
245-
}
246-
247-
return failedJobs
220+
// Fetch all jobs first, then filter for failures in JS.
221+
// We can't use jq filtering during pagination because a page full of
222+
// non-failure jobs produces empty jq output, which would incorrectly
223+
// stop pagination before reaching later pages that contain failures.
224+
const allJobs = getAllJobs(runId)
225+
return allJobs
226+
.filter((j) => j.conclusion === 'failure')
227+
.map((j) => ({ id: j.id, name: j.name }))
248228
}
249229

250230
function getAllJobs(runId) {

0 commit comments

Comments
 (0)