fix(ci): stabilize full release validation lanes

This commit is contained in:
Peter Steinberger
2026-04-28 20:36:15 +01:00
parent 1e9faa2a59
commit 933c7968dc
7 changed files with 58 additions and 42 deletions

View File

@@ -7,7 +7,6 @@
"dependencies": {
"@copilotkit/aimock": "1.15.1",
"@modelcontextprotocol/sdk": "1.29.0",
"@openclaw/qa-channel": "workspace:*",
"playwright-core": "1.59.1",
"yaml": "^2.8.3",
"zod": "^4.3.6"

View File

@@ -20,7 +20,7 @@ export {
searchQaBusMessages,
sendQaBusMessage,
setQaChannelRuntime,
} from "@openclaw/qa-channel/api.js";
} from "openclaw/plugin-sdk/qa-channel";
export type {
QaBusAttachment,
QaBusConversation,

3
pnpm-lock.yaml generated
View File

@@ -1117,9 +1117,6 @@ importers:
'@modelcontextprotocol/sdk':
specifier: 1.29.0
version: 1.29.0(zod@4.3.6)
'@openclaw/qa-channel':
specifier: workspace:*
version: link:../qa-channel
playwright-core:
specifier: 1.59.1
version: 1.59.1

View File

@@ -1 +1 @@
["qa-lab", "qa-runtime"]
["qa-channel", "qa-channel-protocol", "qa-lab", "qa-runtime"]

View File

@@ -3,7 +3,6 @@ import path from "node:path";
import { formatCliCommand } from "../cli/command-format.js";
import type { OpenClawConfig } from "../config/types.openclaw.js";
import { resolveOpenClawPackageRootSync } from "../infra/openclaw-root.js";
import { resolveBundledPluginsDir } from "../plugins/bundled-dir.js";
import {
createBundledRuntimeDepsWritableInstallSpecs,
repairBundledRuntimeDepsInstallRootAsync,
@@ -12,7 +11,6 @@ import {
type BundledRuntimeDepsInstallParams,
} from "../plugins/bundled-runtime-deps.js";
import { normalizePluginsConfig } from "../plugins/config-state.js";
import { resolveEffectivePluginIds } from "../plugins/effective-plugin-ids.js";
import { passesManifestOwnerBasePolicy } from "../plugins/manifest-owner-policy.js";
import type { RuntimeEnv } from "../runtime.js";
import { note } from "../terminal/note.js";
@@ -20,19 +18,6 @@ import type { DoctorPrompter } from "./doctor-prompter.js";
const RUNTIME_DEPS_INSTALL_HEARTBEAT_MS = 15_000;
function filterPluginIdsPresentInBundledTree(
bundledPluginsDir: string,
pluginIds: readonly string[],
): string[] | undefined {
const present = pluginIds.filter((pluginId) => {
if (path.basename(pluginId) !== pluginId) {
return false;
}
return fs.existsSync(path.join(bundledPluginsDir, pluginId));
});
return present.length > 0 ? present : undefined;
}
function collectPackagedRuntimeDepsRepairPluginIds(params: {
bundledPluginsDir: string;
config: OpenClawConfig;
@@ -143,23 +128,11 @@ export async function maybeRepairBundledPluginRuntimeDeps(params: {
const env = params.env ?? process.env;
const bundledPluginsDir = path.join(packageRoot, "dist", "extensions");
const effectivePluginIds = params.config
? resolveBundledPluginsDir({ ...env, OPENCLAW_BUNDLED_PLUGINS_DIR: bundledPluginsDir }) ===
bundledPluginsDir
? filterPluginIdsPresentInBundledTree(
bundledPluginsDir,
resolveEffectivePluginIds({
config: params.config,
env: {
...env,
OPENCLAW_BUNDLED_PLUGINS_DIR: bundledPluginsDir,
},
}),
)
: collectPackagedRuntimeDepsRepairPluginIds({
bundledPluginsDir,
config: params.config,
includeConfiguredChannels: params.includeConfiguredChannels,
})
? collectPackagedRuntimeDepsRepairPluginIds({
bundledPluginsDir,
config: params.config,
includeConfiguredChannels: params.includeConfiguredChannels,
})
: undefined;
const { deps, missing, conflicts } = scanBundledPluginRuntimeDeps({
packageRoot,

View File

@@ -64,11 +64,13 @@ function hasDiagnosticSourceSuffix(
}
function buildDiscoveryEnv(stateDir: string): NodeJS.ProcessEnv {
const bundledPluginsDir = path.join(stateDir, "empty-bundled-plugins");
mkdirSafe(bundledPluginsDir);
return {
OPENCLAW_STATE_DIR: stateDir,
OPENCLAW_HOME: undefined,
OPENCLAW_DISABLE_BUNDLED_PLUGINS: "1",
OPENCLAW_BUNDLED_PLUGINS_DIR: "/nonexistent/bundled/plugins",
OPENCLAW_BUNDLED_PLUGINS_DIR: bundledPluginsDir,
};
}

View File

@@ -101,7 +101,7 @@ function createPluginSdkAliasFixture(params?: {
mkdirSafeDir(path.join(root, "scripts", "lib"));
fs.writeFileSync(
path.join(root, "scripts", "lib", "plugin-sdk-private-local-only-subpaths.json"),
JSON.stringify(["qa-lab", "qa-runtime"], null, 2),
JSON.stringify(["qa-channel", "qa-channel-protocol", "qa-lab", "qa-runtime"], null, 2),
"utf-8",
);
fs.writeFileSync(srcFile, params?.srcBody ?? "export {};\n", "utf-8");
@@ -530,6 +530,16 @@ describe("plugin sdk alias helpers", () => {
"./plugin-sdk/core": { default: "./dist/plugin-sdk/core.js" },
},
});
fs.writeFileSync(
path.join(fixture.root, "src", "plugin-sdk", "qa-channel.ts"),
"export const qaChannel = true;\n",
"utf-8",
);
fs.writeFileSync(
path.join(fixture.root, "src", "plugin-sdk", "qa-channel-protocol.ts"),
"export const qaChannelProtocol = true;\n",
"utf-8",
);
fs.writeFileSync(
path.join(fixture.root, "src", "plugin-sdk", "qa-runtime.ts"),
"export const qaRuntime = true;\n",
@@ -546,7 +556,7 @@ describe("plugin sdk alias helpers", () => {
modulePath: path.join(fixture.root, "src", "plugins", "loader.ts"),
}),
);
expect(subpaths).toEqual(["core", "qa-lab", "qa-runtime"]);
expect(subpaths).toEqual(["core", "qa-channel", "qa-channel-protocol", "qa-lab", "qa-runtime"]);
});
it("does not reuse a non-private cached subpath list after private qa gets enabled", () => {
@@ -555,6 +565,16 @@ describe("plugin sdk alias helpers", () => {
"./plugin-sdk/core": { default: "./dist/plugin-sdk/core.js" },
},
});
fs.writeFileSync(
path.join(fixture.root, "src", "plugin-sdk", "qa-channel.ts"),
"export const qaChannel = true;\n",
"utf-8",
);
fs.writeFileSync(
path.join(fixture.root, "src", "plugin-sdk", "qa-channel-protocol.ts"),
"export const qaChannelProtocol = true;\n",
"utf-8",
);
fs.writeFileSync(
path.join(fixture.root, "src", "plugin-sdk", "qa-runtime.ts"),
"export const qaRuntime = true;\n",
@@ -577,7 +597,13 @@ describe("plugin sdk alias helpers", () => {
modulePath: path.join(fixture.root, "src", "plugins", "loader.ts"),
}),
);
expect(privateSubpaths).toEqual(["core", "qa-lab", "qa-runtime"]);
expect(privateSubpaths).toEqual([
"core",
"qa-channel",
"qa-channel-protocol",
"qa-lab",
"qa-runtime",
]);
});
it.each([
@@ -657,9 +683,22 @@ describe("plugin sdk alias helpers", () => {
},
});
const sourceRootAlias = path.join(fixture.root, "src", "plugin-sdk", "root-alias.cjs");
const sourceQaChannelPath = path.join(fixture.root, "src", "plugin-sdk", "qa-channel.ts");
const sourceQaChannelProtocolPath = path.join(
fixture.root,
"src",
"plugin-sdk",
"qa-channel-protocol.ts",
);
const sourceQaRuntimePath = path.join(fixture.root, "src", "plugin-sdk", "qa-runtime.ts");
const distQaLabPath = path.join(fixture.root, "dist", "plugin-sdk", "qa-lab.js");
fs.writeFileSync(sourceRootAlias, "module.exports = {};\n", "utf-8");
fs.writeFileSync(sourceQaChannelPath, "export const qaChannel = true;\n", "utf-8");
fs.writeFileSync(
sourceQaChannelProtocolPath,
"export const qaChannelProtocol = true;\n",
"utf-8",
);
fs.writeFileSync(sourceQaRuntimePath, "export const qaRuntime = true;\n", "utf-8");
fs.writeFileSync(distQaLabPath, "export const qaLab = true;\n", "utf-8");
const sourcePluginEntry = writePluginEntry(
@@ -677,6 +716,12 @@ describe("plugin sdk alias helpers", () => {
expect(fs.realpathSync(aliases["openclaw/plugin-sdk/qa-runtime"] ?? "")).toBe(
fs.realpathSync(sourceQaRuntimePath),
);
expect(fs.realpathSync(aliases["openclaw/plugin-sdk/qa-channel"] ?? "")).toBe(
fs.realpathSync(sourceQaChannelPath),
);
expect(fs.realpathSync(aliases["openclaw/plugin-sdk/qa-channel-protocol"] ?? "")).toBe(
fs.realpathSync(sourceQaChannelProtocolPath),
);
expect(fs.realpathSync(aliases["openclaw/plugin-sdk/qa-lab"] ?? "")).toBe(
fs.realpathSync(distQaLabPath),
);