From 685ef52284ab2db860e21ac5dfe7ceb8c53fffe8 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Fri, 3 Apr 2026 12:58:46 +0100 Subject: [PATCH] refactor: simplify test workflow helpers --- .github/workflows/ci.yml | 129 ++++++++++++- .github/workflows/install-smoke.yml | 20 +- docs/reference/RELEASING.md | 2 +- scripts/ci-write-manifest-outputs.mjs | 182 ------------------ scripts/test-extension.mjs | 38 ++-- .../scripts/ci-write-manifest-outputs.test.ts | 99 ---------- test/scripts/test-extension.test.ts | 23 +-- vitest.config.ts | 1 - 8 files changed, 167 insertions(+), 327 deletions(-) delete mode 100644 scripts/ci-write-manifest-outputs.mjs delete mode 100644 test/scripts/ci-write-manifest-outputs.test.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c9998192299..3a1012b09f7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -129,7 +129,134 @@ jobs: OPENCLAW_CI_RUN_SKILLS_PYTHON: ${{ steps.changed_scope.outputs.run_skills_python || 'false' }} OPENCLAW_CI_HAS_CHANGED_EXTENSIONS: ${{ steps.changed_extensions.outputs.has_changed_extensions || 'false' }} OPENCLAW_CI_CHANGED_EXTENSIONS_MATRIX: ${{ steps.changed_extensions.outputs.changed_extensions_matrix || '{"include":[]}' }} - run: node scripts/ci-write-manifest-outputs.mjs --workflow ci + run: | + node --input-type=module <<'EOF' + import { appendFileSync } from "node:fs"; + + const parseBoolean = (value, fallback = false) => { + if (value === undefined) return fallback; + const normalized = value.trim().toLowerCase(); + if (normalized === "true" || normalized === "1") return true; + if (normalized === "false" || normalized === "0" || normalized === "") return false; + return fallback; + }; + + const parseJson = (value, fallback) => { + try { + return value ? JSON.parse(value) : fallback; + } catch { + return fallback; + } + }; + + const createMatrix = (include) => ({ include }); + const outputPath = process.env.GITHUB_OUTPUT; + const eventName = process.env.GITHUB_EVENT_NAME ?? "pull_request"; + const isPush = eventName === "push"; + const docsOnly = parseBoolean(process.env.OPENCLAW_CI_DOCS_ONLY); + const docsChanged = parseBoolean(process.env.OPENCLAW_CI_DOCS_CHANGED); + const runNode = parseBoolean(process.env.OPENCLAW_CI_RUN_NODE) && !docsOnly; + const runMacos = parseBoolean(process.env.OPENCLAW_CI_RUN_MACOS) && !docsOnly; + const runAndroid = parseBoolean(process.env.OPENCLAW_CI_RUN_ANDROID) && !docsOnly; + const runWindows = parseBoolean(process.env.OPENCLAW_CI_RUN_WINDOWS) && !docsOnly; + const runSkillsPython = parseBoolean(process.env.OPENCLAW_CI_RUN_SKILLS_PYTHON) && !docsOnly; + const hasChangedExtensions = + parseBoolean(process.env.OPENCLAW_CI_HAS_CHANGED_EXTENSIONS) && !docsOnly; + const changedExtensionsMatrix = hasChangedExtensions + ? parseJson(process.env.OPENCLAW_CI_CHANGED_EXTENSIONS_MATRIX, { include: [] }) + : { include: [] }; + + const manifest = { + docs_only: docsOnly, + docs_changed: docsChanged, + run_node: runNode, + run_macos: runMacos, + run_android: runAndroid, + run_skills_python: runSkillsPython, + run_windows: runWindows, + has_changed_extensions: hasChangedExtensions, + changed_extensions_matrix: changedExtensionsMatrix, + run_build_artifacts: runNode, + run_checks_fast: runNode, + checks_fast_matrix: createMatrix( + runNode + ? [ + { check_name: "checks-fast-bundled", runtime: "node", task: "bundled" }, + { check_name: "checks-fast-extensions", runtime: "node", task: "extensions" }, + { + check_name: "checks-fast-contracts-protocol", + runtime: "node", + task: "contracts-protocol", + }, + ] + : [], + ), + run_checks: runNode, + checks_matrix: createMatrix( + runNode + ? [ + { check_name: "checks-node-test", runtime: "node", task: "test" }, + { check_name: "checks-node-channels", runtime: "node", task: "channels" }, + ...(isPush + ? [ + { + check_name: "checks-node-compat-node22", + runtime: "node", + task: "compat-node22", + node_version: "22.x", + cache_key_suffix: "node22", + }, + ] + : []), + ] + : [], + ), + run_extension_fast: hasChangedExtensions, + extension_fast_matrix: createMatrix( + hasChangedExtensions + ? (changedExtensionsMatrix.include ?? []).map((entry) => ({ + check_name: `extension-fast-${entry.extension}`, + extension: entry.extension, + })) + : [], + ), + run_check: runNode, + run_check_additional: runNode, + run_build_smoke: runNode, + run_check_docs: docsChanged, + run_skills_python_job: runSkillsPython, + run_checks_windows: runWindows, + checks_windows_matrix: createMatrix( + runWindows + ? [{ check_name: "checks-windows-node-test", runtime: "node", task: "test" }] + : [], + ), + run_macos_node: runMacos, + macos_node_matrix: createMatrix( + runMacos ? [{ check_name: "macos-node", runtime: "node", task: "test" }] : [], + ), + run_macos_swift: runMacos, + run_android_job: runAndroid, + android_matrix: createMatrix( + runAndroid + ? [ + { check_name: "android-test-play", task: "test-play" }, + { check_name: "android-test-third-party", task: "test-third-party" }, + { check_name: "android-build-play", task: "build-play" }, + { check_name: "android-build-third-party", task: "build-third-party" }, + ] + : [], + ), + }; + + for (const [key, value] of Object.entries(manifest)) { + appendFileSync( + outputPath, + `${key}=${typeof value === "string" ? value : JSON.stringify(value)}\n`, + "utf8", + ); + } + EOF # Run the fast security/SCM checks in parallel with scope detection so the # main Node jobs do not have to wait for Python/pre-commit setup. diff --git a/.github/workflows/install-smoke.yml b/.github/workflows/install-smoke.yml index 8dc93dc09ba..ccacbd52e36 100644 --- a/.github/workflows/install-smoke.yml +++ b/.github/workflows/install-smoke.yml @@ -67,16 +67,18 @@ jobs: id: manifest env: OPENCLAW_CI_DOCS_ONLY: ${{ steps.docs_scope.outputs.docs_only }} - OPENCLAW_CI_DOCS_CHANGED: "false" - OPENCLAW_CI_RUN_NODE: "false" - OPENCLAW_CI_RUN_MACOS: "false" - OPENCLAW_CI_RUN_ANDROID: "false" - OPENCLAW_CI_RUN_WINDOWS: "false" - OPENCLAW_CI_RUN_SKILLS_PYTHON: "false" - OPENCLAW_CI_HAS_CHANGED_EXTENSIONS: "false" - OPENCLAW_CI_CHANGED_EXTENSIONS_MATRIX: '{"include":[]}' OPENCLAW_CI_RUN_CHANGED_SMOKE: ${{ steps.changed_scope.outputs.run_changed_smoke || 'false' }} - run: node scripts/ci-write-manifest-outputs.mjs --workflow install-smoke + run: | + docs_only="${OPENCLAW_CI_DOCS_ONLY:-false}" + run_changed_smoke="${OPENCLAW_CI_RUN_CHANGED_SMOKE:-false}" + run_install_smoke=false + if [ "$docs_only" != "true" ] && [ "$run_changed_smoke" = "true" ]; then + run_install_smoke=true + fi + { + echo "docs_only=$docs_only" + echo "run_install_smoke=$run_install_smoke" + } >> "$GITHUB_OUTPUT" install-smoke: needs: [preflight] diff --git a/docs/reference/RELEASING.md b/docs/reference/RELEASING.md index 970c7131ee4..fa1f31a9f58 100644 --- a/docs/reference/RELEASING.md +++ b/docs/reference/RELEASING.md @@ -67,7 +67,7 @@ OpenClaw has three public release lanes: so we do not ship an empty browser dashboard again - If the release work touched CI planning, extension timing manifests, or fast test matrices, regenerate and review the planner-owned `checks-fast-extensions` - shard plan via `node scripts/ci-write-manifest-outputs.mjs --workflow ci` + workflow matrix outputs from `.github/workflows/ci.yml` before approval so release notes do not describe a stale CI layout - Stable macOS release readiness also includes the updater surfaces: - the GitHub release must end up with the packaged `.zip`, `.dmg`, and `.dSYM.zip` diff --git a/scripts/ci-write-manifest-outputs.mjs b/scripts/ci-write-manifest-outputs.mjs deleted file mode 100644 index e21c16578a4..00000000000 --- a/scripts/ci-write-manifest-outputs.mjs +++ /dev/null @@ -1,182 +0,0 @@ -import { appendFileSync } from "node:fs"; -import path from "node:path"; -import { pathToFileURL } from "node:url"; - -const WORKFLOWS = new Set(["ci", "install-smoke"]); - -const parseArgs = (argv) => { - const parsed = { - workflow: "ci", - }; - for (let index = 0; index < argv.length; index += 1) { - const arg = argv[index]; - if (arg === "--workflow") { - const nextValue = argv[index + 1] ?? ""; - if (!WORKFLOWS.has(nextValue)) { - throw new Error( - `Unsupported --workflow value "${String(nextValue || "")}". Supported values: ci, install-smoke.`, - ); - } - parsed.workflow = nextValue; - index += 1; - } - } - return parsed; -}; - -const parseBooleanEnv = (value, defaultValue = false) => { - if (value === undefined) { - return defaultValue; - } - const normalized = value.trim().toLowerCase(); - if (normalized === "true" || normalized === "1") { - return true; - } - if (normalized === "false" || normalized === "0" || normalized === "") { - return false; - } - return defaultValue; -}; - -const parseJsonEnv = (value, fallback) => { - try { - return value ? JSON.parse(value) : fallback; - } catch { - return fallback; - } -}; - -const createMatrix = (include) => ({ include }); - -export function buildWorkflowManifest(env = process.env, workflow = "ci") { - const eventName = env.GITHUB_EVENT_NAME ?? "pull_request"; - const isPush = eventName === "push"; - const docsOnly = parseBooleanEnv(env.OPENCLAW_CI_DOCS_ONLY); - const docsChanged = parseBooleanEnv(env.OPENCLAW_CI_DOCS_CHANGED); - const runNode = parseBooleanEnv(env.OPENCLAW_CI_RUN_NODE); - const runMacos = parseBooleanEnv(env.OPENCLAW_CI_RUN_MACOS); - const runAndroid = parseBooleanEnv(env.OPENCLAW_CI_RUN_ANDROID); - const runWindows = parseBooleanEnv(env.OPENCLAW_CI_RUN_WINDOWS); - const runSkillsPython = parseBooleanEnv(env.OPENCLAW_CI_RUN_SKILLS_PYTHON); - const hasChangedExtensions = parseBooleanEnv(env.OPENCLAW_CI_HAS_CHANGED_EXTENSIONS); - const changedExtensionsMatrix = parseJsonEnv(env.OPENCLAW_CI_CHANGED_EXTENSIONS_MATRIX, { - include: [], - }); - const runChangedSmoke = parseBooleanEnv(env.OPENCLAW_CI_RUN_CHANGED_SMOKE); - - const checksFastMatrix = createMatrix( - runNode - ? [ - { check_name: "checks-fast-bundled", runtime: "node", task: "bundled" }, - { check_name: "checks-fast-extensions", runtime: "node", task: "extensions" }, - { - check_name: "checks-fast-contracts-protocol", - runtime: "node", - task: "contracts-protocol", - }, - ] - : [], - ); - - const checksMatrixInclude = runNode - ? [ - { check_name: "checks-node-test", runtime: "node", task: "test" }, - { check_name: "checks-node-channels", runtime: "node", task: "channels" }, - ...(isPush - ? [ - { - check_name: "checks-node-compat-node22", - runtime: "node", - task: "compat-node22", - node_version: "22.x", - cache_key_suffix: "node22", - }, - ] - : []), - ] - : []; - - const windowsMatrix = createMatrix( - runWindows ? [{ check_name: "checks-windows-node-test", runtime: "node", task: "test" }] : [], - ); - const macosNodeMatrix = createMatrix( - runMacos ? [{ check_name: "macos-node", runtime: "node", task: "test" }] : [], - ); - const androidMatrix = createMatrix( - runAndroid - ? [ - { check_name: "android-test-play", task: "test-play" }, - { check_name: "android-test-third-party", task: "test-third-party" }, - { check_name: "android-build-play", task: "build-play" }, - { check_name: "android-build-third-party", task: "build-third-party" }, - ] - : [], - ); - const extensionFastMatrix = createMatrix( - hasChangedExtensions - ? (changedExtensionsMatrix.include ?? []).map((entry) => ({ - check_name: `extension-fast-${entry.extension}`, - extension: entry.extension, - })) - : [], - ); - - if (workflow === "install-smoke") { - return { - docs_only: docsOnly, - run_install_smoke: !docsOnly && runChangedSmoke, - }; - } - - return { - docs_only: docsOnly, - docs_changed: docsChanged, - run_node: !docsOnly && runNode, - run_macos: !docsOnly && runMacos, - run_android: !docsOnly && runAndroid, - run_skills_python: !docsOnly && runSkillsPython, - run_windows: !docsOnly && runWindows, - has_changed_extensions: !docsOnly && hasChangedExtensions, - changed_extensions_matrix: changedExtensionsMatrix, - run_build_artifacts: !docsOnly && runNode, - run_checks_fast: !docsOnly && runNode, - checks_fast_matrix: checksFastMatrix, - run_checks: !docsOnly && runNode, - checks_matrix: createMatrix(checksMatrixInclude), - run_extension_fast: !docsOnly && hasChangedExtensions, - extension_fast_matrix: extensionFastMatrix, - run_check: !docsOnly && runNode, - run_check_additional: !docsOnly && runNode, - run_build_smoke: !docsOnly && runNode, - run_check_docs: docsChanged, - run_skills_python_job: !docsOnly && runSkillsPython, - run_checks_windows: !docsOnly && runWindows, - checks_windows_matrix: windowsMatrix, - run_macos_node: !docsOnly && runMacos, - macos_node_matrix: macosNodeMatrix, - run_macos_swift: !docsOnly && runMacos, - run_android_job: !docsOnly && runAndroid, - android_matrix: androidMatrix, - }; -} - -const entryHref = process.argv[1] ? pathToFileURL(path.resolve(process.argv[1])).href : ""; - -if (import.meta.url === entryHref) { - const outputPath = process.env.GITHUB_OUTPUT; - - if (!outputPath) { - throw new Error("GITHUB_OUTPUT is required"); - } - - const { workflow } = parseArgs(process.argv.slice(2)); - const manifest = buildWorkflowManifest(process.env, workflow); - - const writeOutput = (name, value) => { - appendFileSync(outputPath, `${name}=${value}\n`, "utf8"); - }; - - for (const [key, value] of Object.entries(manifest)) { - writeOutput(key, typeof value === "string" ? value : JSON.stringify(value)); - } -} diff --git a/scripts/test-extension.mjs b/scripts/test-extension.mjs index c02d5f28204..34258374289 100644 --- a/scripts/test-extension.mjs +++ b/scripts/test-extension.mjs @@ -28,12 +28,8 @@ function normalizeRelative(inputPath) { return inputPath.split(path.sep).join("/"); } -function isTestFile(filePath) { - return filePath.endsWith(".test.ts") || filePath.endsWith(".test.tsx"); -} - -function collectTestFiles(rootPath) { - const results = []; +function countTestFiles(rootPath) { + let total = 0; const stack = [rootPath]; while (stack.length > 0) { @@ -50,13 +46,13 @@ function collectTestFiles(rootPath) { stack.push(fullPath); continue; } - if (entry.isFile() && isTestFile(fullPath)) { - results.push(fullPath); + if (entry.isFile() && (fullPath.endsWith(".test.ts") || fullPath.endsWith(".test.tsx"))) { + total += 1; } } } - return results.toSorted((left, right) => left.localeCompare(right)); + return total; } function hasGitCommit(ref) { @@ -224,22 +220,22 @@ export function resolveExtensionTestPlan(params = {}) { const pairedCoreRoot = path.join(repoRoot, "src", extensionId); if (fs.existsSync(pairedCoreRoot)) { const pairedRelativeRoot = normalizeRelative(path.relative(repoRoot, pairedCoreRoot)); - if (collectTestFiles(pairedCoreRoot).length > 0) { - roots.push(pairedRelativeRoot); - } + roots.push(pairedRelativeRoot); } const usesChannelConfig = roots.some((root) => channelTestRoots.includes(root)); const config = usesChannelConfig ? "vitest.channels.config.ts" : "vitest.extensions.config.ts"; - const testFiles = roots - .flatMap((root) => collectTestFiles(path.join(repoRoot, root))) - .map((filePath) => normalizeRelative(path.relative(repoRoot, filePath))); + const testFileCount = roots.reduce( + (sum, root) => sum + countTestFiles(path.join(repoRoot, root)), + 0, + ); return { config, extensionDir: relativeExtensionDir, extensionId, + hasTests: testFileCount > 0, roots, - testFiles, + testFileCount, }; } @@ -247,7 +243,7 @@ async function runVitestBatch(params) { return await new Promise((resolve, reject) => { const child = spawn( pnpm, - ["exec", "vitest", "run", "--config", params.config, ...params.files, ...params.args], + ["exec", "vitest", "run", "--config", params.config, ...params.targets, ...params.args], { cwd: repoRoot, stdio: "inherit", @@ -382,23 +378,23 @@ async function run() { console.log(`[test-extension] ${plan.extensionId}`); console.log(`config: ${plan.config}`); console.log(`roots: ${plan.roots.join(", ")}`); - console.log(`tests: ${plan.testFiles.length}`); + console.log(`tests: ${plan.testFileCount}`); } return; } - if (plan.testFiles.length === 0) { + if (!plan.hasTests) { process.exit(printNoTestsMessage(plan, requireTests)); } console.log( - `[test-extension] Running ${plan.testFiles.length} test files for ${plan.extensionId} with ${plan.config}`, + `[test-extension] Running ${plan.testFileCount} test files for ${plan.extensionId} with ${plan.config}`, ); const exitCode = await runVitestBatch({ args: passthroughArgs, config: plan.config, env: process.env, - files: plan.testFiles, + targets: plan.roots, }); process.exit(exitCode); } diff --git a/test/scripts/ci-write-manifest-outputs.test.ts b/test/scripts/ci-write-manifest-outputs.test.ts deleted file mode 100644 index 731cca73e7c..00000000000 --- a/test/scripts/ci-write-manifest-outputs.test.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { buildWorkflowManifest } from "../../scripts/ci-write-manifest-outputs.mjs"; - -describe("buildWorkflowManifest", () => { - it("builds static CI matrices from scope env", () => { - const manifest = buildWorkflowManifest({ - GITHUB_EVENT_NAME: "pull_request", - OPENCLAW_CI_DOCS_ONLY: "false", - OPENCLAW_CI_DOCS_CHANGED: "false", - OPENCLAW_CI_RUN_NODE: "true", - OPENCLAW_CI_RUN_MACOS: "true", - OPENCLAW_CI_RUN_ANDROID: "true", - OPENCLAW_CI_RUN_WINDOWS: "true", - OPENCLAW_CI_RUN_SKILLS_PYTHON: "false", - OPENCLAW_CI_HAS_CHANGED_EXTENSIONS: "true", - OPENCLAW_CI_CHANGED_EXTENSIONS_MATRIX: '{"include":[{"extension":"discord"}]}', - }); - - expect(manifest.run_checks).toBe(true); - expect(manifest.checks_fast_matrix).toEqual({ - include: [ - { check_name: "checks-fast-bundled", runtime: "node", task: "bundled" }, - { check_name: "checks-fast-extensions", runtime: "node", task: "extensions" }, - { - check_name: "checks-fast-contracts-protocol", - runtime: "node", - task: "contracts-protocol", - }, - ], - }); - expect(manifest.checks_matrix).toEqual({ - include: [ - { check_name: "checks-node-test", runtime: "node", task: "test" }, - { check_name: "checks-node-channels", runtime: "node", task: "channels" }, - ], - }); - expect(manifest.checks_windows_matrix).toEqual({ - include: [{ check_name: "checks-windows-node-test", runtime: "node", task: "test" }], - }); - expect(manifest.extension_fast_matrix).toEqual({ - include: [{ check_name: "extension-fast-discord", extension: "discord" }], - }); - expect(manifest.android_matrix).toHaveProperty("include"); - expect(manifest.macos_node_matrix).toEqual({ - include: [{ check_name: "macos-node", runtime: "node", task: "test" }], - }); - }); - - it("includes the push-only compat lane on pushes", () => { - const manifest = buildWorkflowManifest({ - GITHUB_EVENT_NAME: "push", - OPENCLAW_CI_DOCS_ONLY: "false", - OPENCLAW_CI_DOCS_CHANGED: "false", - OPENCLAW_CI_RUN_NODE: "true", - }); - - expect(manifest.checks_matrix).toEqual({ - include: [ - { check_name: "checks-node-test", runtime: "node", task: "test" }, - { check_name: "checks-node-channels", runtime: "node", task: "channels" }, - { - check_name: "checks-node-compat-node22", - runtime: "node", - task: "compat-node22", - node_version: "22.x", - cache_key_suffix: "node22", - }, - ], - }); - }); - - it("suppresses heavy jobs for docs-only changes", () => { - const manifest = buildWorkflowManifest({ - OPENCLAW_CI_DOCS_ONLY: "true", - OPENCLAW_CI_DOCS_CHANGED: "true", - OPENCLAW_CI_RUN_NODE: "true", - OPENCLAW_CI_RUN_WINDOWS: "true", - }); - - expect(manifest.run_checks).toBe(false); - expect(manifest.run_checks_windows).toBe(false); - expect(manifest.run_check_docs).toBe(true); - }); - - it("builds install-smoke outputs separately", () => { - const manifest = buildWorkflowManifest( - { - OPENCLAW_CI_DOCS_ONLY: "false", - OPENCLAW_CI_RUN_CHANGED_SMOKE: "true", - }, - "install-smoke", - ); - - expect(manifest).toEqual({ - docs_only: false, - run_install_smoke: true, - }); - }); -}); diff --git a/test/scripts/test-extension.test.ts b/test/scripts/test-extension.test.ts index 867790e0629..136817e112f 100644 --- a/test/scripts/test-extension.test.ts +++ b/test/scripts/test-extension.test.ts @@ -28,8 +28,7 @@ function runScript(args: string[], cwd = process.cwd()) { function findExtensionWithoutTests() { const extensionId = listAvailableExtensionIds().find( - (candidate) => - resolveExtensionTestPlan({ targetArg: candidate, cwd: process.cwd() }).testFiles.length === 0, + (candidate) => !resolveExtensionTestPlan({ targetArg: candidate, cwd: process.cwd() }).hasTests, ); expect(extensionId).toBeDefined(); @@ -43,9 +42,8 @@ describe("scripts/test-extension.mjs", () => { expect(plan.extensionId).toBe("slack"); expect(plan.extensionDir).toBe(bundledPluginRoot("slack")); expect(plan.config).toBe("vitest.channels.config.ts"); - expect(plan.testFiles.some((file) => file.startsWith(`${bundledPluginRoot("slack")}/`))).toBe( - true, - ); + expect(plan.roots).toContain(bundledPluginRoot("slack")); + expect(plan.hasTests).toBe(true); }); it("resolves provider extensions onto the extensions vitest config", () => { @@ -53,19 +51,17 @@ describe("scripts/test-extension.mjs", () => { expect(plan.extensionId).toBe("firecrawl"); expect(plan.config).toBe("vitest.extensions.config.ts"); - expect( - plan.testFiles.some((file) => file.startsWith(`${bundledPluginRoot("firecrawl")}/`)), - ).toBe(true); + expect(plan.roots).toContain(bundledPluginRoot("firecrawl")); + expect(plan.hasTests).toBe(true); }); - it("includes paired src roots when they contain tests", () => { + it("keeps extension-root plans lean when there is no paired core test root", () => { const plan = resolveExtensionTestPlan({ targetArg: "line", cwd: process.cwd() }); expect(plan.roots).toContain(bundledPluginRoot("line")); + expect(plan.roots).not.toContain("src/line"); expect(plan.config).toBe("vitest.extensions.config.ts"); - expect(plan.testFiles.some((file) => file.startsWith(`${bundledPluginRoot("line")}/`))).toBe( - true, - ); + expect(plan.hasTests).toBe(true); }); it("infers the extension from the current working directory", () => { @@ -111,7 +107,8 @@ describe("scripts/test-extension.mjs", () => { const plan = readPlan([extensionId]); expect(plan.extensionId).toBe(extensionId); - expect(plan.testFiles).toEqual([]); + expect(plan.hasTests).toBe(false); + expect(plan.testFileCount).toBe(0); }); it("treats extensions without tests as a no-op by default", () => { diff --git a/vitest.config.ts b/vitest.config.ts index 2d3af3a2796..e261bca57be 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -79,7 +79,6 @@ export default defineConfig({ "test/setup.shared.ts", "test/setup.extensions.ts", "scripts/test-projects.mjs", - "scripts/ci-write-manifest-outputs.mjs", "vitest.channel-paths.mjs", "vitest.channels.config.ts", "vitest.bundled.config.ts",