chore: import upstream snapshot with attribution
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
import { readdirSync, readFileSync } from "node:fs";
|
||||
import { resolve } from "node:path";
|
||||
import parseChangeset from "@changesets/parse";
|
||||
|
||||
if (require.main === module) {
|
||||
const packages = findPackages();
|
||||
const changesets = readChangesets(resolve(__dirname, "../../.changeset"));
|
||||
const errors = validateChangesets(packages, changesets);
|
||||
if (errors.length > 0) {
|
||||
console.error("Validation errors in changesets:");
|
||||
for (const error of errors) {
|
||||
console.error("- ", error);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
export function validateChangesets(
|
||||
packages: Map<string, PackageJSON>,
|
||||
changesets: ChangesetFile[]
|
||||
) {
|
||||
const errors: string[] = [];
|
||||
changesets.map(({ file, contents }) => {
|
||||
try {
|
||||
const changeset = parseChangeset(contents);
|
||||
for (const release of changeset.releases) {
|
||||
const targetPackage = packages.get(release.name);
|
||||
if (!targetPackage) {
|
||||
errors.push(
|
||||
`Unknown package name "${release.name}" in changeset at "${file}".`
|
||||
);
|
||||
}
|
||||
|
||||
if (release.type === "major" && targetPackage?.private !== true) {
|
||||
errors.push(
|
||||
`Major version bumps are not allowed for package "${release.name}" in changeset at "${file}".`
|
||||
);
|
||||
}
|
||||
if (!["major", "minor", "patch", "none"].includes(release.type)) {
|
||||
errors.push(
|
||||
`Invalid type "${release.type}" for package "${release.name}" in changeset at "${file}".`
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
errors.push(e.toString() + `at file "${file}"`);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
});
|
||||
return errors;
|
||||
}
|
||||
|
||||
export function readChangesets(changesetDir: string): ChangesetFile[] {
|
||||
return readdirSync(changesetDir)
|
||||
.filter(
|
||||
(file) =>
|
||||
!file.startsWith(".") && file.endsWith(".md") && file !== "README.md"
|
||||
)
|
||||
.map((file) => ({
|
||||
file,
|
||||
contents: readFileSync(resolve(changesetDir, file), "utf-8"),
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for all the packages (under the top-level "packages" directory of the monorepo) that can have changesets.
|
||||
*
|
||||
* This is determined by the package containing a package.json that is public or
|
||||
* is marked as `"private": true` and has a `deploy` script.
|
||||
*/
|
||||
export function findPackages(): Map<string, PackageJSON> {
|
||||
const packagesDirectory = resolve(__dirname, "../../packages");
|
||||
const allPackageDirectories = readdirSync(packagesDirectory).map((p) =>
|
||||
resolve(packagesDirectory, p)
|
||||
);
|
||||
const allPackages: PackageJSON[] = [];
|
||||
for (const dir of allPackageDirectories) {
|
||||
try {
|
||||
allPackages.push(
|
||||
JSON.parse(readFileSync(resolve(dir, "package.json"), "utf-8"))
|
||||
);
|
||||
} catch {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
const deployablePackages = new Map<string, PackageJSON>();
|
||||
for (const pkg of allPackages) {
|
||||
if (!pkg.private || pkg.scripts?.deploy !== undefined) {
|
||||
deployablePackages.set(pkg.name, pkg);
|
||||
}
|
||||
}
|
||||
return deployablePackages;
|
||||
}
|
||||
|
||||
export type ChangesetFile = {
|
||||
file: string;
|
||||
contents: string;
|
||||
};
|
||||
|
||||
export type PackageJSON = {
|
||||
name: string;
|
||||
private?: boolean;
|
||||
scripts?: Record<string, unknown>;
|
||||
"workers-sdk"?: {
|
||||
deploy?: boolean;
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user