// Plugin release pretag pack check tests cover its script-local target and command routing. import { join } from "node:path"; import { afterEach, describe, expect, it, vi } from "vitest"; import { collectPluginReleasePretagPackTargets, runPluginReleasePretagPackCheck, } from "../../scripts/plugin-release-pretag-pack-check.ts"; import { writePublishablePluginFixture } from "../helpers/publishable-plugin-fixture.js"; import { cleanupTempDirs, makeTempDir as makeTempRepoRoot } from "../helpers/temp-dir.js"; import { writeJsonFile } from "../helpers/temp-repo.js"; const { execFileSyncMock } = vi.hoisted(() => ({ execFileSyncMock: vi.fn(), })); vi.mock("node:child_process", async () => { const actual = await vi.importActual("node:child_process"); return { ...actual, execFileSync: execFileSyncMock, }; }); const tempDirs: string[] = []; type ExecOptions = { cwd?: string; env?: NodeJS.ProcessEnv; stdio?: unknown; }; afterEach(() => { cleanupTempDirs(tempDirs); execFileSyncMock.mockReset(); }); function createDualPublishPluginRepo() { const repoDir = makeTempRepoRoot(tempDirs, "openclaw-plugin-pretag-pack-"); writeJsonFile(join(repoDir, "package.json"), { name: "openclaw-test-root", type: "module" }); writePublishablePluginFixture(repoDir, { version: "2026.4.10", publishTo: "both", }); return repoDir; } function callOptions(index: number): ExecOptions { return execFileSyncMock.mock.calls[index]?.[2] as ExecOptions; } describe("scripts/plugin-release-pretag-pack-check.ts", () => { it("collects dual-published plugin targets for npm and ClawHub pack checks", () => { const repoDir = createDualPublishPluginRepo(); expect(collectPluginReleasePretagPackTargets(repoDir)).toEqual([ { packageDir: "extensions/demo-plugin", packageName: "@openclaw/demo-plugin", packClawHub: true, packNpm: true, }, ]); }); it("runs runtime build, npm pack, and ClawHub pack commands for selected targets", () => { const repoDir = createDualPublishPluginRepo(); execFileSyncMock.mockImplementation(() => ""); runPluginReleasePretagPackCheck(repoDir); expect(execFileSyncMock).toHaveBeenCalledTimes(3); expect(execFileSyncMock.mock.calls[0]?.slice(0, 2)).toEqual([ process.execPath, [ "--import", "tsx", "scripts/check-plugin-npm-runtime-builds.mts", "--package", "extensions/demo-plugin", ], ]); expect(callOptions(0)).toMatchObject({ cwd: repoDir, stdio: "inherit" }); expect(execFileSyncMock.mock.calls[1]?.slice(0, 2)).toEqual([ "bash", ["scripts/plugin-npm-publish.sh", "--pack-dry-run", "extensions/demo-plugin"], ]); expect(callOptions(1)).toMatchObject({ cwd: repoDir, env: { OPENCLAW_PLUGIN_NPM_RUNTIME_BUILD: "0" }, stdio: ["inherit", "ignore", "inherit"], }); expect(execFileSyncMock.mock.calls[2]?.slice(0, 2)).toEqual([ "bash", ["scripts/plugin-clawhub-publish.sh", "--pack", "extensions/demo-plugin"], ]); expect(callOptions(2)).toMatchObject({ cwd: repoDir, env: { OPENCLAW_PLUGIN_NPM_RUNTIME_BUILD: "0" }, stdio: ["inherit", "ignore", "inherit"], }); expect(callOptions(2).env?.OPENCLAW_CLAWHUB_PACK_OUTPUT_DIR).toContain("clawhub-0"); }); });