From abb856ece4798c726e7786ecbc0b46cd69e52070 Mon Sep 17 00:00:00 2001 From: Patrick Erichsen Date: Mon, 10 Aug 2026 18:45:42 -0700 Subject: [PATCH] fix(release): restore frozen beta validation (#121791) Punchcard-Session: coral-summit-brook-8j --- .github/workflows/ci.yml | 21 +++++++++++++++++++++ scripts/e2e/lib/upgrade-survivor/run.sh | 6 +++++- test/scripts/ci-workflow-guards.test.ts | 23 ++++++++++++++++++++++- test/scripts/docker-build-helper.test.ts | 5 ++++- 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5292980a64ef..4de171bb3617 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2366,6 +2366,27 @@ jobs: fi ;; dependencies) + # The beta.1 release commit backported this workflow-only helper after its + # Knip config was frozen. Register that exact executable root without + # weakening the target's remaining dead-code scan. + release_evidence_entry='"scripts/generate-dependency-release-evidence.mts!"' + if [[ + "$FROZEN_TARGET" == "true" && + -f scripts/generate-dependency-release-evidence.mts && + -f config/knip.config.ts + ]] && ! grep -Fq "$release_evidence_entry" config/knip.config.ts; then + RELEASE_EVIDENCE_ENTRY="$release_evidence_entry" node --input-type=module -e ' + import { readFileSync, writeFileSync } from "node:fs"; + const configPath = "config/knip.config.ts"; + const marker = "const repositoryScriptEntries = ["; + const source = readFileSync(configPath, "utf8"); + if (!source.includes(marker)) throw new Error(`${configPath} is missing ${marker}`); + writeFileSync(configPath, source.replace( + marker, + `${marker}\n ${process.env.RELEASE_EVIDENCE_ENTRY},`, + )); + ' + fi if has_package_script "deadcode:dependencies" && has_package_script "deadcode:unused-files"; then # The three deadcode scripts spawn independent Knip scans over diff --git a/scripts/e2e/lib/upgrade-survivor/run.sh b/scripts/e2e/lib/upgrade-survivor/run.sh index d0291970da2f..6e43fb994b12 100644 --- a/scripts/e2e/lib/upgrade-survivor/run.sh +++ b/scripts/e2e/lib/upgrade-survivor/run.sh @@ -1537,6 +1537,10 @@ phase configure-plugin-registry configure_plugin_registry phase update-candidate update_candidate if [ -n "${OPENCLAW_CLAWHUB_URL:-}" ]; then clawhub_security_mode="required" + prepublish_package="@openclaw/whatsapp" + if [ "$SCENARIO" = "configured-plugin-installs" ]; then + prepublish_package="@openclaw/matrix" + fi # 2026.6.35 predates the release-security endpoint. The trusted fixture still # asserts its exact older request contract instead of accepting arbitrary IO. if [ "$candidate_version" = "2026.6.35" ]; then @@ -1544,7 +1548,7 @@ if [ -n "${OPENCLAW_CLAWHUB_URL:-}" ]; then fi phase assert-prepublish-requests node \ "${OPENCLAW_UPGRADE_SURVIVOR_CLAWHUB_FIXTURE_SERVER:-scripts/e2e/lib/clawhub-fixture-server.cjs}" \ - assert-prepublish-requests "$OPENCLAW_CLAWHUB_URL" "@openclaw/matrix" "$candidate_version" "$clawhub_security_mode" + assert-prepublish-requests "$OPENCLAW_CLAWHUB_URL" "$prepublish_package" "$candidate_version" "$clawhub_security_mode" fi phase root-managed-vps-cli-usable assert_root_managed_vps_cli_usable phase assert-legacy-plugin-dependency-debris-before-doctor assert_legacy_plugin_dependency_debris_before_doctor diff --git a/test/scripts/ci-workflow-guards.test.ts b/test/scripts/ci-workflow-guards.test.ts index bde5fc535cfb..1aa62ecbf9de 100644 --- a/test/scripts/ci-workflow-guards.test.ts +++ b/test/scripts/ci-workflow-guards.test.ts @@ -970,7 +970,11 @@ function runProtocolSinceFixture(checkout: string, baseSha: string) { }); } -function runDependencyCheckFixture(options: { historicalTarget: boolean; scripts: string[] }): { +function runDependencyCheckFixture(options: { + historicalTarget: boolean; + releaseToolingEntry?: boolean; + scripts: string[]; +}): { calls: string[]; output: string; status: number | null; @@ -986,9 +990,23 @@ function runDependencyCheckFixture(options: { historicalTarget: boolean; scripts scripts: Object.fromEntries(options.scripts.map((name) => [name, "true"])), })}\n`, ); + if (options.releaseToolingEntry) { + mkdirSync(path.join(root, "config"), { recursive: true }); + mkdirSync(path.join(root, "scripts"), { recursive: true }); + writeFileSync( + path.join(root, "config/knip.config.ts"), + "const repositoryScriptEntries = [\n] as const;\n", + ); + writeFileSync(path.join(root, "scripts/generate-dependency-release-evidence.mts"), ""); + } writeExecutable(path.join(fakeBin, "pnpm"), [ "#!/usr/bin/env bash", "set -euo pipefail", + 'if [ "${EXPECT_RELEASE_TOOLING_ENTRY:-false}" = "true" ] &&', + " ! grep -Fq '\"scripts/generate-dependency-release-evidence.mts!\"' config/knip.config.ts; then", + ' echo "release-only helper is missing from Knip entries" >&2', + " exit 1", + "fi", 'printf "%s\\n" "$*" >> "$PNPM_CALLS"', ]); const checkShardRun = readCiWorkflow().jobs["check-shard"].steps.find( @@ -999,6 +1017,8 @@ function runDependencyCheckFixture(options: { historicalTarget: boolean; scripts encoding: "utf8", env: { ...process.env, + EXPECT_RELEASE_TOOLING_ENTRY: options.releaseToolingEntry ? "true" : "false", + FROZEN_TARGET: options.historicalTarget ? "true" : "false", FORMAT_CHECK: "false", HISTORICAL_TARGET: options.historicalTarget ? "true" : "false", PATH: `${fakeBin}:${process.env.PATH ?? ""}`, @@ -4842,6 +4862,7 @@ printf '%s\n' "\${CURL_SUCCESS_IP:-203.0.113.7}" const frozenWithExports = runDependencyCheckFixture({ historicalTarget: true, + releaseToolingEntry: true, scripts: ["deadcode:dependencies", "deadcode:unused-files", "deadcode:exports"], }); expect(frozenWithExports.status, frozenWithExports.output).toBe(0); diff --git a/test/scripts/docker-build-helper.test.ts b/test/scripts/docker-build-helper.test.ts index a331cfc1240a..6f5665e37e0d 100644 --- a/test/scripts/docker-build-helper.test.ts +++ b/test/scripts/docker-build-helper.test.ts @@ -2370,8 +2370,11 @@ docker_e2e_docker_run_cmd run demo publishedRunner.indexOf("phase assert-prepublish-requests node"), ); expect(publishedRunner).toContain('if [ "$candidate_version" = "2026.6.35" ]; then'); + expect(publishedRunner).toContain('prepublish_package="@openclaw/whatsapp"'); + expect(publishedRunner).toContain('if [ "$SCENARIO" = "configured-plugin-installs" ]; then'); + expect(publishedRunner).toContain('prepublish_package="@openclaw/matrix"'); expect(publishedRunner).toContain( - 'assert-prepublish-requests "$OPENCLAW_CLAWHUB_URL" "@openclaw/matrix" "$candidate_version"', + 'assert-prepublish-requests "$OPENCLAW_CLAWHUB_URL" "$prepublish_package" "$candidate_version"', ); expect(publishedRunner).toContain('"$clawhub_security_mode"'); expect(publishedRunner.indexOf("phase assert-prepublish-requests node")).toBeLessThan(