refactor(qa): split Matrix QA into optional plugin (#66723)

Merged via squash.

Prepared head SHA: 27241bd089
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Co-authored-by: gumadeiras <5599352+gumadeiras@users.noreply.github.com>
Reviewed-by: @gumadeiras
This commit is contained in:
Gustavo Madeira Santana
2026-04-14 16:28:57 -04:00
committed by GitHub
parent 3425823dfb
commit 82a2db71e8
69 changed files with 2026 additions and 229 deletions

View File

@@ -0,0 +1,143 @@
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { afterEach, beforeEach, describe, expect, it } from "vitest";
import { clearPluginDiscoveryCache } from "../plugins/discovery.js";
import { clearPluginManifestRegistryCache } from "../plugins/manifest-registry.js";
import { resetFacadeRuntimeStateForTest } from "./facade-runtime.js";
const ORIGINAL_ENV = {
OPENCLAW_DISABLE_BUNDLED_PLUGINS: process.env.OPENCLAW_DISABLE_BUNDLED_PLUGINS,
OPENCLAW_CONFIG_PATH: process.env.OPENCLAW_CONFIG_PATH,
OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE: process.env.OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE,
OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE: process.env.OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE,
OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS: process.env.OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS,
OPENCLAW_PLUGIN_MANIFEST_CACHE_MS: process.env.OPENCLAW_PLUGIN_MANIFEST_CACHE_MS,
OPENCLAW_TEST_FAST: process.env.OPENCLAW_TEST_FAST,
} as const;
const tempDirs: string[] = [];
function makeTempDir(prefix: string): string {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix));
tempDirs.push(dir);
return dir;
}
function resetQaRunnerRuntimeState() {
clearPluginDiscoveryCache();
clearPluginManifestRegistryCache();
resetFacadeRuntimeStateForTest();
}
describe("plugin-sdk qa-runner-runtime linked plugin smoke", () => {
beforeEach(() => {
resetQaRunnerRuntimeState();
process.env.OPENCLAW_DISABLE_BUNDLED_PLUGINS = "1";
process.env.OPENCLAW_DISABLE_PLUGIN_DISCOVERY_CACHE = "1";
process.env.OPENCLAW_DISABLE_PLUGIN_MANIFEST_CACHE = "1";
process.env.OPENCLAW_PLUGIN_DISCOVERY_CACHE_MS = "0";
process.env.OPENCLAW_PLUGIN_MANIFEST_CACHE_MS = "0";
process.env.OPENCLAW_TEST_FAST = "1";
});
afterEach(() => {
resetQaRunnerRuntimeState();
for (const dir of tempDirs.splice(0)) {
fs.rmSync(dir, { recursive: true, force: true });
}
for (const [key, value] of Object.entries(ORIGINAL_ENV)) {
if (value === undefined) {
delete process.env[key];
} else {
process.env[key] = value;
}
}
});
it("loads an activated qa runner from a linked plugin path", async () => {
const stateDir = makeTempDir("openclaw-qa-runner-state-");
const pluginDir = path.join(stateDir, "extensions", "qa-linked");
const configPath = path.join(stateDir, "openclaw.json");
fs.writeFileSync(
configPath,
JSON.stringify({
plugins: {},
}),
"utf8",
);
process.env.OPENCLAW_CONFIG_PATH = configPath;
fs.mkdirSync(pluginDir, { recursive: true });
fs.writeFileSync(
path.join(pluginDir, "openclaw.plugin.json"),
JSON.stringify({
id: "qa-linked",
qaRunners: [
{
commandName: "linked",
description: "Run the linked QA lane",
},
],
configSchema: {
type: "object",
additionalProperties: false,
properties: {},
},
}),
"utf8",
);
fs.writeFileSync(
path.join(pluginDir, "package.json"),
JSON.stringify({
name: "@openclaw/qa-linked",
type: "module",
openclaw: {
extensions: ["./index.js"],
install: {
npmSpec: "@openclaw/qa-linked",
},
},
}),
"utf8",
);
fs.writeFileSync(path.join(pluginDir, "index.js"), 'export default {};\n', "utf8");
fs.writeFileSync(
path.join(pluginDir, "runtime-api.js"),
[
"export const qaRunnerCliRegistrations = [",
" {",
' commandName: "linked",',
" register() {}",
" }",
"];",
].join("\n"),
"utf8",
);
const module = await import("./qa-runner-runtime.js");
expect(module.listQaRunnerCliContributions()).toEqual(
expect.arrayContaining([
{
pluginId: "qa-linked",
commandName: "linked",
description: "Run the linked QA lane",
status: "available",
registration: {
commandName: "linked",
register: expect.any(Function),
},
},
{
pluginId: "qa-matrix",
commandName: "matrix",
description: "Run the Docker-backed Matrix live QA lane against a disposable homeserver",
status: "missing",
npmSpec: "@openclaw/qa-matrix",
},
]),
);
});
});