mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-21 10:16:44 +00:00
fix(release): retain npm provenance evidence
This commit is contained in:
@@ -1918,17 +1918,17 @@ jobs:
|
||||
fi
|
||||
|
||||
if [[ "${PUBLISH_OPENCLAW_NPM}" == "true" ]]; then
|
||||
OPENCLAW_NPM_EXPECTED_WORKFLOW_REF="${openclaw_npm_expected_workflow_ref}" \
|
||||
OPENCLAW_NPM_EXPECTED_WORKFLOW_SHA="${openclaw_npm_expected_workflow_sha}" \
|
||||
node --import tsx \
|
||||
"${GITHUB_WORKSPACE}/.release-harness/scripts/openclaw-npm-postpublish-verify.ts" \
|
||||
"${release_version}"
|
||||
verify_args+=(--skip-postpublish)
|
||||
verify_args+=(
|
||||
--postpublish-verifier
|
||||
"${GITHUB_WORKSPACE}/.release-harness/scripts/openclaw-npm-postpublish-verify.ts"
|
||||
)
|
||||
fi
|
||||
|
||||
node --import tsx \
|
||||
"${GITHUB_WORKSPACE}/.release-harness/scripts/release-verify-beta.ts" \
|
||||
"${verify_args[@]}"
|
||||
OPENCLAW_NPM_EXPECTED_WORKFLOW_REF="${openclaw_npm_expected_workflow_ref}" \
|
||||
OPENCLAW_NPM_EXPECTED_WORKFLOW_SHA="${openclaw_npm_expected_workflow_sha}" \
|
||||
node --import tsx \
|
||||
"${GITHUB_WORKSPACE}/.release-harness/scripts/release-verify-beta.ts" \
|
||||
"${verify_args[@]}"
|
||||
|
||||
# Resolve already validated this exact v3 run before mutation. Append
|
||||
# its immutable tuple here so frozen targets need no new CLI option.
|
||||
|
||||
@@ -26,6 +26,7 @@ type ReleaseVerifyBetaArgs = {
|
||||
pluginSelection: string[];
|
||||
clawHubBootstrapPlugins: string[];
|
||||
evidenceOut?: string;
|
||||
postpublishVerifier?: string;
|
||||
skipPostpublish: boolean;
|
||||
skipGitHubRelease: boolean;
|
||||
skipClawHub: boolean;
|
||||
@@ -242,6 +243,7 @@ export function parseReleaseVerifyBetaArgs(argv: string[]): ReleaseVerifyBetaArg
|
||||
pluginSelection: [],
|
||||
clawHubBootstrapPlugins: [],
|
||||
evidenceOut: undefined,
|
||||
postpublishVerifier: undefined,
|
||||
skipPostpublish: false,
|
||||
skipGitHubRelease: false,
|
||||
skipClawHub: false,
|
||||
@@ -300,6 +302,9 @@ export function parseReleaseVerifyBetaArgs(argv: string[]): ReleaseVerifyBetaArg
|
||||
case "--evidence-out":
|
||||
parsed.evidenceOut = next();
|
||||
break;
|
||||
case "--postpublish-verifier":
|
||||
parsed.postpublishVerifier = next();
|
||||
break;
|
||||
case "--full-release-validation-run":
|
||||
parsed.workflowRuns.fullReleaseValidation = next();
|
||||
break;
|
||||
@@ -335,6 +340,10 @@ export function parseReleaseVerifyBetaArgs(argv: string[]): ReleaseVerifyBetaArg
|
||||
}
|
||||
}
|
||||
|
||||
if (parsed.skipPostpublish && parsed.postpublishVerifier !== undefined) {
|
||||
throw new Error("--postpublish-verifier cannot be combined with --skip-postpublish.");
|
||||
}
|
||||
|
||||
if (parsed.workflowRuns.pluginClawHubBootstrap !== undefined) {
|
||||
if (parsed.releaseSha === undefined) {
|
||||
throw new Error("--plugin-clawhub-bootstrap-run requires --release-sha.");
|
||||
@@ -349,6 +358,17 @@ export function parseReleaseVerifyBetaArgs(argv: string[]): ReleaseVerifyBetaArg
|
||||
return parsed;
|
||||
}
|
||||
|
||||
export function resolveOpenClawNpmPostpublishVerifier(rootDir: string, override?: string): string {
|
||||
if (override === undefined) {
|
||||
return resolve(rootDir, "scripts/openclaw-npm-postpublish-verify.ts");
|
||||
}
|
||||
const verifier = resolve(override);
|
||||
if (verifier !== resolve(TRUSTED_TOOLING_ROOT, "scripts/openclaw-npm-postpublish-verify.ts")) {
|
||||
throw new Error("--postpublish-verifier must select the trusted tooling verifier.");
|
||||
}
|
||||
return verifier;
|
||||
}
|
||||
|
||||
async function fetchWithRetry(
|
||||
url: string,
|
||||
options: RequestInit,
|
||||
@@ -1274,12 +1294,11 @@ export async function verifyBetaRelease(
|
||||
lines.push(`openclaw npm OK: ${args.version} (${args.distTag})`);
|
||||
|
||||
if (!args.skipPostpublish) {
|
||||
runCommandInherited("node", [
|
||||
"--import",
|
||||
"tsx",
|
||||
"scripts/openclaw-npm-postpublish-verify.ts",
|
||||
args.version,
|
||||
]);
|
||||
const postpublishVerifier = resolveOpenClawNpmPostpublishVerifier(
|
||||
rootDir,
|
||||
args.postpublishVerifier,
|
||||
);
|
||||
runCommandInherited("node", ["--import", "tsx", postpublishVerifier, args.version]);
|
||||
lines.push("openclaw postpublish verifier OK");
|
||||
}
|
||||
|
||||
|
||||
@@ -4028,7 +4028,10 @@ describe("package artifact reuse", () => {
|
||||
expect(releaseWorkflow).toContain(
|
||||
'"${GITHUB_WORKSPACE}/.release-harness/scripts/openclaw-npm-postpublish-verify.ts"',
|
||||
);
|
||||
expect(releaseWorkflow).toContain("verify_args+=(--skip-postpublish)");
|
||||
expect(releaseWorkflow).toContain(
|
||||
'"${GITHUB_WORKSPACE}/.release-harness/scripts/openclaw-npm-postpublish-verify.ts"',
|
||||
);
|
||||
expect(releaseWorkflow).toContain("--postpublish-verifier");
|
||||
expect(releaseWorkflow).toContain('"${verify_args[@]}"');
|
||||
expect(releaseWorkflow).toContain(
|
||||
"OpenClaw Release Publish must use trusted main workflow tooling",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Release Beta Verifier tests cover release beta verifier script behavior.
|
||||
/* oxlint-disable typescript/no-base-to-string -- fetch mock normalizes standard RequestInfo inputs for URL assertions. */
|
||||
import { createHash } from "node:crypto";
|
||||
import { resolve } from "node:path";
|
||||
import { expectDefined } from "@openclaw/normalization-core";
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import {
|
||||
@@ -10,6 +11,7 @@ import {
|
||||
parseNpmViewFields,
|
||||
parseReleaseVerifyBetaArgs,
|
||||
readBoundedJsonResponse,
|
||||
resolveOpenClawNpmPostpublishVerifier,
|
||||
runNpmViewWithRetry,
|
||||
validateClawHubBootstrapEvidence,
|
||||
} from "../../scripts/lib/release-beta-verifier.ts";
|
||||
@@ -91,6 +93,7 @@ describe("parseReleaseVerifyBetaArgs", () => {
|
||||
pluginSelection: [],
|
||||
clawHubBootstrapPlugins: [],
|
||||
evidenceOut: undefined,
|
||||
postpublishVerifier: undefined,
|
||||
skipPostpublish: false,
|
||||
skipGitHubRelease: false,
|
||||
skipClawHub: false,
|
||||
@@ -128,7 +131,8 @@ describe("parseReleaseVerifyBetaArgs", () => {
|
||||
"44",
|
||||
"--evidence-out",
|
||||
".artifacts/release-evidence.json",
|
||||
"--skip-postpublish",
|
||||
"--postpublish-verifier",
|
||||
"/tmp/trusted-postpublish.ts",
|
||||
"--skip-github-release",
|
||||
"--skip-clawhub",
|
||||
"--rerun-failed-clawhub",
|
||||
@@ -145,7 +149,8 @@ describe("parseReleaseVerifyBetaArgs", () => {
|
||||
pluginSelection: ["@openclaw/plugin-a", "@openclaw/plugin-b"],
|
||||
clawHubBootstrapPlugins: ["@openclaw/plugin-b"],
|
||||
evidenceOut: ".artifacts/release-evidence.json",
|
||||
skipPostpublish: true,
|
||||
postpublishVerifier: "/tmp/trusted-postpublish.ts",
|
||||
skipPostpublish: false,
|
||||
skipGitHubRelease: true,
|
||||
skipClawHub: true,
|
||||
rerunFailedClawHub: true,
|
||||
@@ -160,6 +165,27 @@ describe("parseReleaseVerifyBetaArgs", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("only accepts the trusted tooling postpublish verifier override", () => {
|
||||
expect(resolveOpenClawNpmPostpublishVerifier("/tmp/release")).toBe(
|
||||
"/tmp/release/scripts/openclaw-npm-postpublish-verify.ts",
|
||||
);
|
||||
const trustedVerifier = resolve("scripts/openclaw-npm-postpublish-verify.ts");
|
||||
expect(resolveOpenClawNpmPostpublishVerifier("/tmp/release", trustedVerifier)).toBe(
|
||||
trustedVerifier,
|
||||
);
|
||||
expect(() =>
|
||||
resolveOpenClawNpmPostpublishVerifier("/tmp/release", "/tmp/untrusted-verifier.ts"),
|
||||
).toThrow("must select the trusted tooling verifier");
|
||||
expect(() =>
|
||||
parseReleaseVerifyBetaArgs([
|
||||
"2026.5.10-beta.3",
|
||||
"--postpublish-verifier",
|
||||
trustedVerifier,
|
||||
"--skip-postpublish",
|
||||
]),
|
||||
).toThrow("cannot be combined");
|
||||
});
|
||||
|
||||
it("requires exact target and package inputs for bootstrap run verification", () => {
|
||||
expect(() =>
|
||||
parseReleaseVerifyBetaArgs(["2026.5.10-beta.3", "--plugin-clawhub-bootstrap-run", "34"]),
|
||||
|
||||
Reference in New Issue
Block a user