fix(runtime): make dist-runtime staging idempotent

This commit is contained in:
Vincent Koc
2026-03-22 22:36:05 -07:00
parent 5822892fee
commit fd5555d5be
2 changed files with 62 additions and 4 deletions

View File

@@ -2,7 +2,7 @@ import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { pathToFileURL } from "node:url";
import { afterEach, describe, expect, it } from "vitest";
import { afterEach, describe, expect, it, vi } from "vitest";
import { stageBundledPluginRuntime } from "../../scripts/stage-bundled-plugin-runtime.mjs";
import { discoverOpenClawPlugins } from "./discovery.js";
import { loadPluginManifestRegistry } from "./manifest-registry.js";
@@ -329,4 +329,40 @@ describe("stageBundledPluginRuntime", () => {
expect(fs.existsSync(path.join(repoRoot, "dist-runtime"))).toBe(false);
});
it("tolerates EEXIST when an identical runtime symlink is materialized concurrently", () => {
const repoRoot = makeRepoRoot("openclaw-stage-bundled-runtime-eexist-");
const distPluginDir = path.join(repoRoot, "dist", "extensions", "feishu");
const distSkillDir = path.join(distPluginDir, "skills", "feishu-doc");
fs.mkdirSync(distSkillDir, { recursive: true });
fs.writeFileSync(path.join(distPluginDir, "index.js"), "export default {}\n", "utf8");
fs.writeFileSync(path.join(distSkillDir, "SKILL.md"), "# Feishu Doc\n", "utf8");
const realSymlinkSync = fs.symlinkSync.bind(fs);
const symlinkSpy = vi.spyOn(fs, "symlinkSync").mockImplementation(((target, link, type) => {
const linkPath = String(link);
if (linkPath.endsWith(path.join("skills", "feishu-doc", "SKILL.md"))) {
const err = Object.assign(new Error("file already exists"), { code: "EEXIST" });
realSymlinkSync(String(target), linkPath, type);
throw err;
}
return realSymlinkSync(String(target), linkPath, type);
}) as typeof fs.symlinkSync);
expect(() => stageBundledPluginRuntime({ repoRoot })).not.toThrow();
const runtimeSkillPath = path.join(
repoRoot,
"dist-runtime",
"extensions",
"feishu",
"skills",
"feishu-doc",
"SKILL.md",
);
expect(fs.lstatSync(runtimeSkillPath).isSymbolicLink()).toBe(true);
expect(fs.readFileSync(runtimeSkillPath, "utf8")).toBe("# Feishu Doc\n");
symlinkSpy.mockRestore();
});
});