test: harden parallels beta smoke flows

This commit is contained in:
Peter Steinberger 2026-03-14 05:54:41 +00:00
parent e7d9648fba
commit 6e251dcf68
No known key found for this signature in database
4 changed files with 207 additions and 20 deletions

View File

@ -203,6 +203,8 @@
- Vocabulary: "makeup" = "mac app".
- Parallels macOS retests: use the snapshot most closely named like `macOS 26.3.1 fresh` when the user asks for a clean/fresh macOS rerun; avoid older Tahoe snapshots unless explicitly requested.
- Parallels beta smoke: use `--target-package-spec openclaw@<beta-version>` for the beta artifact, and pin the stable side with both `--install-version <stable-version>` and `--latest-version <stable-version>` for upgrade runs. npm dist-tags can move mid-run.
- Parallels beta smoke, Windows nuance: old stable `2026.3.12` still prints the Unicode Windows onboarding banner, so mojibake during the stable precheck log is expected there. Judge the beta package by the post-upgrade lane.
- Parallels macOS smoke playbook:
- `prlctl exec` is fine for deterministic repo commands, but it can misrepresent interactive shell behavior (`PATH`, `HOME`, `curl | bash`, shebang resolution). For installer parity or shell-sensitive repros, prefer the guest Terminal or `prlctl enter`.
- Fresh Tahoe snapshot current reality: `brew` exists, `node` may not be on `PATH` in noninteractive guest exec. Use absolute `/opt/homebrew/bin/node` for repo/CLI runs when needed.

View File

@ -10,6 +10,8 @@ HOST_PORT="18427"
HOST_PORT_EXPLICIT=0
HOST_IP=""
LATEST_VERSION=""
INSTALL_VERSION=""
TARGET_PACKAGE_SPEC=""
JSON_OUTPUT=0
KEEP_SERVER=0
@ -41,6 +43,14 @@ say() {
printf '==> %s\n' "$*"
}
artifact_label() {
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
printf 'target package tgz'
return
fi
printf 'current main tgz'
}
warn() {
printf 'warn: %s\n' "$*" >&2
}
@ -72,6 +82,10 @@ Options:
--host-port <port> Host HTTP port for current-main tgz. Default: 18427
--host-ip <ip> Override Parallels host IP.
--latest-version <ver> Override npm latest version lookup.
--install-version <ver> Pin site-installer version/dist-tag for the baseline lane.
--target-package-spec <npm-spec>
Install this npm package tarball instead of packing current main.
Example: openclaw@2026.3.13-beta.1
--keep-server Leave temp host HTTP server running.
--json Print machine-readable JSON summary.
-h, --help Show help.
@ -113,6 +127,14 @@ while [[ $# -gt 0 ]]; do
LATEST_VERSION="$2"
shift 2
;;
--install-version)
INSTALL_VERSION="$2"
shift 2
;;
--target-package-spec)
TARGET_PACKAGE_SPEC="$2"
shift 2
;;
--keep-server)
KEEP_SERVER=1
shift
@ -299,10 +321,26 @@ ensure_current_build() {
[[ "$build_commit" == "$head" ]] || die "dist/build-info.json still does not match HEAD after build"
}
extract_package_version_from_tgz() {
tar -xOf "$1" package/package.json | python3 -c 'import json, sys; print(json.load(sys.stdin)["version"])'
}
pack_main_tgz() {
local short_head pkg
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
say "Pack target package tgz: $TARGET_PACKAGE_SPEC"
pkg="$(
npm pack "$TARGET_PACKAGE_SPEC" --ignore-scripts --json --pack-destination "$MAIN_TGZ_DIR" \
| python3 -c 'import json, sys; data = json.load(sys.stdin); print(data[-1]["filename"])'
)"
MAIN_TGZ_PATH="$MAIN_TGZ_DIR/$(basename "$pkg")"
TARGET_EXPECT_VERSION="$(extract_package_version_from_tgz "$MAIN_TGZ_PATH")"
say "Packed $MAIN_TGZ_PATH"
say "Target package version: $TARGET_EXPECT_VERSION"
return
fi
say "Pack current main tgz"
ensure_current_build
local short_head pkg
short_head="$(git rev-parse --short HEAD)"
pkg="$(
npm pack --ignore-scripts --json --pack-destination "$MAIN_TGZ_DIR" \
@ -314,6 +352,14 @@ pack_main_tgz() {
tar -xOf "$MAIN_TGZ_PATH" package/dist/build-info.json
}
verify_target_version() {
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
verify_version_contains "$TARGET_EXPECT_VERSION"
return
fi
verify_version_contains "$(git rev-parse --short=7 HEAD)"
}
start_server() {
local host_ip="$1"
local artifact probe_url attempt
@ -321,7 +367,7 @@ start_server() {
attempt=0
while :; do
attempt=$((attempt + 1))
say "Serve current main tgz on $host_ip:$HOST_PORT"
say "Serve $(artifact_label) on $host_ip:$HOST_PORT"
(
cd "$MAIN_TGZ_DIR"
exec python3 -m http.server "$HOST_PORT" --bind 0.0.0.0
@ -344,8 +390,12 @@ start_server() {
}
install_latest_release() {
local version_args=()
if [[ -n "$INSTALL_VERSION" ]]; then
version_args=(--version "$INSTALL_VERSION")
fi
guest_exec curl -fsSL "$INSTALL_URL" -o /tmp/openclaw-install.sh
guest_exec /usr/bin/env OPENCLAW_NO_ONBOARD=1 bash /tmp/openclaw-install.sh --no-onboard
guest_exec /usr/bin/env OPENCLAW_NO_ONBOARD=1 bash /tmp/openclaw-install.sh "${version_args[@]}" --no-onboard
guest_exec openclaw --version
}
@ -478,6 +528,8 @@ summary = {
"snapshotId": os.environ["SUMMARY_SNAPSHOT_ID"],
"mode": os.environ["SUMMARY_MODE"],
"latestVersion": os.environ["SUMMARY_LATEST_VERSION"],
"installVersion": os.environ["SUMMARY_INSTALL_VERSION"],
"targetPackageSpec": os.environ["SUMMARY_TARGET_PACKAGE_SPEC"],
"currentHead": os.environ["SUMMARY_CURRENT_HEAD"],
"runDir": os.environ["SUMMARY_RUN_DIR"],
"daemon": os.environ["SUMMARY_DAEMON_STATUS"],
@ -509,7 +561,7 @@ run_fresh_main_lane() {
phase_run "fresh.install-latest-bootstrap" "$TIMEOUT_INSTALL_S" install_latest_release
phase_run "fresh.install-main" "$TIMEOUT_INSTALL_S" install_main_tgz "$host_ip" "openclaw-main-fresh.tgz"
FRESH_MAIN_VERSION="$(extract_last_version "$(phase_log_path fresh.install-main)")"
phase_run "fresh.verify-main-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$(git rev-parse --short=7 HEAD)"
phase_run "fresh.verify-main-version" "$TIMEOUT_VERIFY_S" verify_target_version
phase_run "fresh.onboard-ref" "$TIMEOUT_ONBOARD_S" run_ref_onboard
FRESH_GATEWAY_STATUS="skipped-no-detached-linux-gateway"
phase_run "fresh.first-local-agent-turn" "$TIMEOUT_AGENT_S" verify_local_turn
@ -526,7 +578,7 @@ run_upgrade_lane() {
phase_run "upgrade.verify-latest-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$LATEST_VERSION"
phase_run "upgrade.install-main" "$TIMEOUT_INSTALL_S" install_main_tgz "$host_ip" "openclaw-main-upgrade.tgz"
UPGRADE_MAIN_VERSION="$(extract_last_version "$(phase_log_path upgrade.install-main)")"
phase_run "upgrade.verify-main-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$(git rev-parse --short=7 HEAD)"
phase_run "upgrade.verify-main-version" "$TIMEOUT_VERIFY_S" verify_target_version
phase_run "upgrade.onboard-ref" "$TIMEOUT_ONBOARD_S" run_ref_onboard
UPGRADE_GATEWAY_STATUS="skipped-no-detached-linux-gateway"
phase_run "upgrade.first-local-agent-turn" "$TIMEOUT_AGENT_S" verify_local_turn
@ -582,6 +634,8 @@ SUMMARY_JSON_PATH="$(
SUMMARY_SNAPSHOT_ID="$SNAPSHOT_ID" \
SUMMARY_MODE="$MODE" \
SUMMARY_LATEST_VERSION="$LATEST_VERSION" \
SUMMARY_INSTALL_VERSION="$INSTALL_VERSION" \
SUMMARY_TARGET_PACKAGE_SPEC="$TARGET_PACKAGE_SPEC" \
SUMMARY_CURRENT_HEAD="$(git rev-parse --short HEAD)" \
SUMMARY_RUN_DIR="$RUN_DIR" \
SUMMARY_DAEMON_STATUS="$DAEMON_STATUS" \
@ -601,6 +655,12 @@ if [[ "$JSON_OUTPUT" -eq 1 ]]; then
cat "$SUMMARY_JSON_PATH"
else
printf '\nSummary:\n'
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
printf ' target-package: %s\n' "$TARGET_PACKAGE_SPEC"
fi
if [[ -n "$INSTALL_VERSION" ]]; then
printf ' baseline-install-version: %s\n' "$INSTALL_VERSION"
fi
printf ' daemon: %s\n' "$DAEMON_STATUS"
printf ' fresh-main: %s (%s)\n' "$FRESH_MAIN_STATUS" "$FRESH_MAIN_VERSION"
printf ' latest->main: %s (%s)\n' "$UPGRADE_STATUS" "$UPGRADE_MAIN_VERSION"

View File

@ -12,6 +12,8 @@ HOST_PORT="18425"
HOST_PORT_EXPLICIT=0
HOST_IP=""
LATEST_VERSION=""
INSTALL_VERSION=""
TARGET_PACKAGE_SPEC=""
KEEP_SERVER=0
CHECK_LATEST_REF=1
JSON_OUTPUT=0
@ -46,6 +48,14 @@ say() {
printf '==> %s\n' "$*"
}
artifact_label() {
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
printf 'target package tgz'
return
fi
printf 'current main tgz'
}
warn() {
printf 'warn: %s\n' "$*" >&2
}
@ -81,8 +91,8 @@ Options:
--snapshot-hint <name> Snapshot name substring/fuzzy match.
Default: "macOS 26.3.1 fresh"
--mode <fresh|upgrade|both>
fresh = fresh snapshot -> current main tgz -> onboard smoke
upgrade = fresh snapshot -> latest release -> current main tgz -> onboard smoke
fresh = fresh snapshot -> target package/current main tgz -> onboard smoke
upgrade = fresh snapshot -> latest release -> target package/current main tgz -> onboard smoke
both = run both lanes
--openai-api-key-env <var> Host env var name for OpenAI API key.
Default: OPENAI_API_KEY
@ -90,6 +100,10 @@ Options:
--host-port <port> Host HTTP port for current-main tgz. Default: 18425
--host-ip <ip> Override Parallels host IP.
--latest-version <ver> Override npm latest version lookup.
--install-version <ver> Pin site-installer version/dist-tag for the baseline lane.
--target-package-spec <npm-spec>
Install this npm package tarball instead of packing current main.
Example: openclaw@2026.3.13-beta.1
--skip-latest-ref-check Skip the known latest-release ref-mode precheck in upgrade lane.
--keep-server Leave temp host HTTP server running.
--json Print machine-readable JSON summary.
@ -132,6 +146,14 @@ while [[ $# -gt 0 ]]; do
LATEST_VERSION="$2"
shift 2
;;
--install-version)
INSTALL_VERSION="$2"
shift 2
;;
--target-package-spec)
TARGET_PACKAGE_SPEC="$2"
shift 2
;;
--skip-latest-ref-check)
CHECK_LATEST_REF=0
shift
@ -343,12 +365,16 @@ resolve_latest_version() {
}
install_latest_release() {
local install_url_q
local install_url_q version_arg_q
install_url_q="$(shell_quote "$INSTALL_URL")"
version_arg_q=""
if [[ -n "$INSTALL_VERSION" ]]; then
version_arg_q=" --version $(shell_quote "$INSTALL_VERSION")"
fi
guest_current_user_sh "$(cat <<EOF
export OPENCLAW_NO_ONBOARD=1
curl -fsSL $install_url_q -o /tmp/openclaw-install.sh
bash /tmp/openclaw-install.sh
bash /tmp/openclaw-install.sh${version_arg_q}
$GUEST_OPENCLAW_BIN --version
EOF
)"
@ -370,10 +396,26 @@ verify_version_contains() {
esac
}
extract_package_version_from_tgz() {
tar -xOf "$1" package/package.json | python3 -c 'import json, sys; print(json.load(sys.stdin)["version"])'
}
pack_main_tgz() {
local short_head pkg
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
say "Pack target package tgz: $TARGET_PACKAGE_SPEC"
pkg="$(
npm pack "$TARGET_PACKAGE_SPEC" --ignore-scripts --json --pack-destination "$MAIN_TGZ_DIR" \
| python3 -c 'import json, sys; data = json.load(sys.stdin); print(data[-1]["filename"])'
)"
MAIN_TGZ_PATH="$MAIN_TGZ_DIR/$(basename "$pkg")"
TARGET_EXPECT_VERSION="$(extract_package_version_from_tgz "$MAIN_TGZ_PATH")"
say "Packed $MAIN_TGZ_PATH"
say "Target package version: $TARGET_EXPECT_VERSION"
return
fi
say "Pack current main tgz"
ensure_current_build
local short_head pkg
short_head="$(git rev-parse --short HEAD)"
pkg="$(
npm pack --ignore-scripts --json --pack-destination "$MAIN_TGZ_DIR" \
@ -385,6 +427,14 @@ pack_main_tgz() {
tar -xOf "$MAIN_TGZ_PATH" package/dist/build-info.json
}
verify_target_version() {
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
verify_version_contains "$TARGET_EXPECT_VERSION"
return
fi
verify_version_contains "$(git rev-parse --short=7 HEAD)"
}
current_build_commit() {
python3 - <<'PY'
import json
@ -438,7 +488,7 @@ ensure_current_build() {
start_server() {
local host_ip="$1"
say "Serve current main tgz on $host_ip:$HOST_PORT"
say "Serve $(artifact_label) on $host_ip:$HOST_PORT"
(
cd "$MAIN_TGZ_DIR"
exec python3 -m http.server "$HOST_PORT" --bind 0.0.0.0
@ -587,6 +637,8 @@ summary = {
"snapshotId": os.environ["SUMMARY_SNAPSHOT_ID"],
"mode": os.environ["SUMMARY_MODE"],
"latestVersion": os.environ["SUMMARY_LATEST_VERSION"],
"installVersion": os.environ["SUMMARY_INSTALL_VERSION"],
"targetPackageSpec": os.environ["SUMMARY_TARGET_PACKAGE_SPEC"],
"currentHead": os.environ["SUMMARY_CURRENT_HEAD"],
"runDir": os.environ["SUMMARY_RUN_DIR"],
"freshMain": {
@ -632,7 +684,7 @@ run_fresh_main_lane() {
phase_run "fresh.restore-snapshot" "$TIMEOUT_SNAPSHOT_S" restore_snapshot "$snapshot_id"
phase_run "fresh.install-main" "$TIMEOUT_INSTALL_S" install_main_tgz "$host_ip" "openclaw-main-fresh.tgz"
FRESH_MAIN_VERSION="$(extract_last_version "$(phase_log_path fresh.install-main)")"
phase_run "fresh.verify-main-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$(git rev-parse --short=7 HEAD)"
phase_run "fresh.verify-main-version" "$TIMEOUT_VERIFY_S" verify_target_version
phase_run "fresh.verify-bundle-permissions" "$TIMEOUT_PERMISSION_S" verify_bundle_permissions
phase_run "fresh.onboard-ref" "$TIMEOUT_ONBOARD_S" run_ref_onboard
phase_run "fresh.gateway-status" "$TIMEOUT_GATEWAY_S" verify_gateway
@ -659,7 +711,7 @@ run_upgrade_lane() {
fi
phase_run "upgrade.install-main" "$TIMEOUT_INSTALL_S" install_main_tgz "$host_ip" "openclaw-main-upgrade.tgz"
UPGRADE_MAIN_VERSION="$(extract_last_version "$(phase_log_path upgrade.install-main)")"
phase_run "upgrade.verify-main-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$(git rev-parse --short=7 HEAD)"
phase_run "upgrade.verify-main-version" "$TIMEOUT_VERIFY_S" verify_target_version
phase_run "upgrade.verify-bundle-permissions" "$TIMEOUT_PERMISSION_S" verify_bundle_permissions
phase_run "upgrade.onboard-ref" "$TIMEOUT_ONBOARD_S" run_ref_onboard
phase_run "upgrade.gateway-status" "$TIMEOUT_GATEWAY_S" verify_gateway
@ -721,6 +773,8 @@ SUMMARY_JSON_PATH="$(
SUMMARY_SNAPSHOT_ID="$SNAPSHOT_ID" \
SUMMARY_MODE="$MODE" \
SUMMARY_LATEST_VERSION="$LATEST_VERSION" \
SUMMARY_INSTALL_VERSION="$INSTALL_VERSION" \
SUMMARY_TARGET_PACKAGE_SPEC="$TARGET_PACKAGE_SPEC" \
SUMMARY_CURRENT_HEAD="$(git rev-parse --short HEAD)" \
SUMMARY_RUN_DIR="$RUN_DIR" \
SUMMARY_FRESH_MAIN_STATUS="$FRESH_MAIN_STATUS" \
@ -740,6 +794,12 @@ if [[ "$JSON_OUTPUT" -eq 1 ]]; then
cat "$SUMMARY_JSON_PATH"
else
printf '\nSummary:\n'
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
printf ' target-package: %s\n' "$TARGET_PACKAGE_SPEC"
fi
if [[ -n "$INSTALL_VERSION" ]]; then
printf ' baseline-install-version: %s\n' "$INSTALL_VERSION"
fi
printf ' fresh-main: %s (%s)\n' "$FRESH_MAIN_STATUS" "$FRESH_MAIN_VERSION"
printf ' latest->main precheck: %s (%s)\n' "$UPGRADE_PRECHECK_STATUS" "$LATEST_INSTALLED_VERSION"
printf ' latest->main: %s (%s)\n' "$UPGRADE_STATUS" "$UPGRADE_MAIN_VERSION"

View File

@ -10,6 +10,8 @@ HOST_PORT="18426"
HOST_PORT_EXPLICIT=0
HOST_IP=""
LATEST_VERSION=""
INSTALL_VERSION=""
TARGET_PACKAGE_SPEC=""
JSON_OUTPUT=0
KEEP_SERVER=0
CHECK_LATEST_REF=1
@ -44,6 +46,14 @@ say() {
printf '==> %s\n' "$*"
}
artifact_label() {
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
printf 'target package tgz'
return
fi
printf 'current main tgz'
}
warn() {
printf 'warn: %s\n' "$*" >&2
}
@ -77,6 +87,10 @@ Options:
--host-port <port> Host HTTP port for current-main tgz. Default: 18426
--host-ip <ip> Override Parallels host IP.
--latest-version <ver> Override npm latest version lookup.
--install-version <ver> Pin site-installer version/dist-tag for the baseline lane.
--target-package-spec <npm-spec>
Install this npm package tarball instead of packing current main.
Example: openclaw@2026.3.13-beta.1
--skip-latest-ref-check Skip latest-release ref-mode precheck.
--keep-server Leave temp host HTTP server running.
--json Print machine-readable JSON summary.
@ -119,6 +133,14 @@ while [[ $# -gt 0 ]]; do
LATEST_VERSION="$2"
shift 2
;;
--install-version)
INSTALL_VERSION="$2"
shift 2
;;
--target-package-spec)
TARGET_PACKAGE_SPEC="$2"
shift 2
;;
--skip-latest-ref-check)
CHECK_LATEST_REF=0
shift
@ -421,6 +443,8 @@ summary = {
"snapshotId": os.environ["SUMMARY_SNAPSHOT_ID"],
"mode": os.environ["SUMMARY_MODE"],
"latestVersion": os.environ["SUMMARY_LATEST_VERSION"],
"installVersion": os.environ["SUMMARY_INSTALL_VERSION"],
"targetPackageSpec": os.environ["SUMMARY_TARGET_PACKAGE_SPEC"],
"currentHead": os.environ["SUMMARY_CURRENT_HEAD"],
"runDir": os.environ["SUMMARY_RUN_DIR"],
"freshMain": {
@ -556,6 +580,7 @@ ensure_guest_git() {
return
fi
guest_exec cmd.exe /d /s /c "if exist \"%LOCALAPPDATA%\\OpenClaw\\deps\\portable-git\" rmdir /s /q \"%LOCALAPPDATA%\\OpenClaw\\deps\\portable-git\""
guest_exec cmd.exe /d /s /c "if not exist \"%LOCALAPPDATA%\\OpenClaw\\deps\" mkdir \"%LOCALAPPDATA%\\OpenClaw\\deps\""
guest_exec cmd.exe /d /s /c "mkdir \"%LOCALAPPDATA%\\OpenClaw\\deps\\portable-git\""
guest_exec cmd.exe /d /s /c "curl.exe -fsSL \"$mingit_url\" -o \"%TEMP%\\$MINGIT_ZIP_NAME\""
guest_exec cmd.exe /d /s /c "tar.exe -xf \"%TEMP%\\$MINGIT_ZIP_NAME\" -C \"%LOCALAPPDATA%\\OpenClaw\\deps\\portable-git\""
@ -563,9 +588,30 @@ ensure_guest_git() {
}
pack_main_tgz() {
say "Pack current main tgz"
ensure_current_build
local mingit_name mingit_url
local mingit_name mingit_url short_head pkg
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
say "Pack target package tgz: $TARGET_PACKAGE_SPEC"
mapfile -t mingit_meta < <(resolve_mingit_download)
mingit_name="${mingit_meta[0]}"
mingit_url="${mingit_meta[1]}"
MINGIT_ZIP_NAME="$mingit_name"
MINGIT_ZIP_PATH="$MAIN_TGZ_DIR/$mingit_name"
if [[ ! -f "$MINGIT_ZIP_PATH" ]]; then
say "Download $MINGIT_ZIP_NAME"
curl -fsSL "$mingit_url" -o "$MINGIT_ZIP_PATH"
fi
pkg="$(
npm pack "$TARGET_PACKAGE_SPEC" --ignore-scripts --json --pack-destination "$MAIN_TGZ_DIR" \
| python3 -c 'import json, sys; data = json.load(sys.stdin); print(data[-1]["filename"])'
)"
MAIN_TGZ_PATH="$MAIN_TGZ_DIR/$(basename "$pkg")"
TARGET_EXPECT_VERSION="$(tar -xOf "$MAIN_TGZ_PATH" package/package.json | python3 -c "import json, sys; print(json.load(sys.stdin)['version'])")"
say "Packed $MAIN_TGZ_PATH"
say "Target package version: $TARGET_EXPECT_VERSION"
return
fi
say "Pack current main tgz"
ensure_current_build
mapfile -t mingit_meta < <(resolve_mingit_download)
mingit_name="${mingit_meta[0]}"
mingit_url="${mingit_meta[1]}"
@ -575,7 +621,6 @@ pack_main_tgz() {
say "Download $MINGIT_ZIP_NAME"
curl -fsSL "$mingit_url" -o "$MINGIT_ZIP_PATH"
fi
local short_head pkg
short_head="$(git rev-parse --short HEAD)"
pkg="$(
npm pack --ignore-scripts --json --pack-destination "$MAIN_TGZ_DIR" \
@ -587,6 +632,14 @@ pack_main_tgz() {
tar -xOf "$MAIN_TGZ_PATH" package/dist/build-info.json
}
verify_target_version() {
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
verify_version_contains "$TARGET_EXPECT_VERSION"
return
fi
verify_version_contains "$(git rev-parse --short=7 HEAD)"
}
start_server() {
local host_ip="$1"
local artifact probe_url attempt
@ -594,7 +647,7 @@ start_server() {
attempt=0
while :; do
attempt=$((attempt + 1))
say "Serve current main tgz on $host_ip:$HOST_PORT"
say "Serve $(artifact_label) on $host_ip:$HOST_PORT"
(
cd "$MAIN_TGZ_DIR"
exec python3 -m http.server "$HOST_PORT" --bind 0.0.0.0
@ -617,12 +670,16 @@ start_server() {
}
install_latest_release() {
local install_url_q
local install_url_q version_flag_q
install_url_q="$(ps_single_quote "$INSTALL_URL")"
version_flag_q=""
if [[ -n "$INSTALL_VERSION" ]]; then
version_flag_q="-Tag '$(ps_single_quote "$INSTALL_VERSION")' "
fi
guest_powershell "$(cat <<EOF
\$ProgressPreference = 'SilentlyContinue'
\$script = Invoke-RestMethod -Uri '$install_url_q'
& ([scriptblock]::Create(\$script)) -NoOnboard
& ([scriptblock]::Create(\$script)) ${version_flag_q}-NoOnboard
& (Join-Path \$env:APPDATA 'npm\openclaw.cmd') --version
EOF
)"
@ -740,7 +797,7 @@ run_fresh_main_lane() {
phase_run "fresh.ensure-git" "$TIMEOUT_INSTALL_S" ensure_guest_git "$host_ip" || return $?
phase_run "fresh.install-main" "$TIMEOUT_INSTALL_S" install_main_tgz "$host_ip" "openclaw-main-fresh.tgz" || return $?
FRESH_MAIN_VERSION="$(extract_last_version "$(phase_log_path fresh.install-main)")"
phase_run "fresh.verify-main-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$(git rev-parse --short=7 HEAD)" || return $?
phase_run "fresh.verify-main-version" "$TIMEOUT_VERIFY_S" verify_target_version || return $?
phase_run "fresh.onboard-ref" "$TIMEOUT_ONBOARD_S" run_ref_onboard || return $?
phase_run "fresh.gateway-status" "$TIMEOUT_GATEWAY_S" verify_gateway || return $?
FRESH_GATEWAY_STATUS="pass"
@ -768,7 +825,7 @@ run_upgrade_lane() {
phase_run "upgrade.ensure-git" "$TIMEOUT_INSTALL_S" ensure_guest_git "$host_ip" || return $?
phase_run "upgrade.install-main" "$TIMEOUT_INSTALL_S" install_main_tgz "$host_ip" "openclaw-main-upgrade.tgz" || return $?
UPGRADE_MAIN_VERSION="$(extract_last_version "$(phase_log_path upgrade.install-main)")"
phase_run "upgrade.verify-main-version" "$TIMEOUT_VERIFY_S" verify_version_contains "$(git rev-parse --short=7 HEAD)" || return $?
phase_run "upgrade.verify-main-version" "$TIMEOUT_VERIFY_S" verify_target_version || return $?
phase_run "upgrade.onboard-ref" "$TIMEOUT_ONBOARD_S" run_ref_onboard || return $?
phase_run "upgrade.gateway-status" "$TIMEOUT_GATEWAY_S" verify_gateway || return $?
UPGRADE_GATEWAY_STATUS="pass"
@ -825,6 +882,8 @@ SUMMARY_JSON_PATH="$(
SUMMARY_SNAPSHOT_ID="$SNAPSHOT_ID" \
SUMMARY_MODE="$MODE" \
SUMMARY_LATEST_VERSION="$LATEST_VERSION" \
SUMMARY_INSTALL_VERSION="$INSTALL_VERSION" \
SUMMARY_TARGET_PACKAGE_SPEC="$TARGET_PACKAGE_SPEC" \
SUMMARY_CURRENT_HEAD="$(git rev-parse --short HEAD)" \
SUMMARY_RUN_DIR="$RUN_DIR" \
SUMMARY_FRESH_MAIN_STATUS="$FRESH_MAIN_STATUS" \
@ -844,6 +903,12 @@ if [[ "$JSON_OUTPUT" -eq 1 ]]; then
cat "$SUMMARY_JSON_PATH"
else
printf '\nSummary:\n'
if [[ -n "$TARGET_PACKAGE_SPEC" ]]; then
printf ' target-package: %s\n' "$TARGET_PACKAGE_SPEC"
fi
if [[ -n "$INSTALL_VERSION" ]]; then
printf ' baseline-install-version: %s\n' "$INSTALL_VERSION"
fi
printf ' fresh-main: %s (%s)\n' "$FRESH_MAIN_STATUS" "$FRESH_MAIN_VERSION"
printf ' latest->main precheck: %s (%s)\n' "$UPGRADE_PRECHECK_STATUS" "$LATEST_INSTALLED_VERSION"
printf ' latest->main: %s (%s)\n' "$UPGRADE_STATUS" "$UPGRADE_MAIN_VERSION"