返回 DeepSeek-Reasonix
check-single-release-public-contract.mjs
根目录 / scripts / check-single-release-public-contract.mjs
1 #!/usr/bin/env node
2
3 import { readFileSync } from "node:fs";
4 import { execFileSync } from "node:child_process";
5
6 const files = execFileSync("git", ["ls-files", "README.md", "docs/*.md", "site/src/pages/*", "site/src/pages/**/*"], {
7 encoding: "utf8",
8 }).trim().split("\n").filter(Boolean);
9 const migrationReferences = new Set([
10 "docs/RELEASING.md",
11 "docs/SIGNPATH_WINDOWS_ADMIN_SOP.md",
12 "docs/CLI.md",
13 "docs/CLI.zh-CN.md",
14 ]);
15 const rules = [
16 [/release-channel-switch/, "public release channel selector"],
17 [/reasonix upgrade (?:preview|stable)\b/i, "deprecated channel install command"],
18 [/[?&]channel=(?:preview|canary)\b/i, "public channel deep link"],
19 [/npm (?:i|install).*(?:@canary|@next)\b/i, "public prerelease npm install"],
20 [/\bStable 1\.x\b|· stable\b|current 1\.x stable\b/i, "public Stable channel label"],
21 ];
22 const failures = [];
23 for (const file of files) {
24 if (migrationReferences.has(file) || file.includes("/changelog/")) continue;
25 const source = readFileSync(file, "utf8");
26 for (const [pattern, description] of rules) {
27 if (pattern.test(source)) failures.push(`${file}: ${description}`);
28 }
29 }
30 if (failures.length) {
31 console.error(`single-release public contract failed:\n${failures.join("\n")}`);
32 process.exit(1);
33 }
34 console.log(`single-release public contract OK (${files.length} files checked)`);
35
35 lines Plain Text