Files
openclaw/test/scripts/full-release-validation-at-sha.test.ts
Vincent Koc c47ceb0f3d improve(release): reuse exact-SHA validation evidence (#104162)
* perf(release): share changelog verification snapshots

* perf(release): reuse exact-SHA validation evidence

* feat(release): checkpoint candidate workflow state

* feat(release): watch CI transitions compactly

* fix(testbox): rotate stale reusable leases

* refactor(release): move CI verifier into scripts

* fix(release): preserve verifier executable mode

* fix(testbox): force noninteractive remote hydration

* perf(testbox): skip sync for proven clean heads

* fix(testbox): keep changed gates synchronized

* fix(testbox): isolate git state probes

* fix(testbox): isolate wrapper git commands

* fix(testbox): preserve git command contracts

* fix(release): validate reused SHA evidence

* fix(release): resume serialized plugin selections

* fix(testbox): sync source on every lease reuse

* fix(release): verify from trusted workflow checkout

* fix(release): gate evidence reuse on trusted lineage

* fix(release): support legacy verifier checkouts

* fix(testbox): export CI across shell snippets

* fix(release): revalidate reused evidence before publish

* fix(release): reject untrusted reuse before lookup

* fix(release): reuse SHA-pinned root evidence

* fix(ci): allow unreleased notes in QA packages

* fix(release): satisfy script lint contracts

* fix(release): handle Unicode workflow refs safely
2026-07-11 12:48:27 +08:00

97 lines
3.2 KiB
TypeScript

import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { describe, expect, it } from "vitest";
import {
parseArgs,
releaseEvidenceVerificationArgs,
releaseEvidenceVerifierPath,
} from "../../scripts/full-release-validation-at-sha.mjs";
describe("full-release-validation-at-sha", () => {
it("parses release validation dispatch args", () => {
expect(
parseArgs([
"--sha",
"abc123",
"--workflow-sha",
"origin/main",
"--keep-branch",
"--dry-run",
"-f",
"provider=anthropic",
"--",
"mode=linux",
]),
).toMatchObject({
dryRun: true,
keepBranch: true,
inputs: {
mode: "linux",
provider: "anthropic",
reuse_evidence: "true",
},
sha: "abc123",
workflowSha: "origin/main",
});
});
it("rejects missing option values", () => {
expect(() => parseArgs(["--sha", "--dry-run"])).toThrow("--sha requires a value");
expect(() => parseArgs(["--sha", "-h"])).toThrow("--sha requires a value");
expect(() => parseArgs(["--workflow-sha", "--dry-run"])).toThrow(
"--workflow-sha requires a value",
);
expect(() => parseArgs(["--workflow-sha", "-h"])).toThrow("--workflow-sha requires a value");
expect(() => parseArgs(["-f", "--dry-run"])).toThrow("-f requires a value");
expect(() => parseArgs(["-f", "-h"])).toThrow("-f requires a value");
});
it("allows exact-target reuse to be disabled for a forced fresh run", () => {
expect(parseArgs(["-f", "reuse_evidence=false"]).inputs.reuse_evidence).toBe("false");
expect(() => parseArgs(["-f", "reuse_evidence=maybe"])).toThrow(
"reuse_evidence must be true or false",
);
});
it("reserves the candidate ref for the resolved --sha", () => {
expect(() => parseArgs(["-f", "ref=other"])).toThrow("reserves the ref input");
expect(() => parseArgs(["--", "ref=other"])).toThrow("reserves the ref input");
});
it("validates direct and reused runs through the strict evidence verifier", () => {
expect(releaseEvidenceVerificationArgs("123")).toEqual([
"--validate-run",
"123",
"--trusted-workflow-ref",
"main",
"--json",
]);
expect(() => releaseEvidenceVerificationArgs("")).toThrow("positive decimal");
});
it("supports current and legacy verifier locations in trusted workflow checkouts", () => {
const root = mkdtempSync(join(tmpdir(), "openclaw-release-verifier-path-"));
try {
const legacy = join(
root,
".agents",
"skills",
"release-openclaw-ci",
"scripts",
"release-ci-summary.mjs",
);
mkdirSync(join(legacy, ".."), { recursive: true });
writeFileSync(legacy, "");
expect(releaseEvidenceVerifierPath(root)).toBe(legacy);
const current = join(root, "scripts", "release-ci-summary.mjs");
mkdirSync(join(current, ".."), { recursive: true });
writeFileSync(current, "");
expect(releaseEvidenceVerifierPath(root)).toBe(current);
} finally {
rmSync(root, { force: true, recursive: true });
}
});
});