






















@@ -0,0 +1,191 @@
1+#!/usr/bin/env bash
2+set -euo pipefail
3+4+ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
5+BUN_BIN="${BUN_BIN:-bun}"
6+HOST_BUILD="${OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD:-1}"
7+DIST_IMAGE="${OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE:-}"
8+PACKAGE_TGZ="${OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ:-}"
9+COMMAND_TIMEOUT_MS="${OPENCLAW_BUN_GLOBAL_SMOKE_TIMEOUT_MS:-180000}"
10+SMOKE_DIR=""
11+PACK_DIR=""
12+13+cleanup() {
14+if [ -n "${SMOKE_DIR:-}" ]; then
15+ rm -rf "$SMOKE_DIR"
16+fi
17+if [ -n "${PACK_DIR:-}" ]; then
18+ rm -rf "$PACK_DIR"
19+fi
20+}
21+22+trap cleanup EXIT
23+24+run_with_timeout() {
25+local timeout_ms="$1"
26+shift
27+ node - "$timeout_ms" "$@" <<'NODE'
28+const { spawnSync } = require("node:child_process");
29+30+const timeout = Number(process.argv[2]);
31+const command = process.argv[3];
32+const args = process.argv.slice(4);
33+const result = spawnSync(command, args, {
34+ encoding: "utf8",
35+ env: process.env,
36+ timeout,
37+});
38+39+if (result.stdout) {
40+ process.stdout.write(result.stdout);
41+}
42+if (result.stderr) {
43+ process.stderr.write(result.stderr);
44+}
45+if (result.error) {
46+ console.error(`command failed: ${command}: ${result.error.message}`);
47+ process.exit(1);
48+}
49+if (result.signal) {
50+ console.error(`command terminated: ${command}: ${result.signal}`);
51+ process.exit(1);
52+}
53+process.exit(result.status ?? 0);
54+NODE
55+}
56+57+restore_dist_from_image() {
58+local image="$1"
59+local container_id
60+61+echo "==> Reuse dist/ from Docker image: $image"
62+ container_id="$(docker create "$image")"
63+ rm -rf "$ROOT_DIR/dist"
64+if ! docker cp "${container_id}:/app/dist" "$ROOT_DIR/dist"; then
65+ docker rm -f "$container_id" >/dev/null 2>&1 || true
66+return 1
67+fi
68+ docker rm -f "$container_id" >/dev/null
69+}
70+71+resolve_package_tgz() {
72+if [ -n "$PACKAGE_TGZ" ]; then
73+if [ ! -f "$PACKAGE_TGZ" ]; then
74+echo "OPENCLAW_BUN_GLOBAL_SMOKE_PACKAGE_TGZ does not exist: $PACKAGE_TGZ" >&2
75+exit 1
76+fi
77+ PACKAGE_TGZ="$(cd "$(dirname "$PACKAGE_TGZ")" && pwd)/$(basename "$PACKAGE_TGZ")"
78+return 0
79+fi
80+81+if [ -n "$DIST_IMAGE" ]; then
82+ restore_dist_from_image "$DIST_IMAGE"
83+elif [ "$HOST_BUILD" != "0" ]; then
84+echo "==> Build host package artifacts"
85+ pnpm build
86+else
87+echo "==> Skipping host build (OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0)"
88+fi
89+90+if [ ! -d "$ROOT_DIR/dist" ]; then
91+echo "dist/ is missing; run pnpm build or set OPENCLAW_BUN_GLOBAL_SMOKE_DIST_IMAGE" >&2
92+exit 1
93+fi
94+95+echo "==> Write package inventory"
96+ node --import tsx scripts/write-package-dist-inventory.ts
97+98+local pack_json_file
99+ PACK_DIR="$(mktemp -d "${TMPDIR:-/tmp}/openclaw-bun-pack.XXXXXX")"
100+ pack_json_file="$PACK_DIR/pack.json"
101+102+echo "==> Pack OpenClaw tarball"
103+ npm pack --ignore-scripts --json --pack-destination "$PACK_DIR" >"$pack_json_file"
104+ PACKAGE_TGZ="$(
105+ node -e '
106+const raw = require("node:fs").readFileSync(process.argv[1], "utf8") || "[]";
107+const parsed = JSON.parse(raw);
108+const last = Array.isArray(parsed) ? parsed.at(-1) : null;
109+if (!last || typeof last.filename !== "string" || last.filename.length === 0) {
110+ process.exit(1);
111+}
112+process.stdout.write(require("node:path").resolve(process.argv[2], last.filename));
113+' "$pack_json_file" "$PACK_DIR"
114+ )"
115+if [ -z "$PACKAGE_TGZ" ] || [ ! -f "$PACKAGE_TGZ" ]; then
116+echo "missing packed OpenClaw tarball" >&2
117+exit 1
118+fi
119+}
120+121+main() {
122+cd "$ROOT_DIR"
123+124+if ! command -v "$BUN_BIN" >/dev/null 2>&1; then
125+echo "Bun is required for bun global install smoke; set BUN_BIN or install bun." >&2
126+exit 1
127+fi
128+129+ resolve_package_tgz
130+131+local bun_path
132+local openclaw_bin
133+ bun_path="$(command -v "$BUN_BIN")"
134+ SMOKE_DIR="$(mktemp -d "${TMPDIR:-/tmp}/openclaw-bun-global.XXXXXX")"
135+136+export HOME="$SMOKE_DIR/home"
137+export BUN_INSTALL="$HOME/.bun"
138+export XDG_CACHE_HOME="$SMOKE_DIR/cache"
139+export OPENCLAW_NO_ONBOARD=1
140+export OPENCLAW_DISABLE_UPDATE_CHECK=1
141+export NO_COLOR=1
142+ mkdir -p "$HOME" "$BUN_INSTALL/bin" "$XDG_CACHE_HOME"
143+export PATH="$BUN_INSTALL/bin:$(dirname "$(command -v node)"):$PATH"
144+145+echo "==> Bun version"
146+"$bun_path" --version
147+148+echo "==> Bun global install packed OpenClaw"
149+"$bun_path" install -g "$PACKAGE_TGZ" --no-progress
150+151+ openclaw_bin="$BUN_INSTALL/bin/openclaw"
152+if [ ! -x "$openclaw_bin" ]; then
153+ openclaw_bin="$(command -v openclaw || true)"
154+fi
155+if [ -z "$openclaw_bin" ] || [ ! -x "$openclaw_bin" ]; then
156+echo "Bun global install did not create an executable openclaw binary" >&2
157+exit 1
158+fi
159+160+echo "==> OpenClaw version through Bun global install"
161+ run_with_timeout "$COMMAND_TIMEOUT_MS" "$openclaw_bin" --version
162+163+echo "==> OpenClaw image providers through Bun global install"
164+local providers_json
165+ providers_json="$(run_with_timeout "$COMMAND_TIMEOUT_MS" "$openclaw_bin" infer image providers --json)"
166+ OPENCLAW_IMAGE_PROVIDERS_JSON="$providers_json" node - <<'NODE'
167+const raw = process.env.OPENCLAW_IMAGE_PROVIDERS_JSON ?? "";
168+let parsed;
169+try {
170+ parsed = JSON.parse(raw);
171+} catch (error) {
172+ console.error(raw);
173+ throw new Error(`image providers output is not JSON: ${error.message}`);
174+}
175+if (!Array.isArray(parsed)) {
176+ throw new Error("image providers output must be a JSON array");
177+}
178+if (parsed.length === 0) {
179+ throw new Error("image providers output is empty");
180+}
181+const ids = new Set(parsed.map((entry) => entry && typeof entry.id === "string" ? entry.id : ""));
182+for (const expected of ["google", "openai", "xai"]) {
183+ if (!ids.has(expected)) {
184+ throw new Error(`image providers output is missing bundled provider '${expected}'`);
185+ }
186+}
187+console.log(`bun-global-install-smoke: image providers OK (${parsed.length} providers)`);
188+NODE
189+}
190+191+main "$@"
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。