fix: CRITICAL - fix field name mismatch in getCIChecks causing all checks to fail

Root cause of "CI failing" everywhere: scm-github plugin was requesting
non-existent fields from gh CLI, causing all checks to map to "failed".

**The Bug:**
- Requesting: `conclusion` and `detailsUrl` (don't exist in gh pr checks)
- Since `conclusion` was always undefined, every check hit the else clause
  and was marked as "failed"

**The Fix:**
- Use correct field names: `state` (contains SUCCESS/FAILURE/PENDING directly)
  and `link` (replaces detailsUrl)
- Parse `state` directly instead of looking for non-existent `conclusion`
- Map state values: SUCCESS → passed, FAILURE → failed, PENDING → pending, etc.

**Impact:**
This was the #1 bug causing false "CI failing" status everywhere, not rate
limiting. All PRs with passing CI were incorrectly shown as failing.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
Prateek 2026-02-15 03:23:19 +05:30
parent f0d3a08489
commit f8fc51ae9d
1 changed files with 12 additions and 13 deletions

View File

@ -208,14 +208,13 @@ function createGitHubSCM(): SCM {
"--repo",
repoFlag(pr),
"--json",
"name,state,conclusion,detailsUrl,startedAt,completedAt",
"name,state,link,startedAt,completedAt",
]);
const checks: Array<{
name: string;
state: string;
conclusion: string;
detailsUrl: string;
link: string;
startedAt: string;
completedAt: string;
}> = JSON.parse(raw);
@ -223,33 +222,33 @@ function createGitHubSCM(): SCM {
return checks.map((c) => {
let status: CICheck["status"];
const state = c.state?.toUpperCase();
const conclusion = c.conclusion?.toUpperCase();
// gh pr checks returns state directly: SUCCESS, FAILURE, PENDING, QUEUED, etc.
if (state === "PENDING" || state === "QUEUED") {
status = "pending";
} else if (state === "IN_PROGRESS") {
status = "running";
} else if (conclusion === "SUCCESS") {
} else if (state === "SUCCESS") {
status = "passed";
} else if (
conclusion === "FAILURE" ||
conclusion === "TIMED_OUT" ||
conclusion === "CANCELLED" ||
conclusion === "ACTION_REQUIRED"
state === "FAILURE" ||
state === "TIMED_OUT" ||
state === "CANCELLED" ||
state === "ACTION_REQUIRED"
) {
status = "failed";
} else if (conclusion === "SKIPPED" || conclusion === "NEUTRAL") {
} else if (state === "SKIPPED" || state === "NEUTRAL") {
status = "skipped";
} else {
// Unknown conclusion on a completed check — fail closed
// Unknown state on a check — fail closed for safety
status = "failed";
}
return {
name: c.name,
status,
url: c.detailsUrl || undefined,
conclusion: c.conclusion || undefined,
url: c.link || undefined,
conclusion: state || undefined, // Store original state for debugging
startedAt: c.startedAt ? new Date(c.startedAt) : undefined,
completedAt: c.completedAt ? new Date(c.completedAt) : undefined,
};