Files
babel/scripts/ensure-yarn-version-integrity.ts
Huáng JùnliàngandGitHub b7c98eb305 ci: enforce yarn integrity (#18018)
* ci: enforce yarn integrity

* ci: enforce integrity when yarn binary is changed

* fix invalid git usage

* add a new yarn integrity workflow

The checkout is always shallow so it is impossible to compare with base ref.

* ci: run integrity check when package.json changes

* chore: rename workflow

* Address review comments
2026-06-15 15:51:53 -04:00

53 lines
1.7 KiB
TypeScript

import { createHash } from "node:crypto";
import fs from "node:fs";
import cp from "node:child_process";
function readPackageManagerSpec() {
const packageJson = JSON.parse(fs.readFileSync("./package.json", "utf-8"));
if (!packageJson.packageManager) {
throw new Error("packageManager field is missing in package.json");
}
return packageJson.packageManager;
}
const packageManagerSpecRegex = /^yarn@(\d+\.\d+\.\d+)\+sha512\.([a-f0-9]+)$/;
const yarnPathRegex = /^yarnPath:\s*(\S+)/m;
const match = packageManagerSpecRegex.exec(readPackageManagerSpec());
if (!match) {
throw new Error(
"Invalid packageManager format in package.json, expected 'yarn@<version>+sha512.<hash>'. Use 'corepack use yarn@<version>' to get the correct hash."
);
}
const [, yarnVersion] = match;
cp.execSync(`corepack use yarn@${yarnVersion}`);
// Read the package manager spec again to get the expected hash, since corepack might have updated it
const updatedPackageManagerSpec = readPackageManagerSpec();
const match2 = packageManagerSpecRegex.exec(updatedPackageManagerSpec);
if (!match2) {
throw new Error(
`Invalid packageManager format in package.json after corepack update, expected 'yarn@<version>+sha512.<hash>', got '${updatedPackageManagerSpec}'.`
);
}
const [, , expectedHash] = match2;
const yarnPath = yarnPathRegex.exec(
fs.readFileSync(".yarnrc.yml", "utf-8")
)?.[1];
if (!yarnPath) {
throw new Error("yarnPath is missing in .yarnrc.yml");
}
const actualHash = createHash("sha512")
.update(fs.readFileSync(yarnPath))
.digest("hex");
if (actualHash !== expectedHash) {
throw new Error(
`Yarn version integrity check failed. Expected hash: ${expectedHash}, Actual hash: ${actualHash}`
);
}