diff --git a/scripts/e2e/parallels-npm-update-smoke.sh b/scripts/e2e/parallels-npm-update-smoke.sh index d37e8376f65..34d0f9ae065 100755 --- a/scripts/e2e/parallels-npm-update-smoke.sh +++ b/scripts/e2e/parallels-npm-update-smoke.sh @@ -742,7 +742,7 @@ function Invoke-OpenClawUpdateWithTimeout { $previousDisableBundledPlugins = $env:OPENCLAW_DISABLE_BUNDLED_PLUGINS $env:OPENCLAW_DISABLE_BUNDLED_PLUGINS = '1' try { - $output = & $Path update --tag $Target --yes --json *>&1 + $output = & $Path update --tag $Target --yes --no-restart --json *>&1 } finally { if ($null -eq $previousDisableBundledPlugins) { Remove-Item Env:OPENCLAW_DISABLE_BUNDLED_PLUGINS -ErrorAction SilentlyContinue @@ -835,6 +835,33 @@ function Invoke-OpenClawAgentWithTimeout { throw "openclaw agent timed out after ${TimeoutSeconds}s" } +function Invoke-OpenClawVersionWithRetry { + param( + [Parameter(Mandatory = $true)][string]$OpenClawPath, + [Parameter(Mandatory = $false)][string]$ExpectedNeedle, + [int]$Attempts = 12, + [int]$SleepSeconds = 2 + ) + + $lastError = '' + for ($attempt = 1; $attempt -le $Attempts; $attempt++) { + Write-ProgressLog "update.verify-version.attempt-$attempt" + try { + $version = Invoke-CaptureLogged 'openclaw --version' { & $OpenClawPath --version } + if (-not $ExpectedNeedle -or $version -match [regex]::Escape($ExpectedNeedle)) { + return $version + } + $lastError = "version mismatch: expected substring $ExpectedNeedle" + } catch { + $lastError = $_ | Out-String + } + if ($attempt -lt $Attempts) { + Start-Sleep -Seconds $SleepSeconds + } + } + throw $lastError +} + function Start-GatewayRunFallback { param( [Parameter(Mandatory = $true)][string]$OpenClawPath @@ -948,10 +975,7 @@ try { Write-ProgressLog 'update.openclaw-update' Invoke-OpenClawUpdateWithTimeout -OpenClawPath $openclaw -UpdateTarget $UpdateTarget Write-ProgressLog 'update.verify-version' - $version = Invoke-CaptureLogged 'openclaw --version' { & $openclaw --version } - if ($ExpectedNeedle -and $version -notmatch [regex]::Escape($ExpectedNeedle)) { - throw "version mismatch: expected substring $ExpectedNeedle" - } + $version = Invoke-OpenClawVersionWithRetry -OpenClawPath $openclaw -ExpectedNeedle $ExpectedNeedle Write-ProgressLog $version Write-ProgressLog 'update.status' Invoke-Logged 'openclaw update status' { & $openclaw update status --json } @@ -1678,6 +1702,27 @@ stop_openclaw_gateway_processes() { /bin/kill -9 "\$pid" 2>/dev/null || true done } +openclaw_version_with_retry() { + bin="\$1" + expected="\$2" + version="" + last_output="" + for attempt in 1 2 3 4 5 6 7 8 9 10 11 12; do + if version="\$("\$bin" --version 2>&1)"; then + printf '%s\n' "\$version" + if [ -z "\$expected" ] || [[ "\$version" == *"\$expected"* ]]; then + return 0 + fi + last_output="version mismatch: expected substring \$expected" + else + last_output="\$version" + printf '%s\n' "\$last_output" >&2 + fi + sleep 2 + done + printf '%s\n' "\$last_output" >&2 + return 1 +} # Stop the pre-update gateway before replacing the package. Otherwise the old # host can observe new plugin metadata mid-update and abort config validation. scrub_future_plugin_entries @@ -1686,21 +1731,11 @@ stop_openclaw_gateway_processes # host while new bundled plugin metadata is already on disk. Keep this # same-guest update hop focused on core/package migration; post-update smoke # below starts the fresh gateway with bundled plugins enabled. -OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 /opt/homebrew/bin/openclaw update --tag "$update_target" --yes --json +OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 /opt/homebrew/bin/openclaw update --tag "$update_target" --yes --no-restart --json # Same-guest npm upgrades can leave the old gateway process holding the old # bundled plugin host version. Stop it before post-update config commands. stop_openclaw_gateway_processes -version="\$(/opt/homebrew/bin/openclaw --version)" -printf '%s\n' "\$version" -if [ -n "$expected_needle" ]; then - case "\$version" in - *"$expected_needle"*) ;; - *) - echo "version mismatch: expected substring $expected_needle" >&2 - exit 1 - ;; - esac -fi +version="\$(openclaw_version_with_retry /opt/homebrew/bin/openclaw "$expected_needle")" /opt/homebrew/bin/openclaw update status --json /opt/homebrew/bin/openclaw models set "$MODEL_ID" /opt/homebrew/bin/openclaw config set agents.defaults.skipBootstrap true --strict-json @@ -1816,25 +1851,36 @@ stop_openclaw_gateway_processes() { done fi } +openclaw_version_with_retry() { + bin="\$1" + expected="\$2" + version="" + last_output="" + for attempt in 1 2 3 4 5 6 7 8 9 10 11 12; do + if version="\$("\$bin" --version 2>&1)"; then + printf '%s\n' "\$version" + if [ -z "\$expected" ] || [[ "\$version" == *"\$expected"* ]]; then + return 0 + fi + last_output="version mismatch: expected substring \$expected" + else + last_output="\$version" + printf '%s\n' "\$last_output" >&2 + fi + sleep 2 + done + printf '%s\n' "\$last_output" >&2 + return 1 +} # Stop the pre-update manual gateway before replacing the package. Otherwise # the old host can observe new plugin metadata mid-update and abort validation. scrub_future_plugin_entries stop_openclaw_gateway_processes -OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 openclaw update --tag "$update_target" --yes --json +OPENCLAW_DISABLE_BUNDLED_PLUGINS=1 openclaw update --tag "$update_target" --yes --no-restart --json # The fresh Linux lane starts a manual gateway; stop the old process before # post-update config validation sees mixed old-host/new-plugin metadata. stop_openclaw_gateway_processes -version="\$(openclaw --version)" -printf '%s\n' "\$version" -if [ -n "$expected_needle" ]; then - case "\$version" in - *"$expected_needle"*) ;; - *) - echo "version mismatch: expected substring $expected_needle" >&2 - exit 1 - ;; - esac -fi +version="\$(openclaw_version_with_retry openclaw "$expected_needle")" openclaw update status --json openclaw models set "$MODEL_ID" openclaw config set agents.defaults.skipBootstrap true --strict-json