fix(release): preserve upgrade diagnostic probe (#123338)

* fix(release): preserve upgrade diagnostic probe

* test(vitest): reinstantiate contract projects for audits

* style(test): format upgrade diagnostic assertions

* test(ui): isolate route transition outlet fixture
This commit is contained in:
Peter Steinberger
2026-08-13 16:56:43 -07:00
committed by GitHub
parent f66a2c6a29
commit 1287befae7
10 changed files with 114 additions and 46 deletions
+13 -4
View File
@@ -72,6 +72,8 @@ update_restart_seconds=""
BASELINE_INSTALL_LOG="$ARTIFACT_ROOT/baseline-install.log"
UPDATE_JSON="$ARTIFACT_ROOT/update.json"
UPDATE_ERR="$ARTIFACT_ROOT/update.err"
POST_UPDATE_VALIDATE_JSON="$ARTIFACT_ROOT/post-update-validate.json"
POST_UPDATE_VALIDATE_ERR="$ARTIFACT_ROOT/post-update-validate.err"
DOCTOR_LOG="$ARTIFACT_ROOT/doctor.log"
BASELINE_DOCTOR_LOG="$ARTIFACT_ROOT/baseline-doctor.log"
GATEWAY_LOG="$ARTIFACT_ROOT/gateway.log"
@@ -1386,11 +1388,18 @@ update_candidate() {
if [ "$ROOT_MANAGED_VPS" != "1" ]; then
update_env+=(OPENCLAW_ALLOW_ROOT=1)
fi
if ! openclaw_e2e_maybe_timeout "$COMMAND_TIMEOUT" "${update_env[@]}" openclaw "${update_args[@]}" >"$UPDATE_JSON" 2>"$UPDATE_ERR"; then
local update_status=0
openclaw_e2e_maybe_timeout "$COMMAND_TIMEOUT" "${update_env[@]}" openclaw "${update_args[@]}" >"$UPDATE_JSON" 2>"$UPDATE_ERR" || update_status=$?
if [ "$update_status" -ne 0 ]; then
echo "openclaw update failed" >&2
openclaw_e2e_print_log "$UPDATE_ERR" >&2
openclaw_e2e_print_log "$UPDATE_JSON" >&2
return 1
local validate_status=0
openclaw_e2e_maybe_timeout "$COMMAND_TIMEOUT" openclaw config validate --json >"$POST_UPDATE_VALIDATE_JSON" 2>"$POST_UPDATE_VALIDATE_ERR" || validate_status=$?
echo "post-update config validation probe status=$validate_status" >&2
openclaw_e2e_print_log "$POST_UPDATE_VALIDATE_ERR" >&2 || true
openclaw_e2e_print_log "$POST_UPDATE_VALIDATE_JSON" >&2 || true
openclaw_e2e_print_log "$UPDATE_ERR" >&2 || true
openclaw_e2e_print_log "$UPDATE_JSON" >&2 || true
return "$update_status"
fi
if [ "$UPDATE_RESTART_MODE" = "auto-auth" ]; then
update_end="$(node -e "process.stdout.write(String(Date.now()))")"
+7 -5
View File
@@ -465,11 +465,13 @@ update_status=$?
set -e
if [ "$update_status" -ne 0 ]; then
echo "openclaw update failed" >&2
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.err >&2
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.json >&2
openclaw_e2e_maybe_timeout "$command_timeout" openclaw config validate --json >/tmp/openclaw-upgrade-survivor-post-update-validate.json 2>/tmp/openclaw-upgrade-survivor-post-update-validate.err || true
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-post-update-validate.err >&2
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-post-update-validate.json >&2
validate_status=0
openclaw_e2e_maybe_timeout "$command_timeout" openclaw config validate --json >/tmp/openclaw-upgrade-survivor-post-update-validate.json 2>/tmp/openclaw-upgrade-survivor-post-update-validate.err || validate_status=$?
echo "post-update config validation probe status=$validate_status" >&2
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-post-update-validate.err >&2 || true
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-post-update-validate.json >&2 || true
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.err >&2 || true
openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.json >&2 || true
exit "$update_status"
fi
if [ -n "${OPENCLAW_CLAWHUB_URL:-}" ]; then
+35
View File
@@ -185,6 +185,15 @@ function expectTextToIncludeAll(text: string, snippets: readonly string[]): void
}
}
function expectTextToIncludeInOrder(text: string, snippets: readonly string[]): void {
let offset = 0;
for (const snippet of snippets) {
const index = text.indexOf(snippet, offset);
expect(index).toBeGreaterThanOrEqual(offset);
offset = index + snippet.length;
}
}
function extractUpgradeSurvivorSupervisor(script: string): string {
const match = script.match(
/cat >"\$supervisor_script" <<'SUPERVISOR'\n(?<source>[\s\S]*?)\nSUPERVISOR/u,
@@ -3284,6 +3293,32 @@ if (starts === 1) {
const runner = readFileSync(UPGRADE_SURVIVOR_DOCKER_E2E_PATH, "utf8");
const publishedRunner = readFileSync(UPGRADE_SURVIVOR_RUN_SCRIPT, "utf8");
expectTextToIncludeInOrder(runner, [
"update_status=$?",
'if [ "$update_status" -ne 0 ]; then',
'echo "openclaw update failed" >&2',
"openclaw config validate --json >/tmp/openclaw-upgrade-survivor-post-update-validate.json",
'echo "post-update config validation probe status=$validate_status" >&2',
"openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-post-update-validate.err >&2 || true",
"openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-post-update-validate.json >&2 || true",
"openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.err >&2 || true",
"openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.json >&2 || true",
'exit "$update_status"',
]);
expectTextToIncludeInOrder(publishedRunner, [
"local update_status=0",
'openclaw "${update_args[@]}" >"$UPDATE_JSON" 2>"$UPDATE_ERR" || update_status=$?',
'if [ "$update_status" -ne 0 ]; then',
'echo "openclaw update failed" >&2',
'openclaw config validate --json >"$POST_UPDATE_VALIDATE_JSON"',
'echo "post-update config validation probe status=$validate_status" >&2',
'openclaw_e2e_print_log "$POST_UPDATE_VALIDATE_ERR" >&2 || true',
'openclaw_e2e_print_log "$POST_UPDATE_VALIDATE_JSON" >&2 || true',
'openclaw_e2e_print_log "$UPDATE_ERR" >&2 || true',
'openclaw_e2e_print_log "$UPDATE_JSON" >&2 || true',
'return "$update_status"',
]);
expectTextToIncludeAll(runner, [
"openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.err",
"openclaw_e2e_print_log /tmp/openclaw-upgrade-survivor-update.json",
+9 -5
View File
@@ -30,8 +30,12 @@ const bundledUnitExcludePatterns = unitTestAdditionalExcludePatterns.filter(
),
);
export default createUnitVitestConfigWithOptions(process.env, {
includePatterns: bundledPluginDependentUnitTestFiles,
extraExcludePatterns: bundledUnitExcludePatterns,
name: "bundled",
});
export function createBundledVitestConfig(env: Record<string, string | undefined> = process.env) {
return createUnitVitestConfigWithOptions(env, {
includePatterns: bundledPluginDependentUnitTestFiles,
extraExcludePatterns: bundledUnitExcludePatterns,
name: "bundled",
});
}
export default createBundledVitestConfig();
@@ -4,11 +4,13 @@ import {
createContractsVitestConfig,
} from "./vitest.contracts-shared.ts";
export default createContractsVitestConfig(
channelConfigContractPatterns,
process.env,
process.argv,
{
export function createContractsChannelConfigVitestConfig(
env: Record<string, string | undefined> = process.env,
argv: string[] = process.argv,
) {
return createContractsVitestConfig(channelConfigContractPatterns, env, argv, {
name: "contracts-channel-config",
},
);
});
}
export default createContractsChannelConfigVitestConfig();
@@ -4,11 +4,13 @@ import {
createContractsVitestConfig,
} from "./vitest.contracts-shared.ts";
export default createContractsVitestConfig(
channelRegistryContractPatterns,
process.env,
process.argv,
{
export function createContractsChannelRegistryVitestConfig(
env: Record<string, string | undefined> = process.env,
argv: string[] = process.argv,
) {
return createContractsVitestConfig(channelRegistryContractPatterns, env, argv, {
name: "contracts-channel-registry",
},
);
});
}
export default createContractsChannelRegistryVitestConfig();
@@ -4,11 +4,13 @@ import {
createContractsVitestConfig,
} from "./vitest.contracts-shared.ts";
export default createContractsVitestConfig(
channelSessionContractPatterns,
process.env,
process.argv,
{
export function createContractsChannelSessionVitestConfig(
env: Record<string, string | undefined> = process.env,
argv: string[] = process.argv,
) {
return createContractsVitestConfig(channelSessionContractPatterns, env, argv, {
name: "contracts-channel-session",
},
);
});
}
export default createContractsChannelSessionVitestConfig();
@@ -4,11 +4,13 @@ import {
createContractsVitestConfig,
} from "./vitest.contracts-shared.ts";
export default createContractsVitestConfig(
channelSurfaceContractPatterns,
process.env,
process.argv,
{
export function createContractsChannelSurfaceVitestConfig(
env: Record<string, string | undefined> = process.env,
argv: string[] = process.argv,
) {
return createContractsVitestConfig(channelSurfaceContractPatterns, env, argv, {
name: "contracts-channel-surface",
},
);
});
}
export default createContractsChannelSurfaceVitestConfig();
+10 -3
View File
@@ -1,6 +1,13 @@
// Vitest contracts plugin config wires the contracts plugin test shard.
import { createContractsVitestConfig, pluginContractPatterns } from "./vitest.contracts-shared.ts";
export default createContractsVitestConfig(pluginContractPatterns, process.env, process.argv, {
name: "contracts-plugin",
});
export function createContractsPluginVitestConfig(
env: Record<string, string | undefined> = process.env,
argv: string[] = process.argv,
) {
return createContractsVitestConfig(pluginContractPatterns, env, argv, {
name: "contracts-plugin",
});
}
export default createContractsPluginVitestConfig();
+4 -1
View File
@@ -5,7 +5,10 @@ function testDocumentWithOutlet(animate = vi.fn()) {
const outlet = document.createElement("openclaw-router-outlet") as HTMLElement & {
updateComplete: Promise<void>;
};
outlet.updateComplete = Promise.resolve();
Object.defineProperty(outlet, "updateComplete", {
configurable: true,
value: Promise.resolve(),
});
outlet.animate = animate;
document.body.append(outlet);
return {