mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-08 06:54:24 +00:00
* CI: add windows scope output for changed-scope * Test: cover windows scope gating in changed-scope * CI: gate checks-windows by windows scope * Docs: update CI windows scope and runner label * CI: move checks-windows to 32 vCPU runner * Docs: align CI windows runner with workflow
142 lines
4.2 KiB
JavaScript
142 lines
4.2 KiB
JavaScript
import { execSync } from "node:child_process";
|
|
import { appendFileSync } from "node:fs";
|
|
|
|
/** @typedef {{ runNode: boolean; runMacos: boolean; runAndroid: boolean; runWindows: boolean }} ChangedScope */
|
|
|
|
const DOCS_PATH_RE = /^(docs\/|.*\.mdx?$)/;
|
|
const MACOS_PROTOCOL_GEN_RE =
|
|
/^(apps\/macos\/Sources\/OpenClawProtocol\/|apps\/shared\/OpenClawKit\/Sources\/OpenClawProtocol\/)/;
|
|
const MACOS_NATIVE_RE = /^(apps\/macos\/|apps\/ios\/|apps\/shared\/|Swabble\/)/;
|
|
const ANDROID_NATIVE_RE = /^(apps\/android\/|apps\/shared\/)/;
|
|
const NODE_SCOPE_RE =
|
|
/^(src\/|test\/|extensions\/|packages\/|scripts\/|ui\/|\.github\/|openclaw\.mjs$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|tsconfig.*\.json$|vitest.*\.ts$|tsdown\.config\.ts$|\.oxlintrc\.json$|\.oxfmtrc\.jsonc$)/;
|
|
const WINDOWS_SCOPE_RE =
|
|
/^(src\/|test\/|extensions\/|packages\/|scripts\/|ui\/|openclaw\.mjs$|package\.json$|pnpm-lock\.yaml$|pnpm-workspace\.yaml$|tsconfig.*\.json$|vitest.*\.ts$|tsdown\.config\.ts$|\.github\/workflows\/ci\.yml$|\.github\/actions\/setup-node-env\/action\.yml$|\.github\/actions\/setup-pnpm-store-cache\/action\.yml$)/;
|
|
const NATIVE_ONLY_RE =
|
|
/^(apps\/android\/|apps\/ios\/|apps\/macos\/|apps\/shared\/|Swabble\/|appcast\.xml$)/;
|
|
|
|
/**
|
|
* @param {string[]} changedPaths
|
|
* @returns {ChangedScope}
|
|
*/
|
|
export function detectChangedScope(changedPaths) {
|
|
if (!Array.isArray(changedPaths) || changedPaths.length === 0) {
|
|
return { runNode: true, runMacos: true, runAndroid: true, runWindows: true };
|
|
}
|
|
|
|
let runNode = false;
|
|
let runMacos = false;
|
|
let runAndroid = false;
|
|
let runWindows = false;
|
|
let hasNonDocs = false;
|
|
let hasNonNativeNonDocs = false;
|
|
|
|
for (const rawPath of changedPaths) {
|
|
const path = String(rawPath).trim();
|
|
if (!path) {
|
|
continue;
|
|
}
|
|
|
|
if (DOCS_PATH_RE.test(path)) {
|
|
continue;
|
|
}
|
|
|
|
hasNonDocs = true;
|
|
|
|
if (!MACOS_PROTOCOL_GEN_RE.test(path) && MACOS_NATIVE_RE.test(path)) {
|
|
runMacos = true;
|
|
}
|
|
|
|
if (ANDROID_NATIVE_RE.test(path)) {
|
|
runAndroid = true;
|
|
}
|
|
|
|
if (NODE_SCOPE_RE.test(path)) {
|
|
runNode = true;
|
|
}
|
|
|
|
if (WINDOWS_SCOPE_RE.test(path)) {
|
|
runWindows = true;
|
|
}
|
|
|
|
if (!NATIVE_ONLY_RE.test(path)) {
|
|
hasNonNativeNonDocs = true;
|
|
}
|
|
}
|
|
|
|
if (!runNode && hasNonDocs && hasNonNativeNonDocs) {
|
|
runNode = true;
|
|
}
|
|
|
|
return { runNode, runMacos, runAndroid, runWindows };
|
|
}
|
|
|
|
/**
|
|
* @param {string} base
|
|
* @param {string} [head]
|
|
* @returns {string[]}
|
|
*/
|
|
export function listChangedPaths(base, head = "HEAD") {
|
|
if (!base) {
|
|
return [];
|
|
}
|
|
const output = execSync(`git diff --name-only ${base} ${head}`, {
|
|
stdio: ["ignore", "pipe", "pipe"],
|
|
encoding: "utf8",
|
|
});
|
|
return output
|
|
.split("\n")
|
|
.map((line) => line.trim())
|
|
.filter((line) => line.length > 0);
|
|
}
|
|
|
|
/**
|
|
* @param {ChangedScope} scope
|
|
* @param {string} [outputPath]
|
|
*/
|
|
export function writeGitHubOutput(scope, outputPath = process.env.GITHUB_OUTPUT) {
|
|
if (!outputPath) {
|
|
throw new Error("GITHUB_OUTPUT is required");
|
|
}
|
|
appendFileSync(outputPath, `run_node=${scope.runNode}\n`, "utf8");
|
|
appendFileSync(outputPath, `run_macos=${scope.runMacos}\n`, "utf8");
|
|
appendFileSync(outputPath, `run_android=${scope.runAndroid}\n`, "utf8");
|
|
appendFileSync(outputPath, `run_windows=${scope.runWindows}\n`, "utf8");
|
|
}
|
|
|
|
function isDirectRun() {
|
|
const direct = process.argv[1];
|
|
return Boolean(direct && import.meta.url.endsWith(direct));
|
|
}
|
|
|
|
/** @param {string[]} argv */
|
|
function parseArgs(argv) {
|
|
const args = { base: "", head: "HEAD" };
|
|
for (let i = 0; i < argv.length; i += 1) {
|
|
if (argv[i] === "--base") {
|
|
args.base = argv[i + 1] ?? "";
|
|
i += 1;
|
|
continue;
|
|
}
|
|
if (argv[i] === "--head") {
|
|
args.head = argv[i + 1] ?? "HEAD";
|
|
i += 1;
|
|
}
|
|
}
|
|
return args;
|
|
}
|
|
|
|
if (isDirectRun()) {
|
|
const args = parseArgs(process.argv.slice(2));
|
|
try {
|
|
const changedPaths = listChangedPaths(args.base, args.head);
|
|
if (changedPaths.length === 0) {
|
|
writeGitHubOutput({ runNode: true, runMacos: true, runAndroid: true, runWindows: true });
|
|
process.exit(0);
|
|
}
|
|
writeGitHubOutput(detectChangedScope(changedPaths));
|
|
} catch {
|
|
writeGitHubOutput({ runNode: true, runMacos: true, runAndroid: true, runWindows: true });
|
|
}
|
|
}
|