fix: preserve runtime plugin assets after build (#104229)

This commit is contained in:
Peter Steinberger
2026-07-11 00:07:59 -07:00
committed by GitHub
parent 5228183ce2
commit 1e660ac7b2
4 changed files with 61 additions and 7 deletions
+7 -6
View File
@@ -44,6 +44,11 @@ export const BUILD_ALL_STEPS = [
kind: "node",
args: ["scripts/check-cli-bootstrap-imports.mjs"],
},
{
label: "plugins:assets:copy",
kind: "pnpm",
pnpmArgs: ["plugins:assets:copy"],
},
{ label: "runtime-postbuild", kind: "node", args: ["scripts/runtime-postbuild.mjs"] },
{ label: "build-stamp", kind: "node", args: ["scripts/build-stamp.mjs"] },
{
@@ -70,11 +75,6 @@ export const BUILD_ALL_STEPS = [
kind: "node",
args: ["scripts/check-plugin-sdk-exports.mjs"],
},
{
label: "plugins:assets:copy",
kind: "pnpm",
pnpmArgs: ["plugins:assets:copy"],
},
{
label: "copy-hook-metadata",
kind: "node",
@@ -126,12 +126,12 @@ export const BUILD_ALL_PROFILES = {
"plugins:assets:build",
"tsdown",
"check-cli-bootstrap-imports",
"plugins:assets:copy",
"runtime-postbuild",
"build-stamp",
"runtime-postbuild-stamp",
"write-plugin-sdk-entry-dts",
"check-plugin-sdk-exports",
"plugins:assets:copy",
"copy-hook-metadata",
"copy-export-html-templates",
"ui:build",
@@ -150,6 +150,7 @@ export const BUILD_ALL_PROFILES = {
"plugins:assets:build",
"tsdown",
"check-cli-bootstrap-imports",
"plugins:assets:copy",
"runtime-postbuild",
"build-stamp",
"runtime-postbuild-stamp",
+10
View File
@@ -226,6 +226,10 @@ function isBundledSkillRuntimePath(relativePath) {
return relativePath === "skills" || relativePath.startsWith("skills/");
}
function isRawBrowserExtensionAssetPath(relativePath) {
return relativePath === "chrome-extension" || relativePath.endsWith("/chrome-extension");
}
function isPathOrNestedPath(relativePath, nestedPath) {
return relativePath === nestedPath || relativePath.endsWith(`/${nestedPath}`);
}
@@ -290,6 +294,12 @@ function stagePluginRuntimeOverlay(sourceDir, targetDir, relativeDir = "") {
const relativePath = path.join(relativeDir, dirent.name).replace(/\\/g, "/");
if (dirent.isDirectory()) {
// Unpacked browser extensions are executable static payloads, not Node
// modules. Preserve the staged tree byte-for-byte so Chrome can load it.
if (isRawBrowserExtensionAssetPath(relativePath)) {
copyPathFallback(sourcePath, targetPath);
continue;
}
stagePluginRuntimeOverlay(sourcePath, targetPath, relativePath);
continue;
}
@@ -448,6 +448,35 @@ describe("stageBundledPluginRuntime", () => {
expect(fs.readFileSync(runtimePackagePath, "utf8")).toContain('"extensions": [');
});
it("copies unpacked Chrome extension payloads without wrapping their JavaScript", () => {
const repoRoot = makeRepoRoot("openclaw-stage-bundled-runtime-chrome-extension-");
createDistPluginDir(repoRoot, "browser");
const background = "chrome.runtime.onInstalled.addListener(() => {});\n";
const popup = "document.body.dataset.ready = 'true';\n";
setupRepoFiles(repoRoot, {
[bundledDistPluginFile("browser", "chrome-extension/background.js")]: background,
[bundledDistPluginFile("browser", "chrome-extension/popup.js")]: popup,
[bundledDistPluginFile("browser", "chrome-extension/manifest.json")]: "{}\n",
});
stageBundledPluginRuntime({ repoRoot });
const runtimeExtensionDir = path.join(
repoRoot,
"dist-runtime",
"extensions",
"browser",
"chrome-extension",
);
expect(fs.readFileSync(path.join(runtimeExtensionDir, "background.js"), "utf8")).toBe(
background,
);
expect(fs.readFileSync(path.join(runtimeExtensionDir, "popup.js"), "utf8")).toBe(popup);
expect(fs.lstatSync(path.join(runtimeExtensionDir, "background.js")).isSymbolicLink()).toBe(
false,
);
});
it("copies bundled plugin skill trees into the runtime overlay", () => {
const repoRoot = makeRepoRoot("openclaw-stage-bundled-runtime-skills-");
createDistPluginDir(repoRoot, "feishu");
+15 -1
View File
@@ -317,12 +317,12 @@ describe("resolveBuildAllSteps", () => {
"plugins:assets:build",
"tsdown",
"check-cli-bootstrap-imports",
"plugins:assets:copy",
"runtime-postbuild",
"build-stamp",
"runtime-postbuild-stamp",
"write-plugin-sdk-entry-dts",
"check-plugin-sdk-exports",
"plugins:assets:copy",
"copy-hook-metadata",
"copy-export-html-templates",
"ui:build",
@@ -403,6 +403,7 @@ describe("resolveBuildAllSteps", () => {
"plugins:assets:build",
"tsdown",
"check-cli-bootstrap-imports",
"plugins:assets:copy",
"runtime-postbuild",
"build-stamp",
"runtime-postbuild-stamp",
@@ -461,6 +462,19 @@ describe("resolveBuildAllSteps", () => {
});
});
it("copies generated plugin assets before runtime postbuild snapshots static outputs", () => {
for (const profile of ["full", "ciArtifacts", "qaRuntime"]) {
const labels = resolveBuildAllSteps(profile).map((step) => step.label);
expect(labels.indexOf("plugins:assets:copy")).toBeGreaterThan(labels.indexOf("tsdown"));
expect(labels.indexOf("runtime-postbuild")).toBeGreaterThan(
labels.indexOf("plugins:assets:copy"),
);
expect(labels.indexOf("runtime-postbuild-stamp")).toBeGreaterThan(
labels.indexOf("runtime-postbuild"),
);
}
});
it("writes the runtime postbuild stamp after the build stamp", () => {
const labels = resolveBuildAllSteps("full").map((step) => step.label);
expect(labels).toContain("runtime-postbuild");