fix(scm-github): fetch in-progress failed job logs
This commit is contained in:
parent
60b5c91f98
commit
487269aea0
|
|
@ -221,6 +221,29 @@ function extractFailedStep(log: string): string | undefined {
|
|||
return lastStep;
|
||||
}
|
||||
|
||||
async function getFailedJobLog(
|
||||
pr: PRInfo,
|
||||
runReference: { runId: string; jobId?: string },
|
||||
): Promise<string> {
|
||||
try {
|
||||
return await gh([
|
||||
"run",
|
||||
"view",
|
||||
runReference.runId,
|
||||
"--repo",
|
||||
repoFlag(pr),
|
||||
"--log-failed",
|
||||
...(runReference.jobId ? ["--job", runReference.jobId] : []),
|
||||
]);
|
||||
} catch (err) {
|
||||
if (!runReference.jobId) throw err;
|
||||
return gh([
|
||||
"api",
|
||||
`repos/${pr.owner}/${pr.repo}/actions/jobs/${runReference.jobId}/logs`,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
async function getCIChecksFromStatusRollup(pr: PRInfo): Promise<CICheck[]> {
|
||||
const raw = await gh([
|
||||
"pr",
|
||||
|
|
@ -886,15 +909,7 @@ function createGitHubSCM(): SCM {
|
|||
if (seenRuns.has(seenKey)) continue;
|
||||
seenRuns.add(seenKey);
|
||||
|
||||
const log = await gh([
|
||||
"run",
|
||||
"view",
|
||||
runReference.runId,
|
||||
"--repo",
|
||||
repoFlag(pr),
|
||||
"--log-failed",
|
||||
...(runReference.jobId ? ["--job", runReference.jobId] : []),
|
||||
]);
|
||||
const log = await getFailedJobLog(pr, runReference);
|
||||
|
||||
const failedJob: CIFailureSummary["failedJobs"][number] = {
|
||||
name: check.name,
|
||||
|
|
|
|||
|
|
@ -707,6 +707,34 @@ describe("scm-github plugin", () => {
|
|||
|
||||
await expect(scm.getCIFailureSummary?.(pr, checks)).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it("falls back to job logs API when gh run view cannot read logs yet", async () => {
|
||||
const checks = [
|
||||
{
|
||||
name: "lint",
|
||||
status: "failed" as const,
|
||||
conclusion: "FAILURE",
|
||||
url: "https://github.com/acme/repo/actions/runs/123/job/456",
|
||||
},
|
||||
];
|
||||
mockGhError("run 123 is still in progress; logs will be available when it is complete");
|
||||
mockGhRaw("2026-05-14T23:40:42Z ##[error]Lint failed\nunused variable");
|
||||
|
||||
const summary = await scm.getCIFailureSummary?.(pr, checks);
|
||||
|
||||
expect(summary?.failedJobs).toEqual([
|
||||
{
|
||||
name: "lint",
|
||||
runUrl: "https://github.com/acme/repo/actions/runs/123/job/456",
|
||||
logTail: "2026-05-14T23:40:42Z ##[error]Lint failed\nunused variable",
|
||||
},
|
||||
]);
|
||||
expect(ghMock).toHaveBeenLastCalledWith(
|
||||
expect.stringMatching(/(?:^|[\\/])gh(?:\.(?:exe|cmd|bat))?$/i),
|
||||
["api", "repos/acme/repo/actions/jobs/456/logs"],
|
||||
expect.any(Object),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
// ---- getCISummary ------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Reference in New Issue