mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-14 11:16:06 +00:00
158 lines
6.0 KiB
TypeScript
158 lines
6.0 KiB
TypeScript
// Release Check tests cover release check script behavior.
|
|
import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { describe, expect, it } from "vitest";
|
|
import {
|
|
createPackedTarballInstallArgs,
|
|
prepareReleaseCheckLocalPackageTarballs,
|
|
RELEASE_CHECK_LOCAL_PACKAGE_TARBALL_DIR_ENV,
|
|
resolveReleaseCheckLocalPackageTarballs,
|
|
writePackedTarballInstallManifest,
|
|
writePackedBundledPluginActivationConfig,
|
|
} from "../../scripts/release-check.ts";
|
|
|
|
function requirePluginEntries(config: { plugins?: { entries?: Record<string, unknown> } }) {
|
|
if (!config.plugins?.entries) {
|
|
throw new Error("Expected plugin entries in packaged activation config");
|
|
}
|
|
return config.plugins.entries;
|
|
}
|
|
|
|
describe("release-check", () => {
|
|
it("installs the packed core and local sibling package tarballs together", () => {
|
|
expect(createPackedTarballInstallArgs("/tmp/prefix")).toEqual([
|
|
"install",
|
|
"--prefix",
|
|
"/tmp/prefix",
|
|
"--ignore-scripts",
|
|
"--no-audit",
|
|
"--no-fund",
|
|
]);
|
|
});
|
|
|
|
it("resolves exactly one prepacked local dependency tarball", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-tarball-test-"));
|
|
try {
|
|
writeFileSync(join(root, "openclaw-ai-2026.6.33.tgz"), "fixture");
|
|
writeFileSync(join(root, "SHA256SUMS"), "fixture");
|
|
expect(resolveReleaseCheckLocalPackageTarballs(root)).toEqual([
|
|
join(root, "openclaw-ai-2026.6.33.tgz"),
|
|
]);
|
|
expect(resolveReleaseCheckLocalPackageTarballs(undefined)).toEqual([]);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("writes an explicit local project for unpublished core and AI tarballs", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-install-test-"));
|
|
try {
|
|
writePackedTarballInstallManifest(root, "/tmp/openclaw.tgz", ["/tmp/openclaw-ai.tgz"]);
|
|
const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8")) as {
|
|
dependencies?: Record<string, string>;
|
|
private?: boolean;
|
|
};
|
|
expect(manifest.private).toBe(true);
|
|
expect(manifest.dependencies).toEqual({
|
|
"@openclaw/ai": "file:///tmp/openclaw-ai.tgz",
|
|
openclaw: "file:///tmp/openclaw.tgz",
|
|
});
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("packs the local AI workspace when no prepared tarball is supplied", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-ai-pack-test-"));
|
|
try {
|
|
const tarballs = prepareReleaseCheckLocalPackageTarballs({
|
|
tmpRoot: root,
|
|
packLocalAi: (packDestination) => {
|
|
const filename = "openclaw-ai-2026.7.1-beta.3.tgz";
|
|
writeFileSync(join(packDestination, filename), "fixture");
|
|
return [{ filename }];
|
|
},
|
|
});
|
|
expect(tarballs).toEqual([join(root, "ai-pack", "openclaw-ai-2026.7.1-beta.3.tgz")]);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("prefers the prepared AI tarball over packing the workspace", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-ai-pack-test-"));
|
|
try {
|
|
const preparedDir = join(root, "prepared");
|
|
mkdirSync(preparedDir);
|
|
const preparedTarball = join(preparedDir, "openclaw-ai-2026.7.1-beta.3.tgz");
|
|
writeFileSync(preparedTarball, "fixture");
|
|
const tarballs = prepareReleaseCheckLocalPackageTarballs({
|
|
tmpRoot: root,
|
|
tarballDir: preparedDir,
|
|
packLocalAi: () => {
|
|
throw new Error("workspace pack should not run");
|
|
},
|
|
});
|
|
expect(tarballs).toEqual([preparedTarball]);
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("rejects a packed install without the local AI tarball", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-install-test-"));
|
|
try {
|
|
expect(() => writePackedTarballInstallManifest(root, "/tmp/openclaw.tgz", [])).toThrow(
|
|
"requires exactly one @openclaw/ai tarball",
|
|
);
|
|
expect(() =>
|
|
writePackedTarballInstallManifest(root, "/tmp/openclaw.tgz", [
|
|
"/tmp/openclaw-ai-one.tgz",
|
|
"/tmp/openclaw-ai-two.tgz",
|
|
]),
|
|
).toThrow("requires exactly one @openclaw/ai tarball");
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("rejects missing, empty, or ambiguous local dependency tarball directories", () => {
|
|
const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-tarball-test-"));
|
|
try {
|
|
expect(() => resolveReleaseCheckLocalPackageTarballs(join(root, "missing"))).toThrow(
|
|
RELEASE_CHECK_LOCAL_PACKAGE_TARBALL_DIR_ENV,
|
|
);
|
|
const empty = join(root, "empty");
|
|
mkdirSync(empty);
|
|
expect(() => resolveReleaseCheckLocalPackageTarballs(empty)).toThrow("contains 0 tarballs");
|
|
writeFileSync(join(empty, "one.tgz"), "fixture");
|
|
writeFileSync(join(empty, "two.tgz"), "fixture");
|
|
expect(() => resolveReleaseCheckLocalPackageTarballs(empty)).toThrow("contains 2 tarballs");
|
|
} finally {
|
|
rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
|
|
it("seeds packaged activation smoke with an included channel plugin", () => {
|
|
const homeDir = mkdtempSync(join(tmpdir(), "openclaw-release-check-test-"));
|
|
try {
|
|
writePackedBundledPluginActivationConfig(homeDir);
|
|
const config = JSON.parse(
|
|
readFileSync(join(homeDir, ".openclaw", "openclaw.json"), "utf8"),
|
|
) as {
|
|
channels?: Record<string, unknown>;
|
|
plugins?: { entries?: Record<string, unknown> };
|
|
};
|
|
|
|
expect(config.channels).toHaveProperty("matrix");
|
|
const pluginEntries = requirePluginEntries(config);
|
|
expect(pluginEntries).toHaveProperty("matrix");
|
|
expect(config.channels).not.toHaveProperty("feishu");
|
|
expect(pluginEntries).not.toHaveProperty("feishu");
|
|
} finally {
|
|
rmSync(homeDir, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|