mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-02 08:21:35 +00:00
205 lines
6.4 KiB
TypeScript
205 lines
6.4 KiB
TypeScript
// Exercises packaged launcher version provenance without loading the runtime.
|
|
import { spawnSync } from "node:child_process";
|
|
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { cleanupTempDirs, makeTempDir } from "./helpers/temp-dir.js";
|
|
|
|
const packageVersion = "1.2.3-test";
|
|
const checkoutCommit = "abcdef0123456789abcdef0123456789abcdef01";
|
|
const buildCommit = "1234567890abcdef1234567890abcdef12345678";
|
|
|
|
type LauncherVersionFixtureOptions = {
|
|
buildCommit?: string;
|
|
checkout?: "directory" | "linked";
|
|
packageCommit?: string;
|
|
};
|
|
|
|
async function makeLauncherVersionFixture(
|
|
fixtureRoots: string[],
|
|
options: LauncherVersionFixtureOptions = {},
|
|
): Promise<string> {
|
|
const fixtureRoot = makeTempDir(fixtureRoots, "openclaw-launcher-version-");
|
|
await fs.copyFile(
|
|
path.resolve(process.cwd(), "openclaw.mjs"),
|
|
path.join(fixtureRoot, "openclaw.mjs"),
|
|
);
|
|
await fs.mkdir(path.join(fixtureRoot, "dist"), { recursive: true });
|
|
await fs.writeFile(
|
|
path.join(fixtureRoot, "package.json"),
|
|
JSON.stringify({
|
|
name: "openclaw",
|
|
version: packageVersion,
|
|
...(options.packageCommit ? { gitHead: options.packageCommit } : {}),
|
|
}),
|
|
);
|
|
await fs.writeFile(
|
|
path.join(fixtureRoot, "dist", "entry.js"),
|
|
"throw new Error('version fast path must not load the runtime entry');\n",
|
|
);
|
|
|
|
if (options.buildCommit) {
|
|
await fs.writeFile(
|
|
path.join(fixtureRoot, "dist", "build-info.json"),
|
|
JSON.stringify({ version: packageVersion, commit: options.buildCommit }),
|
|
);
|
|
}
|
|
|
|
if (options.checkout) {
|
|
const gitDirectory =
|
|
options.checkout === "linked"
|
|
? path.join(fixtureRoot, "worktree-git")
|
|
: path.join(fixtureRoot, ".git");
|
|
await fs.mkdir(gitDirectory, { recursive: true });
|
|
await fs.writeFile(path.join(gitDirectory, "HEAD"), `${checkoutCommit}\n`);
|
|
if (options.checkout === "linked") {
|
|
await fs.writeFile(path.join(fixtureRoot, ".git"), "gitdir: worktree-git\n");
|
|
}
|
|
}
|
|
|
|
return fixtureRoot;
|
|
}
|
|
|
|
function runLauncherVersion(
|
|
fixtureRoot: string,
|
|
options: { flag?: string; env?: NodeJS.ProcessEnv } = {},
|
|
) {
|
|
return spawnSync(
|
|
process.execPath,
|
|
[path.join(fixtureRoot, "openclaw.mjs"), options.flag ?? "--version"],
|
|
{
|
|
cwd: fixtureRoot,
|
|
env: {
|
|
...process.env,
|
|
GIT_COMMIT: undefined,
|
|
GIT_SHA: undefined,
|
|
OPENCLAW_CONTAINER: undefined,
|
|
...options.env,
|
|
},
|
|
encoding: "utf8",
|
|
},
|
|
);
|
|
}
|
|
|
|
describe("openclaw launcher version provenance", () => {
|
|
const fixtureRoots: string[] = [];
|
|
|
|
afterEach(() => {
|
|
cleanupTempDirs(fixtureRoots);
|
|
});
|
|
|
|
it.each(["directory", "linked"] as const)(
|
|
"reports the packaged build rather than the current %s checkout",
|
|
async (checkout) => {
|
|
const fixtureRoot = await makeLauncherVersionFixture(fixtureRoots, {
|
|
buildCommit,
|
|
checkout,
|
|
});
|
|
|
|
const result = runLauncherVersion(fixtureRoot);
|
|
|
|
expect(result.status).toBe(0);
|
|
expect(result.stdout).toBe(`OpenClaw ${packageVersion} (${buildCommit.slice(0, 7)})\n`);
|
|
expect(result.stderr).toBe("");
|
|
},
|
|
);
|
|
|
|
it.each(["directory", "linked"] as const)(
|
|
"reports the live %s checkout when no packaged build metadata exists",
|
|
async (checkout) => {
|
|
const fixtureRoot = await makeLauncherVersionFixture(fixtureRoots, { checkout });
|
|
|
|
const result = runLauncherVersion(fixtureRoot);
|
|
|
|
expect(result.status).toBe(0);
|
|
expect(result.stdout).toBe(`OpenClaw ${packageVersion} (${checkoutCommit.slice(0, 7)})\n`);
|
|
expect(result.stderr).toBe("");
|
|
},
|
|
);
|
|
|
|
it.each(["--version", "-V", "-v"])(
|
|
"reports the packaged build for the %s fast path without importing the runtime",
|
|
async (flag) => {
|
|
const fixtureRoot = await makeLauncherVersionFixture(fixtureRoots, { buildCommit });
|
|
|
|
const result = runLauncherVersion(fixtureRoot, { flag });
|
|
|
|
expect(result.status).toBe(0);
|
|
expect(result.stdout).toBe(`OpenClaw ${packageVersion} (${buildCommit.slice(0, 7)})\n`);
|
|
expect(result.stderr).toBe("");
|
|
},
|
|
);
|
|
|
|
it.each([
|
|
{
|
|
name: "explicit GIT_COMMIT",
|
|
env: { GIT_COMMIT: "fedcba9876543210fedcba9876543210fedcba98" },
|
|
expected: "fedcba9",
|
|
},
|
|
{
|
|
name: "explicit GIT_SHA",
|
|
env: { GIT_SHA: "deadc0de0123456789abcdef0123456789abcdef" },
|
|
expected: "deadc0d",
|
|
},
|
|
{
|
|
name: "GIT_COMMIT precedence over GIT_SHA",
|
|
env: {
|
|
GIT_COMMIT: "fedcba9876543210fedcba9876543210fedcba98",
|
|
GIT_SHA: "deadc0de0123456789abcdef0123456789abcdef",
|
|
},
|
|
expected: "fedcba9",
|
|
},
|
|
])("preserves $name over packaged and checkout metadata", async ({ env, expected }) => {
|
|
const fixtureRoot = await makeLauncherVersionFixture(fixtureRoots, {
|
|
buildCommit,
|
|
checkout: "linked",
|
|
});
|
|
|
|
const result = runLauncherVersion(fixtureRoot, { env });
|
|
|
|
expect(result.status).toBe(0);
|
|
expect(result.stdout).toBe(`OpenClaw ${packageVersion} (${expected})\n`);
|
|
expect(result.stderr).toBe("");
|
|
});
|
|
|
|
it("uses package metadata when neither a build nor a checkout commit is available", async () => {
|
|
const fixtureRoot = await makeLauncherVersionFixture(fixtureRoots, {
|
|
packageCommit: checkoutCommit,
|
|
});
|
|
|
|
const result = runLauncherVersion(fixtureRoot);
|
|
|
|
expect(result.status).toBe(0);
|
|
expect(result.stdout).toBe(`OpenClaw ${packageVersion} (${checkoutCommit.slice(0, 7)})\n`);
|
|
expect(result.stderr).toBe("");
|
|
});
|
|
|
|
it("defers container-targeted root version to the runtime entry", async () => {
|
|
const fixtureRoot = await makeLauncherVersionFixture(fixtureRoots, { buildCommit });
|
|
await fs.writeFile(
|
|
path.join(fixtureRoot, "dist", "entry.js"),
|
|
"process.stdout.write('RUNTIME ENTRY\\n');\n",
|
|
);
|
|
|
|
const argumentResult = spawnSync(
|
|
process.execPath,
|
|
[path.join(fixtureRoot, "openclaw.mjs"), "--container", "demo", "--version"],
|
|
{
|
|
cwd: fixtureRoot,
|
|
env: { ...process.env, OPENCLAW_CONTAINER: undefined },
|
|
encoding: "utf8",
|
|
},
|
|
);
|
|
|
|
expect(argumentResult.status).toBe(0);
|
|
expect(argumentResult.stdout).toBe("RUNTIME ENTRY\n");
|
|
|
|
const environmentResult = runLauncherVersion(fixtureRoot, {
|
|
env: { OPENCLAW_CONTAINER: "demo" },
|
|
});
|
|
|
|
expect(environmentResult.status).toBe(0);
|
|
expect(environmentResult.stdout).toBe("RUNTIME ENTRY\n");
|
|
});
|
|
});
|