mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-08 04:20:43 +00:00
191 lines
6.5 KiB
Bash
191 lines
6.5 KiB
Bash
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
source scripts/lib/openclaw-e2e-instance.sh
|
|
|
|
openclaw_e2e_eval_test_state_from_b64 "${OPENCLAW_TEST_STATE_SCRIPT_B64:?missing OPENCLAW_TEST_STATE_SCRIPT_B64}"
|
|
openclaw_e2e_install_package /tmp/openclaw-install.log "mounted OpenClaw package" /tmp/npm-prefix
|
|
|
|
package_root="$(openclaw_e2e_package_root /tmp/npm-prefix)"
|
|
entry="$(openclaw_e2e_package_entrypoint "$package_root")"
|
|
package_version="$(node -p "require('$package_root/package.json').version")"
|
|
OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT="$(
|
|
PACKAGE_VERSION="$package_version" node -e 'const version = process.env.PACKAGE_VERSION || ""; const match = new RegExp("^(\\d{4})\\.(\\d{1,2})\\.(\\d{1,2})(?:[-+].*)?").exec(version); if (!match) { console.log("0"); process.exit(0); } const value = [Number(match[1]), Number(match[2]), Number(match[3])]; const max = [2026, 4, 25]; for (let i = 0; i < value.length; i += 1) { if (value[i] < max[i]) { console.log("1"); process.exit(0); } if (value[i] > max[i]) { console.log("0"); process.exit(0); } } console.log("1");'
|
|
)"
|
|
export OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT
|
|
export NPM_CONFIG_REGISTRY=http://127.0.0.1:4873
|
|
export PATH="/tmp/npm-prefix/bin:$PATH"
|
|
|
|
mkdir -p "$HOME/.openclaw/extensions/lossless-claw"
|
|
cat > "$HOME/.openclaw/extensions/lossless-claw/package.json" <<'JSON'
|
|
{
|
|
"name": "@example/lossless-claw",
|
|
"version": "0.9.0"
|
|
}
|
|
JSON
|
|
cat > "$OPENCLAW_CONFIG_PATH" <<'JSON'
|
|
{
|
|
"plugins": {}
|
|
}
|
|
JSON
|
|
mkdir -p "$HOME/.openclaw/plugins"
|
|
cat > "$HOME/.openclaw/plugins/installs.json" <<'JSON'
|
|
{
|
|
"version": 1,
|
|
"warning": "DO NOT EDIT. This file is generated by OpenClaw plugin registry commands.",
|
|
"hostContractVersion": "docker-e2e",
|
|
"compatRegistryVersion": "docker-e2e",
|
|
"migrationVersion": 1,
|
|
"policyHash": "docker-e2e",
|
|
"generatedAtMs": 1777118400000,
|
|
"installRecords": {
|
|
"lossless-claw": {
|
|
"source": "npm",
|
|
"spec": "@example/lossless-claw@0.9.0",
|
|
"installPath": "~/.openclaw/extensions/lossless-claw",
|
|
"resolvedName": "@example/lossless-claw",
|
|
"resolvedVersion": "0.9.0",
|
|
"resolvedSpec": "@example/lossless-claw@0.9.0",
|
|
"integrity": "sha512-same",
|
|
"shasum": "same"
|
|
}
|
|
},
|
|
"plugins": [],
|
|
"diagnostics": []
|
|
}
|
|
JSON
|
|
|
|
node scripts/e2e/lib/plugin-update/registry-server.mjs >/tmp/openclaw-e2e-registry.log 2>&1 &
|
|
registry_pid=$!
|
|
trap 'kill "$registry_pid" >/dev/null 2>&1 || true' EXIT
|
|
|
|
registry_ready=0
|
|
for _ in $(seq 1 50); do
|
|
if node --input-type=module -e '
|
|
import http from "node:http";
|
|
const req = http.get("http://127.0.0.1:4873/@example%2flossless-claw", (res) => {
|
|
process.exit(res.statusCode === 200 ? 0 : 1);
|
|
});
|
|
req.on("error", () => process.exit(1));
|
|
req.setTimeout(200, () => {
|
|
req.destroy();
|
|
process.exit(1);
|
|
});
|
|
'; then
|
|
registry_ready=1
|
|
break
|
|
fi
|
|
sleep 0.1
|
|
done
|
|
if [ "$registry_ready" -ne 1 ]; then
|
|
echo "Local npm metadata registry failed to start"
|
|
cat /tmp/openclaw-e2e-registry.log || true
|
|
exit 1
|
|
fi
|
|
|
|
before_config_hash=""
|
|
if [ "$OPENCLAW_PACKAGE_ACCEPTANCE_LEGACY_COMPAT" != "1" ]; then
|
|
before_config_hash="$(sha256sum "$OPENCLAW_CONFIG_PATH" | awk '{print $1}')"
|
|
fi
|
|
plugin_update_timeout_seconds="${OPENCLAW_PLUGIN_UPDATE_TIMEOUT_SECONDS:-180}"
|
|
|
|
node --input-type=module > /tmp/plugin-update-before.json <<'NODE'
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
|
|
const readJson = (file) => {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
} catch {
|
|
return {};
|
|
}
|
|
};
|
|
const home = os.homedir();
|
|
const config = readJson(path.join(home, ".openclaw", "openclaw.json"));
|
|
const index = readJson(path.join(home, ".openclaw", "plugins", "installs.json"));
|
|
const records = index.installRecords ?? index.records ?? config.plugins?.installs ?? {};
|
|
const record = records["lossless-claw"] ?? records["@example/lossless-claw"];
|
|
if (!record) {
|
|
throw new Error("missing seeded plugin install record");
|
|
}
|
|
const snapshot = {
|
|
source: record.source,
|
|
spec: record.spec,
|
|
resolvedName: record.resolvedName,
|
|
resolvedVersion: record.resolvedVersion,
|
|
resolvedSpec: record.resolvedSpec,
|
|
integrity: record.integrity,
|
|
shasum: record.shasum,
|
|
};
|
|
process.stdout.write(JSON.stringify(snapshot, null, 2));
|
|
NODE
|
|
|
|
set +e
|
|
timeout "${plugin_update_timeout_seconds}s" node "$entry" plugins update @example/lossless-claw > /tmp/plugin-update-output.log 2>&1
|
|
plugin_update_status=$?
|
|
set -e
|
|
if [ "$plugin_update_status" -ne 0 ]; then
|
|
echo "Plugin update command failed or timed out after ${plugin_update_timeout_seconds}s (status ${plugin_update_status})"
|
|
echo "--- plugin update output ---"
|
|
cat /tmp/plugin-update-output.log || true
|
|
echo "--- local registry output ---"
|
|
cat /tmp/openclaw-e2e-registry.log || true
|
|
exit "$plugin_update_status"
|
|
fi
|
|
|
|
if [ -n "$before_config_hash" ]; then
|
|
after_config_hash="$(sha256sum "$OPENCLAW_CONFIG_PATH" | awk '{print $1}')"
|
|
if [ "$before_config_hash" != "$after_config_hash" ]; then
|
|
echo "Config changed unexpectedly for modern package $package_version"
|
|
cat /tmp/plugin-update-output.log
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
node --input-type=module <<'NODE'
|
|
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
|
|
const readJson = (file) => {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(file, "utf8"));
|
|
} catch {
|
|
return {};
|
|
}
|
|
};
|
|
const home = os.homedir();
|
|
const before = readJson("/tmp/plugin-update-before.json");
|
|
const config = readJson(path.join(home, ".openclaw", "openclaw.json"));
|
|
const index = readJson(path.join(home, ".openclaw", "plugins", "installs.json"));
|
|
const records = index.installRecords ?? index.records ?? config.plugins?.installs ?? {};
|
|
const record = records["lossless-claw"] ?? records["@example/lossless-claw"];
|
|
if (!record) {
|
|
throw new Error("missing plugin install record after update");
|
|
}
|
|
const after = {
|
|
source: record.source,
|
|
spec: record.spec,
|
|
resolvedName: record.resolvedName,
|
|
resolvedVersion: record.resolvedVersion,
|
|
resolvedSpec: record.resolvedSpec,
|
|
integrity: record.integrity,
|
|
shasum: record.shasum,
|
|
};
|
|
if (JSON.stringify(before) !== JSON.stringify(after)) {
|
|
throw new Error(`plugin install record changed unexpectedly: ${JSON.stringify({ before, after })}`);
|
|
}
|
|
NODE
|
|
if grep -q "Downloading @example/lossless-claw" /tmp/plugin-update-output.log; then
|
|
echo "Unexpected npm download/reinstall path"
|
|
cat /tmp/plugin-update-output.log
|
|
exit 1
|
|
fi
|
|
if ! grep -q "lossless-claw is up to date (0.9.0)." /tmp/plugin-update-output.log; then
|
|
echo "Expected up-to-date output missing"
|
|
cat /tmp/plugin-update-output.log
|
|
exit 1
|
|
fi
|
|
cat /tmp/plugin-update-output.log
|