diff --git a/scripts/e2e/parallels-npm-update-smoke.sh b/scripts/e2e/parallels-npm-update-smoke.sh index 3668f1fa0e7..063665ced98 100755 --- a/scripts/e2e/parallels-npm-update-smoke.sh +++ b/scripts/e2e/parallels-npm-update-smoke.sh @@ -12,6 +12,7 @@ JSON_OUTPUT=0 RUN_DIR="$(mktemp -d /tmp/openclaw-parallels-npm-update.XXXXXX)" MAIN_TGZ_DIR="$(mktemp -d)" MAIN_TGZ_PATH="" +WINDOWS_UPDATE_SCRIPT_PATH="" SERVER_PID="" HOST_IP="" HOST_PORT="" @@ -165,6 +166,108 @@ pack_main_tgz() { cp "$MAIN_TGZ_DIR/$pkg" "$MAIN_TGZ_PATH" } +write_windows_update_script() { + WINDOWS_UPDATE_SCRIPT_PATH="$MAIN_TGZ_DIR/openclaw-main-update.ps1" + cat >"$WINDOWS_UPDATE_SCRIPT_PATH" <<'EOF' +param( + [Parameter(Mandatory = $true)][string]$TgzUrl, + [Parameter(Mandatory = $true)][string]$HeadShort, + [Parameter(Mandatory = $true)][string]$SessionId, + [Parameter(Mandatory = $true)][string]$LogPath, + [Parameter(Mandatory = $true)][string]$DonePath +) + +$ErrorActionPreference = 'Stop' +$PSNativeCommandUseErrorActionPreference = $false + +function Invoke-Logged { + param( + [Parameter(Mandatory = $true)][string]$Label, + [Parameter(Mandatory = $true)][scriptblock]$Command + ) + + $previousErrorActionPreference = $ErrorActionPreference + $previousNativeErrorPreference = $PSNativeCommandUseErrorActionPreference + try { + $ErrorActionPreference = 'Continue' + $PSNativeCommandUseErrorActionPreference = $false + & $Command *>> $LogPath + $exitCode = $LASTEXITCODE + } finally { + $ErrorActionPreference = $previousErrorActionPreference + $PSNativeCommandUseErrorActionPreference = $previousNativeErrorPreference + } + + if ($exitCode -ne 0) { + throw "$Label failed with exit code $exitCode" + } +} + +function Invoke-CaptureLogged { + param( + [Parameter(Mandatory = $true)][string]$Label, + [Parameter(Mandatory = $true)][scriptblock]$Command + ) + + $previousErrorActionPreference = $ErrorActionPreference + $previousNativeErrorPreference = $PSNativeCommandUseErrorActionPreference + try { + $ErrorActionPreference = 'Continue' + $PSNativeCommandUseErrorActionPreference = $false + $output = & $Command 2>&1 + $exitCode = $LASTEXITCODE + } finally { + $ErrorActionPreference = $previousErrorActionPreference + $PSNativeCommandUseErrorActionPreference = $previousNativeErrorPreference + } + + if ($null -ne $output) { + $output | Tee-Object -FilePath $LogPath -Append | Out-Null + } + + if ($exitCode -ne 0) { + throw "$Label failed with exit code $exitCode" + } + + return ($output | Out-String).Trim() +} + +try { + $env:PATH = "$env:LOCALAPPDATA\OpenClaw\deps\portable-git\cmd;$env:LOCALAPPDATA\OpenClaw\deps\portable-git\mingw64\bin;$env:LOCALAPPDATA\OpenClaw\deps\portable-git\usr\bin;$env:PATH" + $tgz = Join-Path $env:TEMP 'openclaw-main-update.tgz' + Remove-Item $tgz, $LogPath, $DonePath -Force -ErrorAction SilentlyContinue + Invoke-Logged 'download current tgz' { curl.exe -fsSL $TgzUrl -o $tgz } + Invoke-Logged 'npm install current tgz' { npm.cmd install -g $tgz --no-fund --no-audit } + $openclaw = Join-Path $env:APPDATA 'npm\openclaw.cmd' + $version = Invoke-CaptureLogged 'openclaw --version' { & $openclaw --version } + if ($version -notmatch [regex]::Escape($HeadShort)) { + throw "version mismatch: expected substring $HeadShort" + } + Invoke-Logged 'openclaw models set' { & $openclaw models set openai/gpt-5.4 } + # Windows can keep the old hashed dist modules alive across in-place global npm upgrades. + # Restart the gateway/service before verifying status or the next agent turn. + Invoke-Logged 'openclaw gateway restart' { & $openclaw gateway restart } + Start-Sleep -Seconds 5 + Invoke-Logged 'openclaw gateway status' { & $openclaw gateway status --deep --require-rpc } + Invoke-CaptureLogged 'openclaw agent' { & $openclaw agent --agent main --session-id $SessionId --message 'Reply with exact ASCII text OK only.' --json } | Out-Null + $exitCode = $LASTEXITCODE + if ($null -eq $exitCode) { + $exitCode = 0 + } + Set-Content -Path $DonePath -Value ([string]$exitCode) + exit $exitCode +} catch { + if (Test-Path $LogPath) { + Add-Content -Path $LogPath -Value ($_ | Out-String) + } else { + ($_ | Out-String) | Set-Content -Path $LogPath + } + Set-Content -Path $DonePath -Value '1' + exit 1 +} +EOF +} + start_server() { HOST_IP="$(resolve_host_ip)" HOST_PORT="$(allocate_host_port)" @@ -197,6 +300,7 @@ import sys text = pathlib.Path(sys.argv[1]).read_text(encoding="utf-8", errors="replace") matches = re.findall(r"OpenClaw [^\r\n]+", text) +matches = [match for match in matches if re.search(r"OpenClaw \d", match)] print(matches[-1] if matches else "") PY } @@ -218,35 +322,35 @@ PY } run_windows_script_via_log() { - local script_body="$1" - local runner_name log_name done_name done_status + local script_url="$1" + local tgz_url="$2" + local head_short="$3" + local session_id="$4" + local runner_name log_name done_name done_status launcher_state + local start_seconds poll_deadline startup_checked runner_name="openclaw-update-$RANDOM-$RANDOM.ps1" log_name="openclaw-update-$RANDOM-$RANDOM.log" done_name="openclaw-update-$RANDOM-$RANDOM.done" + start_seconds="$SECONDS" + poll_deadline=$((SECONDS + 900)) + startup_checked=0 guest_powershell "$(cat <