Files
openclaw/test/scripts/openclaw-npm-resume-run.test.ts
Peter Steinberger c70aee247e refactor(scripts): migrate JavaScript tools to TypeScript (#121005)
* refactor(scripts): migrate JavaScript tools to TypeScript

* fix(ci): keep changed-scope preflight zero-install

* fix(ci): preserve zero-install script owners

* fix(ci): complete script migration follow-through

* fix(release): keep stable closeout zero-install

* fix(scripts): preserve standalone execution boundaries

* fix(scripts): repair standalone loader boundaries

* fix(scripts): normalize gateway observation ids

* fix(scripts): keep Docker packager standalone

* test(scripts): preserve rebase cleanup helpers

* test(sessions): use tracked temp directory
2026-08-09 07:21:35 -07:00

148 lines
4.9 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import {
resolveOpenClawNpmResumeRun,
runOpenClawNpmResumeGh,
validateOpenClawNpmResumeRun,
} from "../../scripts/openclaw-npm-resume-run.mts";
import type { OpenClawNpmResumeValidationInput } from "../../scripts/openclaw-npm-resume-run.mts";
const SHA = "a".repeat(40);
const TAG_OBJECT_SHA = "b".repeat(40);
const BRANCH = `release-publish/${SHA.slice(0, 12)}-123`;
const URL = "https://github.com/openclaw/openclaw/actions/runs/456";
function fixture(
overrides: Partial<OpenClawNpmResumeValidationInput> = {},
): OpenClawNpmResumeValidationInput {
return {
canonicalWorkflowId: 101,
compareStatus: "identical",
jobs: [{ conclusion: "success", name: "validate_publish_request" }],
run: {
conclusion: "success",
event: "workflow_dispatch",
head_branch: BRANCH,
head_sha: SHA,
html_url: URL,
path: `.github/workflows/openclaw-npm-release.yml@refs/tags/${BRANCH}`,
workflow_id: 101,
},
tag: {
object: { sha: SHA, type: "commit" },
verification: { verified: true },
},
tagRef: { object: { sha: TAG_OBJECT_SHA, type: "tag" } },
...overrides,
};
}
describe("openclaw npm resume run identity", () => {
it("bounds each GitHub lookup", () => {
const execFileSyncImpl = vi.fn(() => "result");
expect(
runOpenClawNpmResumeGh(["api", "repos/openclaw/openclaw/actions/runs/456"], {
execFileSyncImpl,
}),
).toBe("result");
expect(execFileSyncImpl).toHaveBeenCalledWith(
"gh",
["api", "repos/openclaw/openclaw/actions/runs/456"],
{
encoding: "utf8",
killSignal: "SIGKILL",
maxBuffer: 32 * 1024 * 1024,
timeout: 60_000,
},
);
});
it("propagates GitHub lookup timeouts", () => {
const timeoutError = Object.assign(new Error("spawnSync gh ETIMEDOUT"), {
code: "ETIMEDOUT",
});
expect(() =>
runOpenClawNpmResumeGh(["api", "repos/openclaw/openclaw/actions/runs/456"], {
execFileSyncImpl: () => {
throw timeoutError;
},
}),
).toThrow(timeoutError);
});
it("accepts a successful run bound to a signed main-reachable tooling tag", () => {
expect(validateOpenClawNpmResumeRun(fixture())).toEqual({
tagObjectSha: TAG_OBJECT_SHA,
url: URL,
workflowRef: `refs/tags/${BRANCH}`,
workflowSha: SHA,
});
});
it.each([
["branch", { run: { ...fixture().run, head_branch: "main" } }, "untrusted workflow ref"],
["workflow", { run: { ...fixture().run, workflow_id: 999 } }, "untrusted workflow identity"],
["event", { run: { ...fixture().run, event: "push" } }, "untrusted workflow identity"],
[
"conclusion",
{ run: { ...fixture().run, conclusion: "failure" } },
"untrusted workflow identity",
],
[
"path",
{ run: { ...fixture().run, path: ".github/workflows/ci.yml" } },
"untrusted workflow identity",
],
[
"tag kind",
{ tagRef: { object: { sha: TAG_OBJECT_SHA, type: "commit" } } },
"not a signed annotated tag",
],
[
"tag target",
{ tag: { ...fixture().tag, object: { sha: "c".repeat(40), type: "commit" } } },
"not bound to a real",
],
[
"signature",
{ tag: { ...fixture().tag, verification: { verified: false } } },
"not bound to a real",
],
["main ancestry", { compareStatus: "diverged" }, "not bound to a real"],
[
"approval",
{ jobs: [{ conclusion: "failure", name: "validate_publish_request" }] },
"lacks successful parent release approval",
],
])("rejects an untrusted %s", (_label, overrides, message) => {
expect(() => validateOpenClawNpmResumeRun(fixture(overrides))).toThrow(message);
});
it("loads the exact run, workflow, signed tag, ancestry, and approval job", () => {
const responses = new Map<string, unknown>([
[`api repos/openclaw/openclaw/actions/runs/456 --method GET`, fixture().run],
[
`api repos/openclaw/openclaw/actions/workflows/openclaw-npm-release.yml --method GET`,
{ id: 101 },
],
[`api repos/openclaw/openclaw/git/ref/tags/${BRANCH} --method GET`, fixture().tagRef],
[`api repos/openclaw/openclaw/git/tags/${TAG_OBJECT_SHA} --method GET`, fixture().tag],
[`api repos/openclaw/openclaw/compare/${SHA}...main --method GET`, { status: "identical" }],
[`run view 456 --repo openclaw/openclaw --json jobs --jq .jobs`, fixture().jobs],
]);
const runGh = vi.fn((args: string[]) => {
const response = responses.get(args.join(" "));
if (!response) {
throw new Error(`Unexpected gh invocation: ${args.join(" ")}`);
}
return JSON.stringify(response);
});
expect(
resolveOpenClawNpmResumeRun({ repo: "openclaw/openclaw", runGh, runId: "456" }),
).toMatchObject({ workflowRef: `refs/tags/${BRANCH}`, workflowSha: SHA });
expect(runGh).toHaveBeenCalledTimes(6);
});
});