// 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, RELEASE_CHECK_LOCAL_PACKAGE_TARBALL_DIR_ENV, resolveReleaseCheckLocalPackageTarballs, writePackedTarballInstallManifest, writePackedBundledPluginActivationConfig, } from "../../scripts/release-check.ts"; function requirePluginEntries(config: { plugins?: { entries?: Record } }) { 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; 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("preserves the no-env local release check path", () => { const root = mkdtempSync(join(tmpdir(), "openclaw-release-check-install-test-")); try { writePackedTarballInstallManifest(root, "/tmp/openclaw.tgz", []); const manifest = JSON.parse(readFileSync(join(root, "package.json"), "utf8")) as { dependencies?: Record; private?: boolean; }; expect(manifest.private).toBe(true); expect(manifest.dependencies).toEqual({ openclaw: "file:///tmp/openclaw.tgz", }); } 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; plugins?: { entries?: Record }; }; 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 }); } }); });