// Validate release publish approval tests cover the stdin/env CLI contract. import { spawnSync } from "node:child_process"; import { describe, expect, it } from "vitest"; const SCRIPT_PATH = "scripts/validate-release-publish-approval.mjs"; function runApprovalScript( run: Record, env: { DIRECT_RELEASE_RECOVERY?: string; EXPECTED_WORKFLOW_BRANCH?: string; RELEASE_PUBLISH_RUN_ID?: string; } = {}, ) { return spawnSync(process.execPath, [SCRIPT_PATH], { cwd: process.cwd(), encoding: "utf8", env: { ...process.env, DIRECT_RELEASE_RECOVERY: env.DIRECT_RELEASE_RECOVERY ?? "false", EXPECTED_WORKFLOW_BRANCH: env.EXPECTED_WORKFLOW_BRANCH ?? "release/2026.6.21", RELEASE_PUBLISH_RUN_ID: env.RELEASE_PUBLISH_RUN_ID ?? "123", }, input: JSON.stringify(run), }); } function approvalRun(overrides: Record = {}) { return { conclusion: null, event: "workflow_dispatch", headBranch: "release/2026.6.21", status: "in_progress", url: "https://github.com/openclaw/openclaw/actions/runs/123", workflowName: "OpenClaw Release Publish", ...overrides, }; } describe("scripts/validate-release-publish-approval.mjs", () => { it("accepts an in-progress release publish workflow run for approval", () => { const result = runApprovalScript(approvalRun()); expect(result.status).toBe(0); expect(result.stdout).toContain( "Using release publish approval run 123: https://github.com/openclaw/openclaw/actions/runs/123", ); expect(result.stderr).toBe(""); }); it("rejects approval runs from the wrong workflow branch", () => { const result = runApprovalScript(approvalRun({ headBranch: "main" })); expect(result.status).toBe(1); expect(result.stderr).toContain( "Referenced release publish run 123 must have headBranch=release/2026.6.21, got main.", ); expect(result.stdout).toBe(""); }); it("rejects completed runs for normal approval handoff", () => { const result = runApprovalScript(approvalRun({ conclusion: "success", status: "completed" })); expect(result.status).toBe(1); expect(result.stderr).toContain( "Referenced release publish run 123 must still be in_progress, got completed.", ); expect(result.stdout).toBe(""); }); it("accepts completed success or failure runs for direct recovery", () => { for (const conclusion of ["success", "failure"]) { const result = runApprovalScript( approvalRun({ conclusion, status: "completed" }), { DIRECT_RELEASE_RECOVERY: "true" }, ); expect(result.status).toBe(0); expect(result.stdout).toContain( `Using completed release publish run 123 (${conclusion}) for direct recovery: https://github.com/openclaw/openclaw/actions/runs/123`, ); expect(result.stderr).toBe(""); } }); });