Harden PR CI build-gap detection

This commit is contained in:
Devin Foley committed 2026-05-03 19:41:11 -07:00
1 parent 1e979acaa6
commit f6e536538b
3 files changed
+75 -2

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@
"build-storybook": "pnpm --filter @paperclipai/ui build-storybook",
"build": "pnpm run preflight:workspace-links && pnpm -r build",
"typecheck": "pnpm run preflight:workspace-links && pnpm -r typecheck",
"typecheck:build-gaps": "pnpm run preflight:workspace-links && pnpm --filter @paperclipai/plugin-sdk build && pnpm --filter paperclipai typecheck && pnpm --filter @paperclipai/plugin-authoring-smoke-example typecheck",
"typecheck:build-gaps": "pnpm run preflight:workspace-links && node scripts/run-typecheck-build-gaps.mjs",
"test": "pnpm run test:run",
"test:watch": "pnpm run preflight:workspace-links && vitest",
"test:run": "pnpm run preflight:workspace-links && node scripts/run-vitest-stable.mjs",
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env node
import { readFileSync } from "node:fs";
import path from "node:path";
import { spawnSync } from "node:child_process";
const repoRoot = process.cwd();
function fail(message) {
console.error(`[typecheck:build-gaps] ${message}`);
process.exit(1);
}
function run(command, args) {
const result = spawnSync(command, args, {
cwd: repoRoot,
stdio: "inherit",
});
if (result.status !== 0) {
process.exit(result.status ?? 1);
}
}
function readJson(filePath) {
return JSON.parse(readFileSync(filePath, "utf8"));
}
function listWorkspacePackages() {
const result = spawnSync("pnpm", ["ls", "-r", "--depth", "-1", "--json"], {
cwd: repoRoot,
encoding: "utf8",
});
if (result.status !== 0) {
fail("Unable to list pnpm workspace packages.");
}
return JSON.parse(result.stdout);
}
function buildSkipsTypeScript(pkg) {
const buildScript = pkg.scripts?.build;
const typecheckScript = pkg.scripts?.typecheck;
if (typeof buildScript !== "string" || typeof typecheckScript !== "string") {
return false;
}
return !/\btsc\b/.test(buildScript);
}
const workspacePackages = listWorkspacePackages();
const buildGapPackages = workspacePackages
.filter((workspacePkg) => workspacePkg.path !== repoRoot)
.map((workspacePkg) => ({
name: workspacePkg.name,
path: workspacePkg.path,
pkg: readJson(path.join(workspacePkg.path, "package.json")),
}))
.filter(({ pkg }) => buildSkipsTypeScript(pkg));
console.log(
`[typecheck:build-gaps] typechecking ${buildGapPackages.length} workspace(s): ${buildGapPackages.map(({ name }) => name).join(", ") || "(none)"}`,
);
if (buildGapPackages.length === 0) {
process.exit(0);
}
run("pnpm", ["--filter", "@paperclipai/plugin-sdk", "build"]);
for (const workspacePkg of buildGapPackages) {
run("pnpm", ["--filter", workspacePkg.name, "typecheck"]);
}
+1 -1
View File
@@ -87,7 +87,7 @@ function fail(message) {
function readOptionValue(argv, index, argName) {
const value = argv[index + 1];
if (!value) {
if (value === undefined) {
fail(`Missing value for ${argName}`);
}