mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-25 11:55:47 -06:00
improve: validate built CLI with Bun 1.4 (#129192)
* ci: validate built CLI with Bun 1.4 Amp-Thread-ID: https://ampcode.com/threads/T-01a037b7-66db-71f0-91e7-1578b383afb2 * test: align Bun Docker image assertion Amp-Thread-ID: https://ampcode.com/threads/T-01a037b7-66db-71f0-91e7-1578b383afb2 * test: tolerate cold CLI startup in CI Amp-Thread-ID: https://ampcode.com/threads/T-01a037b7-66db-71f0-91e7-1578b383afb2 --------- Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
committed by
GitHub
parent
97cd06b946
commit
5af05ab1a2
@@ -321,7 +321,7 @@ runs:
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
npm install -g bun@1.3.14
|
||||
npm install -g bun@1.4.0
|
||||
|
||||
- name: Runtime versions
|
||||
shell: bash
|
||||
|
||||
@@ -1346,7 +1346,7 @@ jobs:
|
||||
uses: ./.ci-harness/.github/actions/setup-node-env
|
||||
with:
|
||||
cache-mode: ${{ needs.preflight.outputs.cache_mode }}
|
||||
install-bun: "false"
|
||||
install-bun: "true"
|
||||
node-compile-cache: "true"
|
||||
node-compile-cache-scope: "build"
|
||||
# Same-repo Blacksmith runs restore the dependency cache published by
|
||||
@@ -1428,6 +1428,11 @@ jobs:
|
||||
- name: Smoke test CLI launcher status json
|
||||
run: node openclaw.mjs status --json --timeout 1
|
||||
|
||||
- name: Smoke test built CLI with Bun
|
||||
run: |
|
||||
bun openclaw.mjs --help
|
||||
bun openclaw.mjs status --json --timeout 1
|
||||
|
||||
# Doctor index proof, singleton smoke, and startup-memory check are
|
||||
# independent dist readers; Blacksmith runners have the cores to overlap
|
||||
# them, while hosted 4-core runners keep the serial order so the RSS
|
||||
|
||||
@@ -1449,7 +1449,7 @@ jobs:
|
||||
--source-archive-sha256 "$SOURCE_ARCHIVE_SHA256"
|
||||
|
||||
- name: Install Bun for global smoke
|
||||
run: npm install -g bun@1.3.14
|
||||
run: npm install -g bun@1.4.0
|
||||
|
||||
- name: Run Bun global install candidate-payload smoke
|
||||
working-directory: .release-harness
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@ ARG OPENCLAW_NODE_BOOKWORM_SLIM_IMAGE="docker.io/library/node:24-bookworm-slim@s
|
||||
ARG OPENCLAW_NODE_BOOKWORM_SLIM_DIGEST="sha256:3638d9a6fe4030bd716be989438248074489337ba3275657f93595428be4fc03"
|
||||
# Keep in sync with .github/actions/setup-node-env/action.yml bun-version.
|
||||
# To update: docker buildx imagetools inspect docker.io/oven/bun:<version> and use the manifest-list digest.
|
||||
ARG OPENCLAW_BUN_IMAGE="docker.io/oven/bun:1.3.14@sha256:e10577f0db68676a7024391c6e5cb4b879ebd17188ab750cf10024a6d700e5c4"
|
||||
ARG OPENCLAW_BUN_IMAGE="docker.io/oven/bun:1.4.0@sha256:5ff609364c049b54eb0ff560ec96319729a972078ef2c755d758f0c6ef89c2d6"
|
||||
|
||||
# Base images are pinned to SHA256 digests for reproducible builds.
|
||||
# Dependabot refreshes these blessed digests; release builds consume the
|
||||
|
||||
@@ -275,7 +275,7 @@ const jsRuntimeEntrypoints = new Set([
|
||||
]);
|
||||
const awsMacosCorepackEntrypoints = new Set(["pnpm", "yarn", "corepack"]);
|
||||
const awsMacosBunEntrypoints = new Set(["bun", "bunx"]);
|
||||
const awsMacosBunVersion = "1.3.14";
|
||||
const awsMacosBunVersion = "1.4.0";
|
||||
const awsMacosSwiftEntrypoints = new Set(["swift", "xcodebuild"]);
|
||||
const awsMacosSwiftScriptTargets = new Set([
|
||||
"mac:package",
|
||||
|
||||
@@ -147,8 +147,8 @@ main() {
|
||||
export NO_COLOR=1
|
||||
mkdir -p "$HOME" "$BUN_INSTALL/bin" "$BUN_INSTALL/install/global" "$XDG_CACHE_HOME"
|
||||
export PATH="$BUN_INSTALL/bin:$(dirname "$(command -v node)"):$PATH"
|
||||
# Release publishes @openclaw/ai first. Bun 1.3.14 ignores bundled deps in
|
||||
# local tarballs, so resolve that one package from the exact candidate bytes.
|
||||
# Release publishes @openclaw/ai first. Pin the local tarball install to
|
||||
# exact candidate bytes instead of allowing public-registry resolution.
|
||||
node --input-type=module - \
|
||||
"$BUN_INSTALL/install/global/package.json" \
|
||||
"$AI_PACKAGE_TGZ" <<'NODE'
|
||||
|
||||
@@ -86,7 +86,7 @@ DOCKER_COMMAND_TIMEOUT="$DOCKER_RUN_TIMEOUT" docker_e2e_docker_run_cmd run -d \
|
||||
"$IMAGE_NAME" \
|
||||
bash -lc '
|
||||
set -euo pipefail
|
||||
npm install -g --prefix /tmp/bun-runtime bun@1.3.14 --no-fund --no-audit
|
||||
npm install -g --prefix /tmp/bun-runtime bun@1.4.0 --no-fund --no-audit
|
||||
cd /repo
|
||||
BUN_BIN=/tmp/bun-runtime/bin/bun \
|
||||
OPENCLAW_BUN_GLOBAL_SMOKE_HOST_BUILD=0 \
|
||||
|
||||
@@ -148,6 +148,7 @@ async function runIsolatedGatewayCli(params: {
|
||||
stateDir: string;
|
||||
configPath: string;
|
||||
env?: NodeJS.ProcessEnv;
|
||||
timeoutMs?: number;
|
||||
}): Promise<{
|
||||
code: number | null;
|
||||
signal: NodeJS.Signals | null;
|
||||
@@ -185,7 +186,7 @@ async function runIsolatedGatewayCli(params: {
|
||||
},
|
||||
encoding: "utf8",
|
||||
killSignal: "SIGKILL",
|
||||
timeout: 20_000,
|
||||
timeout: params.timeoutMs ?? 20_000,
|
||||
},
|
||||
);
|
||||
return { code: 0, signal: null, stdout: result.stdout, stderr: result.stderr };
|
||||
@@ -235,6 +236,9 @@ describe("gateway-backed CLI process exit", () => {
|
||||
root,
|
||||
stateDir,
|
||||
configPath,
|
||||
// The first source child cold-loads the CLI graph and can contend with
|
||||
// neighboring CI shards before it reaches the Gateway turn.
|
||||
timeoutMs: 45_000,
|
||||
});
|
||||
|
||||
expect(result, result.stderr).toMatchObject({ code: exitCode, signal: null, stderr: "" });
|
||||
@@ -244,7 +248,7 @@ describe("gateway-backed CLI process exit", () => {
|
||||
result: { payloads: [{ text }] },
|
||||
});
|
||||
},
|
||||
30_000,
|
||||
60_000,
|
||||
);
|
||||
|
||||
it.each([
|
||||
|
||||
@@ -85,7 +85,7 @@ describe("Dockerfile", () => {
|
||||
'ARG OPENCLAW_NODE_BOOKWORM_SLIM_IMAGE="docker.io/library/node:24-bookworm-slim@sha256:3638d9a6fe4030bd716be989438248074489337ba3275657f93595428be4fc03"',
|
||||
);
|
||||
expect(dockerfile).toContain(
|
||||
'ARG OPENCLAW_BUN_IMAGE="docker.io/oven/bun:1.3.14@sha256:e10577f0db68676a7024391c6e5cb4b879ebd17188ab750cf10024a6d700e5c4"',
|
||||
'ARG OPENCLAW_BUN_IMAGE="docker.io/oven/bun:1.4.0@sha256:5ff609364c049b54eb0ff560ec96319729a972078ef2c755d758f0c6ef89c2d6"',
|
||||
);
|
||||
expect(dockerfile).toContain("FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS workspace-deps");
|
||||
expect(dockerfile).toContain("FROM ${OPENCLAW_NODE_BOOKWORM_IMAGE} AS build");
|
||||
|
||||
@@ -7405,13 +7405,26 @@ printf '%s\n' "\${CURL_SUCCESS_IP:-203.0.113.7}"
|
||||
expect(realGatewayRunContract).not.toContain("--testTimeout");
|
||||
});
|
||||
|
||||
it("does not rebuild Control UI after build:ci-artifacts", () => {
|
||||
it("builds artifacts once and smoke-tests the built CLI with Node and Bun", () => {
|
||||
const workflow = readCiWorkflow();
|
||||
const buildArtifactSteps = workflow.jobs["build-artifacts"].steps;
|
||||
const setupStep = buildArtifactSteps.find(
|
||||
(step: WorkflowStep) => step.name === "Setup Node environment",
|
||||
);
|
||||
const buildDistStep = buildArtifactSteps.find(
|
||||
(step: WorkflowStep) => step.name === "Build dist",
|
||||
);
|
||||
const nodeHelpSmoke = buildArtifactSteps.find(
|
||||
(step: WorkflowStep) => step.name === "Smoke test CLI launcher help",
|
||||
);
|
||||
const nodeStatusSmoke = buildArtifactSteps.find(
|
||||
(step: WorkflowStep) => step.name === "Smoke test CLI launcher status json",
|
||||
);
|
||||
const bunSmoke = buildArtifactSteps.find(
|
||||
(step: WorkflowStep) => step.name === "Smoke test built CLI with Bun",
|
||||
);
|
||||
|
||||
expect(setupStep.with["install-bun"]).toBe("true");
|
||||
expect(buildDistStep.run).toBe("pnpm build:ci-artifacts");
|
||||
expect(buildArtifactSteps.map((step: WorkflowStep) => step.name)).not.toContain(
|
||||
"Build Control UI",
|
||||
@@ -7419,6 +7432,10 @@ printf '%s\n' "\${CURL_SUCCESS_IP:-203.0.113.7}"
|
||||
expect(buildArtifactSteps.some((step: WorkflowStep) => step.run === "pnpm ui:build")).toBe(
|
||||
false,
|
||||
);
|
||||
expect(nodeHelpSmoke.run).toBe("node openclaw.mjs --help");
|
||||
expect(nodeStatusSmoke.run).toBe("node openclaw.mjs status --json --timeout 1");
|
||||
expect(bunSmoke.run).toContain("bun openclaw.mjs --help");
|
||||
expect(bunSmoke.run).toContain("bun openclaw.mjs status --json --timeout 1");
|
||||
});
|
||||
|
||||
it("keeps source-only Control UI locale drift advisory", () => {
|
||||
|
||||
@@ -2575,7 +2575,7 @@ describe("scripts/crabbox-wrapper", () => {
|
||||
expect(output.args).toContain("--shell");
|
||||
expect(result.stderr).toContain("Node/Corepack/pnpm/Bun");
|
||||
expect(remoteCommand).toContain("openclaw_crabbox_bootstrap_macos_js");
|
||||
expect(remoteCommand).toContain("bun_version=1.3.14");
|
||||
expect(remoteCommand).toContain("bun_version=1.4.0");
|
||||
expect(remoteCommand).toContain('bun_root="$tool_root/bun-v${bun_version}"');
|
||||
expect(remoteCommand).toContain(
|
||||
'npm install --global --prefix "$bun_root" --fetch-timeout=120000 --fetch-retries=2 --fetch-retry-mintimeout=2000 --fetch-retry-maxtimeout=15000 "bun@${bun_version}"',
|
||||
@@ -2871,7 +2871,7 @@ describe("scripts/crabbox-wrapper", () => {
|
||||
it("bootstraps Bun for AWS macOS script-stdin bun shebangs", () => {
|
||||
const script = ["#!/usr/bin/env bun", "console.log(Bun.version);"].join("\n");
|
||||
const { output } = runSuccessfulMacosScript(script);
|
||||
expect(output.scriptContent).toContain("bun_version=1.3.14");
|
||||
expect(output.scriptContent).toContain("bun_version=1.4.0");
|
||||
expect(output.scriptContent).toContain(
|
||||
'npm install --global --prefix "$bun_root" --fetch-timeout=120000 --fetch-retries=2 --fetch-retry-mintimeout=2000 --fetch-retry-maxtimeout=15000 "bun@${bun_version}"',
|
||||
);
|
||||
|
||||
@@ -4520,7 +4520,7 @@ source "$ROOT_DIR/scripts/lib/docker-e2e-logs.sh"
|
||||
"npm install -g --prefix /tmp/openclaw-proof",
|
||||
"corepack prepare pnpm@11.22.0 --activate",
|
||||
"pnpm add --global --allow-build=openclaw",
|
||||
"bun@1.3.14",
|
||||
"bun@1.4.0",
|
||||
'test "$(command -v openclaw)" = "/tmp/openclaw-proof/bin/openclaw"',
|
||||
'test "$(command -v openclaw)" = "$PNPM_HOME/openclaw"',
|
||||
"OPENCLAW_BUN_GLOBAL_SMOKE_PROOF_PATH",
|
||||
|
||||
@@ -543,7 +543,7 @@ describe("install smoke no-push root image transport", () => {
|
||||
expect(bunVerify.run).toContain("install-smoke-candidate-payload.mts verify");
|
||||
expect(bunVerify.run).toContain('--run-id "$PRODUCER_RUN_ID"');
|
||||
expect(bunVerify.run).toContain('--run-attempt "$PRODUCER_RUN_ATTEMPT"');
|
||||
expect(step(bunConsumer, "Install Bun for global smoke").run).toBe("npm install -g bun@1.3.14");
|
||||
expect(step(bunConsumer, "Install Bun for global smoke").run).toBe("npm install -g bun@1.4.0");
|
||||
expect(step(bunConsumer, "Run Bun global install candidate-payload smoke")).toMatchObject({
|
||||
"working-directory": ".release-harness",
|
||||
env: {
|
||||
|
||||
@@ -2171,7 +2171,7 @@ chmod +x "$BUN_INSTALL/bin/openclaw"
|
||||
expect(workflow).toContain("bun_global_install_smoke:");
|
||||
expect(workflow).toContain("Setup trusted release harness for Bun smoke");
|
||||
expect(workflow).toContain("uses: ./.release-harness/.github/actions/setup-release-harness");
|
||||
expect(workflow).toContain("npm install -g bun@1.3.14");
|
||||
expect(workflow).toContain("npm install -g bun@1.4.0");
|
||||
expect(workflow).toContain('install-bun: "false"');
|
||||
expect(workflow).toContain("Run Bun global install candidate-payload smoke");
|
||||
expect(workflow).toContain("working-directory: .release-harness");
|
||||
|
||||
Reference in New Issue
Block a user