mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 14:01:24 +08:00
175 lines
5.1 KiB
TypeScript
175 lines
5.1 KiB
TypeScript
import { describe, expect, it, vi } from "vitest";
|
|
import {
|
|
buildPublishCommand,
|
|
githubApi,
|
|
parseArgs,
|
|
parseRunIdFromDispatchOutput,
|
|
resolveArtifactName,
|
|
} from "../../scripts/release-candidate-checklist.mjs";
|
|
|
|
describe("release candidate checklist", () => {
|
|
it("requires run ids when dispatch is disabled", () => {
|
|
expect(() => parseArgs(["--tag", "v2026.5.14-beta.3", "--skip-dispatch"])).toThrow(
|
|
"--skip-dispatch requires --full-release-run and --npm-preflight-run",
|
|
);
|
|
});
|
|
|
|
it("stops parsing options after the argument terminator", () => {
|
|
const options = parseArgs([
|
|
"--tag",
|
|
"v2026.5.14-beta.3",
|
|
"--full-release-run",
|
|
"111",
|
|
"--npm-preflight-run",
|
|
"222",
|
|
"--skip-dispatch",
|
|
"--",
|
|
"--plugin-publish-scope",
|
|
"selected",
|
|
]);
|
|
|
|
expect(options.pluginPublishScope).toBe("all-publishable");
|
|
});
|
|
|
|
it("accepts package-manager argument separators before script options", () => {
|
|
const options = parseArgs([
|
|
"--",
|
|
"--tag",
|
|
"v2026.5.14-beta.3",
|
|
"--full-release-run",
|
|
"111",
|
|
"--npm-preflight-run",
|
|
"222",
|
|
"--skip-dispatch",
|
|
"--skip-parallels",
|
|
]);
|
|
|
|
expect(options.tag).toBe("v2026.5.14-beta.3");
|
|
expect(options.skipParallels).toBe(true);
|
|
});
|
|
|
|
it("builds the gated release publish command from green evidence inputs", () => {
|
|
const options = {
|
|
...parseArgs([
|
|
"--tag",
|
|
"v2026.5.14-beta.3",
|
|
"--workflow-ref",
|
|
"release/2026.5.14",
|
|
"--full-release-run",
|
|
"111",
|
|
"--npm-preflight-run",
|
|
"222",
|
|
"--skip-dispatch",
|
|
]),
|
|
workflowRef: "release/2026.5.14",
|
|
};
|
|
|
|
expect(buildPublishCommand(options)).toContain("'full_release_validation_run_id=111'");
|
|
expect(buildPublishCommand(options)).toContain("'preflight_run_id=222'");
|
|
expect(buildPublishCommand(options)).toContain("'tag=v2026.5.14-beta.3'");
|
|
expect(buildPublishCommand(options)).toContain("'plugin_publish_scope=all-publishable'");
|
|
});
|
|
|
|
it("carries the Telegram proof run into the publish command when available", () => {
|
|
const options = {
|
|
...parseArgs([
|
|
"--tag",
|
|
"v2026.5.14-beta.3",
|
|
"--workflow-ref",
|
|
"release/2026.5.14",
|
|
"--full-release-run",
|
|
"111",
|
|
"--npm-preflight-run",
|
|
"222",
|
|
"--skip-dispatch",
|
|
]),
|
|
workflowRef: "release/2026.5.14",
|
|
npmTelegramRunId: "333",
|
|
};
|
|
|
|
expect(buildPublishCommand(options)).toContain("'npm_telegram_run_id=333'");
|
|
});
|
|
|
|
it("requires explicit plugin names for selected plugin publish scope", () => {
|
|
expect(() =>
|
|
parseArgs(["--tag", "v2026.5.14-beta.3", "--plugin-publish-scope", "selected"]),
|
|
).toThrow("--plugin-publish-scope selected requires --plugins");
|
|
});
|
|
|
|
it("rejects selected plugin publish scope for release candidates", () => {
|
|
expect(() =>
|
|
parseArgs([
|
|
"--tag",
|
|
"v2026.5.14-beta.3",
|
|
"--plugin-publish-scope",
|
|
"selected",
|
|
"--plugins",
|
|
"@openclaw/diffs",
|
|
]),
|
|
).toThrow("release candidates publish OpenClaw with --plugin-publish-scope all-publishable");
|
|
});
|
|
|
|
it("extracts a workflow run id from gh dispatch output", () => {
|
|
expect(
|
|
parseRunIdFromDispatchOutput(
|
|
"https://github.com/openclaw/openclaw/actions/runs/25922042055\n",
|
|
),
|
|
).toBe("25922042055");
|
|
});
|
|
|
|
it("falls back to a single compatible artifact from the same run", () => {
|
|
expect(
|
|
resolveArtifactName(
|
|
[{ name: "openclaw-npm-preflight-dba00", expired: false }],
|
|
"openclaw-npm-preflight-v2026.5.16-beta.2",
|
|
"openclaw-npm-preflight-",
|
|
),
|
|
).toBe("openclaw-npm-preflight-dba00");
|
|
});
|
|
|
|
it("bounds GitHub API requests with a timeout signal", async () => {
|
|
const fetchImpl = vi.fn(async (_url: string, init?: RequestInit) => {
|
|
expect(init?.signal).toBeInstanceOf(AbortSignal);
|
|
expect(init?.headers).toMatchObject({
|
|
Accept: "application/vnd.github+json",
|
|
Authorization: "Bearer test-token",
|
|
"X-GitHub-Api-Version": "2022-11-28",
|
|
});
|
|
return {
|
|
ok: true,
|
|
json: async () => ({ workflow_runs: [] }),
|
|
};
|
|
});
|
|
|
|
await expect(
|
|
githubApi("repos/openclaw/openclaw/actions/runs", {
|
|
fetchImpl,
|
|
timeoutMs: 1234,
|
|
token: "test-token",
|
|
}),
|
|
).resolves.toEqual({ workflow_runs: [] });
|
|
expect(fetchImpl).toHaveBeenCalledWith(
|
|
"https://api.github.com/repos/openclaw/openclaw/actions/runs",
|
|
expect.objectContaining({
|
|
signal: expect.any(AbortSignal),
|
|
}),
|
|
);
|
|
});
|
|
|
|
it("includes the GitHub API path when a request times out", async () => {
|
|
const fetchImpl = vi.fn(async () => {
|
|
throw new DOMException("request timed out", "TimeoutError");
|
|
});
|
|
|
|
await expect(
|
|
githubApi("repos/openclaw/openclaw/actions/runs/123/jobs", {
|
|
fetchImpl,
|
|
timeoutMs: 5,
|
|
token: "test-token",
|
|
}),
|
|
).rejects.toThrow(
|
|
"GitHub API repos/openclaw/openclaw/actions/runs/123/jobs timed out after 5ms",
|
|
);
|
|
});
|
|
});
|