Skip to content

Commit 5783de4

Browse files
committed
Improve reliability for re-runs
Implements a recommendation that both Codex and Copilot gave to the PR. They accurately pointed out that the results would be unpredictable and unreliable in the case of multiple check runs with the same name (such as reruns). This starts using only the most recent check run for each name.
1 parent f2649b0 commit 5783de4

3 files changed

Lines changed: 65 additions & 30 deletions

File tree

dist/index.js

Lines changed: 31 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main.ts

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -91,18 +91,26 @@ export async function requiredCheckRunLoopIteration(
9191
}
9292
)
9393

94+
// Track check runs by name, keeping only the most recent (highest ID) for each name.
95+
// GitHub's Check Runs API can return multiple check runs with the same name
96+
// (e.g., due to re-runs), and the order is not guaranteed to be deterministic.
9497
const foundChecks = new Map<
9598
string,
96-
{status: string; conclusion: string | null}
99+
{id: number; status: string; conclusion: string | null}
97100
>()
98101

99102
for await (const response of checkRunsIterator) {
100103
for (const checkRun of response.data) {
101104
if (requiredCheckRuns.has(checkRun.name)) {
102-
foundChecks.set(checkRun.name, {
103-
status: checkRun.status,
104-
conclusion: checkRun.conclusion
105-
})
105+
const existing = foundChecks.get(checkRun.name)
106+
// Only update if this check run has a higher ID (more recent)
107+
if (!existing || checkRun.id > existing.id) {
108+
foundChecks.set(checkRun.name, {
109+
id: checkRun.id,
110+
status: checkRun.status,
111+
conclusion: checkRun.conclusion
112+
})
113+
}
106114
}
107115
}
108116
}
@@ -449,10 +457,11 @@ async function checkRunLoopIteration(
449457
)
450458

451459
let totalCheckRuns = 0
452-
let filteredCheckRuns = 0
453460

454-
const pendingCheckRuns: PendingCheckRun[] = []
455-
const completedCheckRuns: CompletedCheckRun[] = []
461+
// Track check runs by name, keeping only the most recent (highest ID) for each name.
462+
// GitHub's Check Runs API can return multiple check runs with the same name
463+
// (e.g., due to re-runs), and the order is not guaranteed to be deterministic.
464+
const checkRunsByName = new Map<string, CheckRun>()
456465

457466
for await (const response of checkRunsIterator) {
458467
totalCheckRuns += response.data.length
@@ -462,18 +471,27 @@ async function checkRunLoopIteration(
462471
continue
463472
}
464473

465-
filteredCheckRuns++
466-
467-
if (isCheckRunCompleted(checkRun)) {
468-
completedCheckRuns.push(checkRun)
469-
} else {
470-
pendingCheckRuns.push(checkRun)
474+
const existing = checkRunsByName.get(checkRun.name)
475+
// Only update if this check run has a higher ID (more recent)
476+
if (!existing || checkRun.id > existing.id) {
477+
checkRunsByName.set(checkRun.name, checkRun)
471478
}
472479
}
473480
}
474481

482+
const pendingCheckRuns: PendingCheckRun[] = []
483+
const completedCheckRuns: CompletedCheckRun[] = []
484+
485+
for (const checkRun of checkRunsByName.values()) {
486+
if (isCheckRunCompleted(checkRun)) {
487+
completedCheckRuns.push(checkRun)
488+
} else {
489+
pendingCheckRuns.push(checkRun)
490+
}
491+
}
492+
475493
core.info(
476-
`Found ${totalCheckRuns} total check runs, keeping ${filteredCheckRuns}.`
494+
`Found ${totalCheckRuns} total check runs, keeping ${checkRunsByName.size} unique.`
477495
)
478496

479497
return [pendingCheckRuns, completedCheckRuns]

0 commit comments

Comments
 (0)