QA: fix private dist freshness check

This commit is contained in:
Gustavo Madeira Santana
2026-04-16 03:44:40 -04:00
parent 4db162db7f
commit 05cac5b980
2 changed files with 40 additions and 9 deletions

View File

@@ -90,6 +90,11 @@ const statMtime = (filePath, fsImpl = fs) => {
}
};
const resolvePrivateQaRequiredDistEntries = (distRoot) => [
path.join(distRoot, "plugin-sdk", "qa-lab.js"),
path.join(distRoot, "plugin-sdk", "qa-runtime.js"),
];
const isExcludedSource = (filePath, sourceRoot, sourceRootName) => {
const relativePath = normalizePath(path.relative(sourceRoot, filePath));
if (relativePath.startsWith("..")) {
@@ -210,8 +215,9 @@ export const resolveBuildRequirement = (deps) => {
}
if (
deps.env.OPENCLAW_BUILD_PRIVATE_QA === "1" &&
((deps.privateQaDistEntry && statMtime(deps.privateQaDistEntry, deps.fs) == null) ||
(deps.privateQaBundledCliEntry && statMtime(deps.privateQaBundledCliEntry, deps.fs) == null))
(deps.privateQaRequiredDistEntries ?? resolvePrivateQaRequiredDistEntries(deps.distRoot)).some(
(entry) => statMtime(entry, deps.fs) == null,
)
) {
return { shouldBuild: true, reason: "missing_private_qa_dist" };
}
@@ -397,8 +403,7 @@ export async function runNodeMain(params = {}) {
path: path.join(deps.cwd, sourceRoot),
}));
deps.configFiles = runNodeConfigFiles.map((filePath) => path.join(deps.cwd, filePath));
deps.privateQaDistEntry = path.join(deps.distRoot, "plugin-sdk", "qa-lab.js");
deps.privateQaBundledCliEntry = path.join(deps.distRoot, "extensions", "qa-lab", "cli.js");
deps.privateQaRequiredDistEntries = resolvePrivateQaRequiredDistEntries(deps.distRoot);
if (deps.args[0] === "qa") {
deps.env.OPENCLAW_BUILD_PRIVATE_QA = "1";
deps.env.OPENCLAW_ENABLE_PRIVATE_QA_CLI = "1";

View File

@@ -20,7 +20,7 @@ const GENERATED_A2UI_BUNDLE_HASH = "src/canvas-host/a2ui/.bundle.hash";
const DIST_ENTRY = "dist/entry.js";
const BUILD_STAMP = "dist/.buildstamp";
const QA_LAB_PLUGIN_SDK_ENTRY = "dist/plugin-sdk/qa-lab.js";
const QA_LAB_BUNDLED_CLI_ENTRY = "dist/extensions/qa-lab/cli.js";
const QA_RUNTIME_PLUGIN_SDK_ENTRY = "dist/plugin-sdk/qa-runtime.js";
const EXTENSION_SRC = bundledPluginFile("demo", "src/index.ts");
const EXTENSION_MANIFEST = bundledPluginFile("demo", "openclaw.plugin.json");
const EXTENSION_PACKAGE = bundledPluginFile("demo", "package.json");
@@ -343,20 +343,20 @@ describe("run-node script", () => {
});
});
it("skips rebuilding for private QA commands when the QA CLI facade is present", async () => {
it("skips rebuilding for private QA commands when the private QA facades are present", async () => {
await withTempDir({ prefix: "openclaw-run-node-" }, async (tmp) => {
await setupTrackedProject(tmp, {
files: {
[ROOT_SRC]: "export const value = 1;\n",
[QA_LAB_PLUGIN_SDK_ENTRY]: "export const qaLab = true;\n",
[QA_LAB_BUNDLED_CLI_ENTRY]: "export const registerQaLabCli = () => {};\n",
[QA_RUNTIME_PLUGIN_SDK_ENTRY]: "export const qaRuntime = true;\n",
},
oldPaths: [
ROOT_SRC,
ROOT_TSCONFIG,
ROOT_PACKAGE,
QA_LAB_PLUGIN_SDK_ENTRY,
QA_LAB_BUNDLED_CLI_ENTRY,
QA_RUNTIME_PLUGIN_SDK_ENTRY,
],
buildPaths: [DIST_ENTRY, BUILD_STAMP],
});
@@ -383,7 +383,7 @@ describe("run-node script", () => {
});
});
it("rebuilds private QA commands when the QA bundled CLI surface is missing", async () => {
it("rebuilds private QA commands when the private QA runtime facade is missing", async () => {
await withTempDir({ prefix: "openclaw-run-node-" }, async (tmp) => {
await setupTrackedProject(tmp, {
files: {
@@ -417,6 +417,32 @@ describe("run-node script", () => {
});
});
it("derives private QA facade checks from distRoot for direct freshness checks", async () => {
await withTempDir({ prefix: "openclaw-run-node-" }, async (tmp) => {
await setupTrackedProject(tmp, {
files: {
[ROOT_SRC]: "export const value = 1;\n",
[QA_LAB_PLUGIN_SDK_ENTRY]: "export const qaLab = true;\n",
},
oldPaths: [ROOT_SRC, ROOT_TSCONFIG, ROOT_PACKAGE, QA_LAB_PLUGIN_SDK_ENTRY],
buildPaths: [DIST_ENTRY, BUILD_STAMP],
});
const requirement = resolveBuildRequirement(
createBuildRequirementDeps(tmp, {
env: { OPENCLAW_BUILD_PRIVATE_QA: "1" },
gitHead: "abc123\n",
gitStatus: "",
}),
);
expect(requirement).toEqual({
shouldBuild: true,
reason: "missing_private_qa_dist",
});
});
});
it("skips runtime postbuild restaging in watch mode when dist is already current", async () => {
await withTempDir({ prefix: "openclaw-run-node-" }, async (tmp) => {
await setupTrackedProject(tmp, {