diff --git a/scripts/release-check.ts b/scripts/release-check.ts index 2a54ae754..9a22467d6 100755 --- a/scripts/release-check.ts +++ b/scripts/release-check.ts @@ -1,6 +1,8 @@ #!/usr/bin/env bun import { execSync } from "node:child_process"; +import { readdirSync, readFileSync } from "node:fs"; +import { join, resolve } from "node:path"; type PackFile = { path: string }; type PackResult = { files?: PackFile[] }; @@ -13,6 +15,11 @@ const requiredPaths = [ ]; const forbiddenPrefixes = ["dist/Clawdbot.app/"]; +type PackageJson = { + name?: string; + version?: string; +}; + function runPackDry(): PackResult[] { const raw = execSync("npm pack --dry-run --json", { encoding: "utf8", @@ -21,7 +28,53 @@ function runPackDry(): PackResult[] { return JSON.parse(raw) as PackResult[]; } +function checkPluginVersions() { + const rootPackagePath = resolve("package.json"); + const rootPackage = JSON.parse(readFileSync(rootPackagePath, "utf8")) as PackageJson; + const targetVersion = rootPackage.version; + + if (!targetVersion) { + console.error("release-check: root package.json missing version."); + process.exit(1); + } + + const extensionsDir = resolve("extensions"); + const entries = readdirSync(extensionsDir, { withFileTypes: true }).filter((entry) => + entry.isDirectory(), + ); + + const mismatches: string[] = []; + + for (const entry of entries) { + const packagePath = join(extensionsDir, entry.name, "package.json"); + let pkg: PackageJson; + try { + pkg = JSON.parse(readFileSync(packagePath, "utf8")) as PackageJson; + } catch { + continue; + } + + if (!pkg.name || !pkg.version) { + continue; + } + + if (pkg.version !== targetVersion) { + mismatches.push(`${pkg.name} (${pkg.version})`); + } + } + + if (mismatches.length > 0) { + console.error(`release-check: plugin versions must match ${targetVersion}:`); + for (const item of mismatches) { + console.error(` - ${item}`); + } + process.exit(1); + } +} + function main() { + checkPluginVersions(); + const results = runPackDry(); const files = results.flatMap((entry) => entry.files ?? []); const paths = new Set(files.map((file) => file.path));