Skip to content

Commit 9e218a5

Browse files
fix(ci): reconcile labels against latest check run per name (#270)
Co-authored-by: Elliott de Launay <edelauna@gmail.com>
1 parent a441e02 commit 9e218a5

1 file changed

Lines changed: 20 additions & 1 deletion

File tree

.github/workflows/label-pr-review-state.yml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,9 +153,28 @@ jobs:
153153
}),
154154
]);
155155
156+
// listForRef returns every check run ever recorded on the ref, including
157+
// stale superseded ones (e.g. a failed run later re-run green). Branch
158+
// protection and the PR UI only consider the latest run per check name, so
159+
// reduce to that before evaluating — otherwise a single stale failure makes
160+
// ciFailed true forever and state labels never come back. See issue #884.
161+
//
162+
// Unlike listReviews (which documents oldest-first order), listForRef's
163+
// ordering is unspecified, so we pick the latest by run.id — GitHub assigns
164+
// monotonically increasing IDs, and id is never null (a freshly re-queued
165+
// run can have started_at: null, which would lose a string comparison
166+
// against an older completed run's timestamp).
167+
const latestByName = new Map();
168+
for (const run of checkRuns) {
169+
const prev = latestByName.get(run.name);
170+
if (!prev || run.id > prev.id) {
171+
latestByName.set(run.name, run);
172+
}
173+
}
174+
156175
// Filter to required checks only (or all checks if rules unavailable).
157176
// Always exclude this workflow's own run to avoid self-referential loops.
158-
const relevantRuns = checkRuns.filter(run => {
177+
const relevantRuns = [...latestByName.values()].filter(run => {
159178
if (run.name === 'Reconcile PR review state labels') return false;
160179
return requiredCheckNames ? requiredCheckNames.has(run.name) : true;
161180
});

0 commit comments

Comments
 (0)