mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 14:50:45 +00:00
chore(release): forward-port 2026.4.29 fixes and bump 2026.4.30
This commit is contained in:
@@ -35,7 +35,8 @@ start_kitchen_sink_clawhub_fixture_server() {
|
||||
local server_pid="$!"
|
||||
echo "$server_pid" >"$server_pid_file"
|
||||
|
||||
for _ in $(seq 1 100); do
|
||||
local wait_attempts="${OPENCLAW_CLAWHUB_FIXTURE_WAIT_ATTEMPTS:-600}"
|
||||
for _ in $(seq 1 "$wait_attempts"); do
|
||||
if [[ -s "$server_port_file" ]]; then
|
||||
export OPENCLAW_CLAWHUB_URL="http://127.0.0.1:$(cat "$server_port_file")"
|
||||
trap 'if [[ -f "'"$server_pid_file"'" ]]; then kill "$(cat "'"$server_pid_file"'")" 2>/dev/null || true; fi' EXIT
|
||||
@@ -49,6 +50,7 @@ start_kitchen_sink_clawhub_fixture_server() {
|
||||
done
|
||||
|
||||
cat "$server_log"
|
||||
ps -p "$server_pid" -o pid=,stat=,etime=,command= || true
|
||||
echo "Timed out waiting for kitchen-sink ClawHub fixture server." >&2
|
||||
return 1
|
||||
}
|
||||
@@ -75,8 +77,8 @@ assert_kitchen_sink_removed() {
|
||||
|
||||
run_success_scenario() {
|
||||
echo "Testing ${KITCHEN_SINK_LABEL} install from ${KITCHEN_SINK_SPEC}..."
|
||||
configure_kitchen_sink_runtime
|
||||
run_logged_print "kitchen-sink-install-${KITCHEN_SINK_LABEL}" node "$OPENCLAW_ENTRY" plugins install "$KITCHEN_SINK_SPEC"
|
||||
configure_kitchen_sink_runtime
|
||||
run_logged_print "kitchen-sink-enable-${KITCHEN_SINK_LABEL}" node "$OPENCLAW_ENTRY" plugins enable "$KITCHEN_SINK_ID"
|
||||
node "$OPENCLAW_ENTRY" plugins list --json >"/tmp/kitchen-sink-${KITCHEN_SINK_LABEL}-plugins.json"
|
||||
node "$OPENCLAW_ENTRY" plugins inspect "$KITCHEN_SINK_ID" --json >"/tmp/kitchen-sink-${KITCHEN_SINK_LABEL}-inspect.json"
|
||||
|
||||
@@ -30,9 +30,10 @@ entries = plugins.get("entries")
|
||||
if isinstance(entries, dict):
|
||||
entries.pop("feishu", None)
|
||||
entries.pop("whatsapp", None)
|
||||
entries.pop("openai", None)
|
||||
allow = plugins.get("allow")
|
||||
if isinstance(allow, list):
|
||||
plugins["allow"] = [item for item in allow if item not in {"feishu", "whatsapp"}]
|
||||
plugins["allow"] = [item for item in allow if item not in {"feishu", "whatsapp", "openai"}]
|
||||
path.write_text(json.dumps(config, indent=2) + "\n")
|
||||
PY
|
||||
}
|
||||
@@ -86,13 +87,13 @@ function Remove-FuturePluginEntries {
|
||||
if (-not ($plugins -is [hashtable])) { return }
|
||||
$entries = $plugins['entries']
|
||||
if ($entries -is [hashtable]) {
|
||||
foreach ($pluginId in @('feishu', 'whatsapp')) {
|
||||
foreach ($pluginId in @('feishu', 'whatsapp', 'openai')) {
|
||||
if ($entries.ContainsKey($pluginId)) { $entries.Remove($pluginId) }
|
||||
}
|
||||
}
|
||||
$allow = $plugins['allow']
|
||||
if ($allow -is [array]) {
|
||||
$plugins['allow'] = @($allow | Where-Object { $_ -notin @('feishu', 'whatsapp') })
|
||||
$plugins['allow'] = @($allow | Where-Object { $_ -notin @('feishu', 'whatsapp', 'openai') })
|
||||
}
|
||||
$config | ConvertTo-Json -Depth 100 | Set-Content -Path $configPath -Encoding UTF8
|
||||
}
|
||||
@@ -119,8 +120,25 @@ if ($updateExit -ne 0) {
|
||||
Write-Host "openclaw update returned a stale post-swap module import; continuing to post-update health checks"
|
||||
}
|
||||
${windowsVersionCheck(input.expectedNeedle)}
|
||||
Invoke-OpenClaw gateway restart
|
||||
Invoke-OpenClaw gateway status --deep --require-rpc
|
||||
function Wait-OpenClawGateway {
|
||||
$deadline = (Get-Date).AddSeconds(180)
|
||||
$attempt = 0
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
Invoke-OpenClaw gateway status --deep --require-rpc --timeout 15000
|
||||
if ($LASTEXITCODE -eq 0) { return }
|
||||
$attempt += 1
|
||||
if ($attempt -eq 4) {
|
||||
Invoke-OpenClaw gateway start *>&1 | Out-Host
|
||||
}
|
||||
Start-Sleep -Seconds 5
|
||||
}
|
||||
throw "gateway did not become ready after update"
|
||||
}
|
||||
Invoke-OpenClaw gateway restart *>&1 | Out-Host
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
"gateway restart exited with code $LASTEXITCODE; probing readiness before failing" | Out-Host
|
||||
}
|
||||
Wait-OpenClawGateway
|
||||
Invoke-OpenClaw models set ${psSingleQuote(input.auth.modelId)}
|
||||
Invoke-OpenClaw config set agents.defaults.skipBootstrap true --strict-json
|
||||
${windowsAgentWorkspaceScript("Parallels npm update smoke test assistant.")}
|
||||
@@ -144,9 +162,10 @@ if (!plugins || typeof plugins !== "object") process.exit(0);
|
||||
if (plugins.entries && typeof plugins.entries === "object") {
|
||||
delete plugins.entries.feishu;
|
||||
delete plugins.entries.whatsapp;
|
||||
delete plugins.entries.openai;
|
||||
}
|
||||
if (Array.isArray(plugins.allow)) {
|
||||
plugins.allow = plugins.allow.filter((id) => id !== "feishu" && id !== "whatsapp");
|
||||
plugins.allow = plugins.allow.filter((id) => id !== "feishu" && id !== "whatsapp" && id !== "openai");
|
||||
}
|
||||
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
||||
JS
|
||||
|
||||
@@ -441,12 +441,22 @@ class NpmUpdateSmoke {
|
||||
timeoutMs: number,
|
||||
ctx: UpdateJobContext,
|
||||
): Promise<void> {
|
||||
const macosExecArgs = this.resolveMacosUpdateExecArgs(ctx);
|
||||
const scriptPath = this.writeGuestScript(
|
||||
macosVm,
|
||||
script,
|
||||
"openclaw-parallels-npm-update-macos",
|
||||
);
|
||||
const macosExecArgs = this.resolveMacosUpdateExecArgs(ctx);
|
||||
const sudoUserArgIndex = macosExecArgs.indexOf("-u");
|
||||
const sudoUser =
|
||||
sudoUserArgIndex >= 0 && sudoUserArgIndex + 1 < macosExecArgs.length
|
||||
? macosExecArgs[sudoUserArgIndex + 1]
|
||||
: "";
|
||||
if (sudoUser) {
|
||||
run("prlctl", ["exec", macosVm, "/usr/sbin/chown", sudoUser, scriptPath], {
|
||||
timeoutMs: 30_000,
|
||||
});
|
||||
}
|
||||
try {
|
||||
const status = await this.runStreamingToJobLog(
|
||||
"prlctl",
|
||||
|
||||
@@ -666,7 +666,7 @@ if (!(Test-Path $scriptPath)) { throw "background script was not written" }`,
|
||||
);
|
||||
let launched = false;
|
||||
let lastLaunchStatus = 0;
|
||||
for (let attempt = 1; attempt <= 3; attempt++) {
|
||||
for (let attempt = 1; attempt <= 5; attempt++) {
|
||||
this.waitForGuestReady(120);
|
||||
const launchLogPath = path.join(this.runDir, `${safeLabel}-launch-${attempt}.log`);
|
||||
const launchStatus = await runStreaming(
|
||||
@@ -675,17 +675,30 @@ if (!(Test-Path $scriptPath)) { throw "background script was not written" }`,
|
||||
"exec",
|
||||
this.options.vmName,
|
||||
"--current-user",
|
||||
"cmd.exe",
|
||||
"/d",
|
||||
"/s",
|
||||
"/c",
|
||||
`start "" /min powershell.exe -NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File "%TEMP%\\${fileBase}.ps1"`,
|
||||
"powershell.exe",
|
||||
"-NoProfile",
|
||||
"-ExecutionPolicy",
|
||||
"Bypass",
|
||||
"-EncodedCommand",
|
||||
encodePowerShell(`${pathsScript}
|
||||
Start-Process -FilePath powershell.exe -WindowStyle Hidden -ArgumentList @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $scriptPath)
|
||||
'started'`),
|
||||
],
|
||||
{ logPath: launchLogPath, quiet: true, timeoutMs: this.remainingPhaseTimeoutMs(20_000) },
|
||||
{ logPath: launchLogPath, quiet: true, timeoutMs: this.remainingPhaseTimeoutMs(30_000) },
|
||||
);
|
||||
const launchLog = await readFile(launchLogPath, "utf8").catch(() => "");
|
||||
this.log(launchLog);
|
||||
if (launchStatus === 0 && launchLog.includes("started")) {
|
||||
launched = true;
|
||||
break;
|
||||
}
|
||||
if (launchStatus === 0 || launchStatus === 124) {
|
||||
const materialized = this.waitForBackgroundMaterialized(pathsScript, 45_000);
|
||||
if (!materialized) {
|
||||
warn(`${label} launch retry ${attempt}: background log/done file did not materialize`);
|
||||
lastLaunchStatus = launchStatus;
|
||||
continue;
|
||||
}
|
||||
launched = true;
|
||||
break;
|
||||
}
|
||||
@@ -754,6 +767,31 @@ Remove-Item -Path $scriptPath, $logPath, $donePath, $exitPath -Force -ErrorActio
|
||||
throw new Error(`${label} timed out`);
|
||||
}
|
||||
|
||||
private waitForBackgroundMaterialized(pathsScript: string, timeoutMs: number): boolean {
|
||||
const deadline = Date.now() + timeoutMs;
|
||||
while (Date.now() < deadline) {
|
||||
const result = this.guest.run(
|
||||
[
|
||||
"powershell.exe",
|
||||
"-NoProfile",
|
||||
"-ExecutionPolicy",
|
||||
"Bypass",
|
||||
"-EncodedCommand",
|
||||
encodePowerShell(`${pathsScript}
|
||||
if ((Test-Path $logPath) -or (Test-Path $donePath)) {
|
||||
'materialized'
|
||||
}`),
|
||||
],
|
||||
{ check: false, timeoutMs: this.remainingPhaseTimeoutMs(15_000) },
|
||||
);
|
||||
if (result.stdout.includes("materialized")) {
|
||||
return true;
|
||||
}
|
||||
run("sleep", ["2"], { quiet: true });
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private runDevChannelUpdate(): void {
|
||||
this.guestPowerShell(
|
||||
`$ErrorActionPreference = 'Stop'
|
||||
|
||||
Reference in New Issue
Block a user