Skip to content

Commit f412bb6

Browse files
committed
fix(miner): classify stale checks as failures
1 parent 7b7a1b6 commit f412bb6

2 files changed

Lines changed: 41 additions & 3 deletions

File tree

packages/gittensory-miner/lib/ci-poller.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ function apiUrl(apiBaseUrl, path, query = "") {
6060

6161
function githubError(response, payload) {
6262
const code = `github_${response.status}`;
63-
const githubMessage = typeof payload?.message === "string" && payload.message.trim() ? payload.message : null;
63+
const githubMessage =
64+
typeof payload?.message === "string" && payload.message.trim() ? payload.message : null;
6465
const message = githubMessage ? `${code}: ${githubMessage}` : code;
6566
return Object.assign(new Error(message), { code, githubMessage });
6667
}
@@ -104,6 +105,7 @@ function normalizeConclusion(checkRun) {
104105
case "cancelled":
105106
case "timed_out":
106107
case "action_required":
108+
case "stale":
107109
case "startup_failure":
108110
return "failure";
109111
default:
@@ -158,7 +160,10 @@ async function fetchCheckRuns(target, headSha, options) {
158160
),
159161
options,
160162
);
161-
const pageChecks = Array.isArray(payload?.check_runs) ? payload.check_runs.map(normalizeCheckRun) : [];
163+
if (!Array.isArray(payload?.check_runs)) {
164+
throw new Error("github_check_runs_malformed");
165+
}
166+
const pageChecks = payload.check_runs.map(normalizeCheckRun);
162167
checks.push(...pageChecks);
163168
expectedTotalCount = payloadTotalCount(payload) ?? expectedTotalCount;
164169
if (!hasNextLink(response) && (expectedTotalCount === null || checks.length >= expectedTotalCount)) {

test/unit/miner-ci-poller.test.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,15 @@ describe("miner CI check-run poller (#2323)", () => {
9797
expect(fetchFn).toHaveBeenCalledTimes(3);
9898
});
9999

100-
it("normalizes failed terminal conclusions to failure", async () => {
100+
it("normalizes failed terminal conclusions, including stale, to failure", async () => {
101101
const fetchFn = vi
102102
.fn()
103103
.mockResolvedValueOnce(prResponse())
104104
.mockResolvedValueOnce(
105105
checksResponse([
106106
checkRun("validate", "completed", "success"),
107107
checkRun("workers", "completed", "timed_out"),
108+
checkRun("expired", "completed", "stale"),
108109
]),
109110
);
110111

@@ -115,10 +116,31 @@ describe("miner CI check-run poller (#2323)", () => {
115116
checks: [
116117
{ name: "validate", conclusion: "success" },
117118
{ name: "workers", conclusion: "failure" },
119+
{ name: "expired", conclusion: "failure" },
118120
],
119121
});
120122
});
121123

124+
it("treats a completed stale check run as terminal failure (regression for #2621)", async () => {
125+
const fetchFn = vi
126+
.fn()
127+
.mockResolvedValueOnce(prResponse())
128+
.mockResolvedValueOnce(checksResponse([checkRun("github-timeout", "completed", "stale")]));
129+
130+
await expect(
131+
pollCheckRuns("acme/widgets", 7, {
132+
apiBaseUrl: API,
133+
fetchFn,
134+
maxAttempts: 3,
135+
sleepFn: vi.fn(),
136+
}),
137+
).resolves.toMatchObject({
138+
conclusion: "failure",
139+
attempts: 1,
140+
checks: [{ name: "github-timeout", conclusion: "failure" }],
141+
});
142+
});
143+
122144
it("keeps pending when checks are queued or absent", async () => {
123145
const queuedFetch = vi
124146
.fn()
@@ -201,4 +223,15 @@ describe("miner CI check-run poller (#2323)", () => {
201223
pollCheckRuns("acme/widgets", 11, { apiBaseUrl: API, fetchFn: missingSha }),
202224
).rejects.toThrow("github_pr_head_sha_missing");
203225
});
226+
227+
it("surfaces malformed check-run responses as deterministic errors", async () => {
228+
const malformedChecks = vi
229+
.fn()
230+
.mockResolvedValueOnce(prResponse())
231+
.mockResolvedValueOnce(jsonResponse({ total_count: 1, check_runs: null }));
232+
233+
await expect(
234+
pollCheckRuns("acme/widgets", 12, { apiBaseUrl: API, fetchFn: malformedChecks }),
235+
).rejects.toThrow("github_check_runs_malformed");
236+
});
204237
});

0 commit comments

Comments
 (0)