Merge pull request #2485 from pikasTech/fix/2477-action-log-not-ready
fix: 正确分类尚未生成的 Actions 日志
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, test } from "bun:test";
|
||||
import { redactAndTailActionLog } from "./gh/actions-runs";
|
||||
import { isActionLogNotReady, redactAndTailActionLog } from "./gh/actions-runs";
|
||||
import { withGhDefaultRendered } from "./gh/default-render";
|
||||
|
||||
describe("GitHub Actions run diagnostics", () => {
|
||||
@@ -22,6 +22,11 @@ describe("GitHub Actions run diagnostics", () => {
|
||||
expect(redactAndTailActionLog("a".repeat(100), 10, 12)).toBe("a".repeat(12));
|
||||
});
|
||||
|
||||
test("classifies a pending job log without claiming the repository is missing", () => {
|
||||
expect(isActionLogNotReady({ status: 404, message: "The specified blob does not exist." })).toBe(true);
|
||||
expect(isActionLogNotReady({ status: 404, message: "Not Found" })).toBe(false);
|
||||
});
|
||||
|
||||
test("renders startup failures and bounded logs without hiding evidence", () => {
|
||||
const startup = withGhDefaultRendered(["run", "view", "42"], {
|
||||
ok: true,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { commandError, githubRequest, githubTextRequest, isGitHubError, validationError } from "./client";
|
||||
import { commandError, errorPayload, githubRequest, githubTextRequest, isGitHubError, validationError } from "./client";
|
||||
|
||||
interface WorkflowRun {
|
||||
id: number;
|
||||
@@ -77,6 +77,12 @@ export function redactAndTailActionLog(text: string, lineLimit = 80, charLimit =
|
||||
return redacted.split(/\r?\n/u).slice(-lineLimit).join("\n").slice(-charLimit);
|
||||
}
|
||||
|
||||
export function isActionLogNotReady(error: unknown): boolean {
|
||||
if (typeof error !== "object" || error === null) return false;
|
||||
const value = error as { status?: unknown; message?: unknown };
|
||||
return value.status === 404 && typeof value.message === "string" && value.message.toLowerCase().includes("blob does not exist");
|
||||
}
|
||||
|
||||
export async function actionRunList(repo: string, token: string, limit: number): Promise<Record<string, unknown>> {
|
||||
const parts = splitRepo(repo);
|
||||
if (parts === null) return validationError("run list", repo, "--repo must use owner/name format");
|
||||
@@ -137,7 +143,22 @@ export async function actionRunLogs(repo: string, token: string, runId: number,
|
||||
if (parts === null) return validationError("run logs", repo, "--repo must use owner/name format");
|
||||
const [owner, name] = parts;
|
||||
const log = await githubTextRequest(token, `/repos/${owner}/${name}/actions/jobs/${jobId}/logs`);
|
||||
if (isGitHubError(log)) return commandError("run logs", repo, log, { runId, jobId, mutation: false });
|
||||
if (isGitHubError(log)) {
|
||||
if (isActionLogNotReady(log)) {
|
||||
return commandError("run logs", repo, errorPayload("action-log-not-ready", "job log is not available yet", {
|
||||
status: 404,
|
||||
retryable: true,
|
||||
details: { runId, jobId, jobStatus: job.status },
|
||||
}), {
|
||||
runId,
|
||||
jobId,
|
||||
mutation: false,
|
||||
retryable: true,
|
||||
next: `bun scripts/cli.ts gh run view ${runId} --repo ${repo}`,
|
||||
});
|
||||
}
|
||||
return commandError("run logs", repo, log, { runId, jobId, mutation: false });
|
||||
}
|
||||
const logTail = redactAndTailActionLog(log);
|
||||
return {
|
||||
ok: true,
|
||||
|
||||
@@ -187,6 +187,7 @@ export type GitHubDegradedReason =
|
||||
| "auth-failed"
|
||||
| "egress-failed"
|
||||
| "github-transient"
|
||||
| "action-log-not-ready"
|
||||
| "network-proxy-failed"
|
||||
| "permission-denied"
|
||||
| "repo-not-found"
|
||||
|
||||
Reference in New Issue
Block a user