mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 20:21:45 +00:00
165 lines
4.6 KiB
TypeScript
165 lines
4.6 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
mergeTelegramProofIntoReleaseBody,
|
|
parseArgs,
|
|
parseWorkflowRunIdFromOutput,
|
|
pollRun,
|
|
run,
|
|
selectNewestDispatchedRunId,
|
|
} from "../../scripts/release-beta-smoke.ts";
|
|
|
|
describe("release-beta-smoke", () => {
|
|
it("rejects runs with both validation lanes skipped", () => {
|
|
expect(() => parseArgs(["--skip-parallels", "--skip-telegram"])).toThrow(
|
|
"--skip-parallels and --skip-telegram cannot be used together",
|
|
);
|
|
});
|
|
|
|
it("parses workflow run urls when gh includes them in dispatch output", () => {
|
|
expect(
|
|
parseWorkflowRunIdFromOutput(
|
|
"Dispatched: https://github.com/openclaw/openclaw/actions/runs/1234567890",
|
|
),
|
|
).toBe("1234567890");
|
|
});
|
|
|
|
it("selects the newest workflow_dispatch run not present before dispatch", () => {
|
|
const beforeIds = new Set(["100", "101"]);
|
|
|
|
expect(
|
|
selectNewestDispatchedRunId({
|
|
beforeIds,
|
|
runs: [
|
|
{ databaseId: 100, createdAt: "2026-05-04T10:00:00Z" },
|
|
{ databaseId: 102, createdAt: "2026-05-04T10:01:00Z" },
|
|
{ databaseId: 103, createdAt: "2026-05-04T10:02:00Z" },
|
|
],
|
|
}),
|
|
).toBe("103");
|
|
});
|
|
|
|
it("selects runs returned by the actions workflow runs API", () => {
|
|
const beforeIds = new Set(["200"]);
|
|
|
|
expect(
|
|
selectNewestDispatchedRunId({
|
|
beforeIds,
|
|
runs: [
|
|
{ id: 200, created_at: "2026-05-04T10:00:00Z" },
|
|
{ id: 201, created_at: "2026-05-04T10:02:00Z" },
|
|
{ id: 202, created_at: "2026-05-04T10:01:00Z" },
|
|
],
|
|
}),
|
|
).toBe("201");
|
|
});
|
|
|
|
it("replaces stale Telegram proof placeholders", () => {
|
|
const body = [
|
|
"## Changes",
|
|
"",
|
|
"### Release verification",
|
|
"",
|
|
"- npm package: https://www.npmjs.com/package/openclaw/v/2026.5.20-beta.1",
|
|
"- npm Telegram beta E2E: not supplied",
|
|
"",
|
|
"### Assets",
|
|
"",
|
|
"- artifact",
|
|
"",
|
|
].join("\n");
|
|
|
|
const merged = mergeTelegramProofIntoReleaseBody(
|
|
body,
|
|
"- npm Telegram beta E2E: https://github.com/openclaw/openclaw/actions/runs/123",
|
|
);
|
|
|
|
expect(merged).toContain("actions/runs/123");
|
|
expect(merged).not.toContain("not supplied");
|
|
expect(merged).toContain("### Assets");
|
|
});
|
|
|
|
it("inserts Telegram proof before the next release notes subsection", () => {
|
|
const body = [
|
|
"## Changes",
|
|
"",
|
|
"### Release verification",
|
|
"",
|
|
"- npm package: https://www.npmjs.com/package/openclaw/v/2026.5.20-beta.1",
|
|
"",
|
|
"### Assets",
|
|
"",
|
|
"- artifact",
|
|
"",
|
|
].join("\n");
|
|
|
|
const merged = mergeTelegramProofIntoReleaseBody(
|
|
body,
|
|
"- npm Telegram beta E2E: https://github.com/openclaw/openclaw/actions/runs/123",
|
|
);
|
|
|
|
expect(merged.indexOf("actions/runs/123")).toBeLessThan(merged.indexOf("### Assets"));
|
|
});
|
|
|
|
it("bounds child command hangs", () => {
|
|
expect(() =>
|
|
run(process.execPath, ["-e", "setInterval(() => {}, 1000)"], {
|
|
capture: true,
|
|
timeoutMs: 50,
|
|
}),
|
|
).toThrow(/timed out after 50ms/u);
|
|
});
|
|
|
|
it("uses a non-ignorable timeout signal for trapped children", () => {
|
|
expect(() =>
|
|
run(
|
|
process.execPath,
|
|
["-e", "process.on('SIGTERM', () => {}); setInterval(() => {}, 1000)"],
|
|
{
|
|
capture: true,
|
|
timeoutMs: 50,
|
|
},
|
|
),
|
|
).toThrow(/timed out after 50ms/u);
|
|
});
|
|
|
|
it("stops polling Telegram workflow runs after the timeout budget", async () => {
|
|
let now = 0;
|
|
const sleeps: number[] = [];
|
|
|
|
await expect(
|
|
pollRun("openclaw/openclaw", "123", {
|
|
now: () => now,
|
|
pollIntervalMs: 400,
|
|
readRun: () => ({
|
|
conclusion: null,
|
|
html_url: "https://github.com/openclaw/openclaw/actions/runs/123",
|
|
status: "queued",
|
|
updated_at: "2026-05-28T12:00:00Z",
|
|
}),
|
|
sleep: async (ms) => {
|
|
sleeps.push(ms);
|
|
now += ms;
|
|
},
|
|
timeoutMs: 1000,
|
|
}),
|
|
).rejects.toThrow("Telegram workflow 123 did not complete within 1000ms");
|
|
expect(sleeps).toEqual([400, 400, 200]);
|
|
});
|
|
|
|
it("returns when the Telegram workflow succeeds", async () => {
|
|
await expect(
|
|
pollRun("openclaw/openclaw", "123", {
|
|
readRun: () => ({
|
|
conclusion: "success",
|
|
html_url: "https://github.com/openclaw/openclaw/actions/runs/123",
|
|
status: "completed",
|
|
updated_at: "2026-05-28T12:00:00Z",
|
|
}),
|
|
sleep: async () => {
|
|
throw new Error("sleep should not run after completion");
|
|
},
|
|
}),
|
|
).resolves.toBeUndefined();
|
|
});
|
|
});
|