diff --git a/scripts/check-engine-version.mjs b/scripts/check-engine-version.mjs index cc3edd5f..da95f246 100644 --- a/scripts/check-engine-version.mjs +++ b/scripts/check-engine-version.mjs @@ -29,6 +29,23 @@ function isNotFoundError(error) { const rootDir = dirname(dirname(fileURLToPath(import.meta.url))); +const ENGINE_MANIFEST = "packages/cli-engine/package.json"; + +/** + * Whether a manifest change alters what npm publishes. devDependencies + * never ship in the tarball — the release version sweep rewrites the + * engine's `@repo/*` devDependencies on every bump, and that must not + * read as "the engine changed". + * + * @param {Record} base + * @param {Record} head + * @returns {boolean} + */ +export function manifestChangeShips(base, head) { + const shipped = ({ devDependencies: _dev, ...rest }) => rest; + return JSON.stringify(shipped(base)) !== JSON.stringify(shipped(head)); +} + /** * @param {{ changedFiles: readonly string[], engineVersion: string, versionOnRegistry: boolean }} input * @returns {string | null} the failure message, or null when the change is fine @@ -66,7 +83,21 @@ async function main() { ["diff", "--name-only", mergeBase.trim(), "HEAD"], { cwd: rootDir }, ); - const changedFiles = diff.split("\n").filter(Boolean); + let changedFiles = diff.split("\n").filter(Boolean); + + if (changedFiles.includes(ENGINE_MANIFEST)) { + const { stdout: baseManifest } = await execFileAsync( + "git", + ["show", `${mergeBase.trim()}:${ENGINE_MANIFEST}`], + { cwd: rootDir }, + ); + const headManifest = readFileSync(join(rootDir, ENGINE_MANIFEST), "utf-8"); + if ( + !manifestChangeShips(JSON.parse(baseManifest), JSON.parse(headManifest)) + ) { + changedFiles = changedFiles.filter((file) => file !== ENGINE_MANIFEST); + } + } const manifest = JSON.parse( readFileSync(join(rootDir, "packages/cli-engine/package.json"), "utf-8"), diff --git a/scripts/check-engine-version.test.mjs b/scripts/check-engine-version.test.mjs index 25b869fb..1237366b 100644 --- a/scripts/check-engine-version.test.mjs +++ b/scripts/check-engine-version.test.mjs @@ -1,6 +1,9 @@ import assert from "node:assert/strict"; import { describe, it } from "node:test"; -import { engineBumpVerdict } from "./check-engine-version.mjs"; +import { + engineBumpVerdict, + manifestChangeShips, +} from "./check-engine-version.mjs"; const NAMES_THE_STALE_VERSION = /0\.1\.1/; const NAMES_THE_BUMP_COMMAND = /bump-cli-engine-version/; @@ -46,3 +49,39 @@ describe("engineBumpVerdict", () => { assert.equal(verdict, null); }); }); + +describe("manifestChangeShips", () => { + const base = { + name: "@prisma/cli-engine", + version: "0.2.0", + dependencies: { colorette: "^2.0.20" }, + devDependencies: { "@repo/tsconfig": "workspace:8.0.0-rc.4" }, + }; + + it("a devDependencies-only change does not ship", () => { + const head = { + ...base, + devDependencies: { "@repo/tsconfig": "workspace:8.0.0-rc.5" }, + }; + assert.equal(manifestChangeShips(base, head), false); + }); + + it("a version change ships", () => { + assert.equal( + manifestChangeShips(base, { ...base, version: "0.2.1" }), + true, + ); + }); + + it("a dependencies change ships", () => { + const head = { ...base, dependencies: { colorette: "^2.1.0" } }; + assert.equal(manifestChangeShips(base, head), true); + }); + + it("an added field ships", () => { + assert.equal( + manifestChangeShips(base, { ...base, sideEffects: false }), + true, + ); + }); +});