

























@@ -3,10 +3,12 @@
33// Uses installed tools when present, otherwise falls back to pinned hooks where
44// possible, then runs repo-specific workflow guards.
55import { spawnSync } from "node:child_process";
6-import { readdirSync } from "node:fs";
6+import { mkdtempSync, readdirSync, rmSync } from "node:fs";
7+import { tmpdir } from "node:os";
78import { join } from "node:path";
89910const ACTIONLINT_VERSION = "1.7.11";
11+const PRE_COMMIT_VERSION = "4.2.0";
1012const WORKFLOW_DIR = ".github/workflows";
11131214function commandExists(command, args = ["--version"]) {
@@ -25,6 +27,59 @@ function run(command, args) {
2527}
2628}
272930+function runChecked(command, args) {
31+const result = spawnSync(command, args, { stdio: "inherit" });
32+if (result.error) {
33+return {
34+message: `[check-workflows] failed to run ${command}: ${result.error.message}`,
35+status: 1,
36+};
37+}
38+if (result.status !== 0) {
39+return {
40+message: null,
41+status: result.status ?? 1,
42+};
43+}
44+return null;
45+}
46+47+function runPreCommitFromTempVenv(hook, hookArgs) {
48+if (!commandExists("python3", ["--version"])) {
49+return false;
50+}
51+const venvDir = mkdtempSync(join(tmpdir(), "openclaw-check-workflows-pre-commit-"));
52+const python = join(venvDir, process.platform === "win32" ? "Scripts/python.exe" : "bin/python");
53+let failure;
54+try {
55+failure = runChecked("python3", ["-m", "venv", venvDir]);
56+if (!failure) {
57+failure = runChecked(python, [
58+"-m",
59+"pip",
60+"install",
61+"--disable-pip-version-check",
62+`pre-commit==${PRE_COMMIT_VERSION}`,
63+]);
64+}
65+if (!failure) {
66+failure = runChecked(python, ["-m", "pre_commit", ...hookArgs]);
67+}
68+if (failure) {
69+return false;
70+}
71+return true;
72+} finally {
73+rmSync(venvDir, { force: true, recursive: true });
74+if (failure) {
75+if (failure.message) {
76+console.error(failure.message);
77+}
78+process.exit(failure.status);
79+}
80+}
81+}
82+2883function workflowFiles() {
2984return readdirSync(WORKFLOW_DIR)
3085.filter((file) => file.endsWith(".yml") || file.endsWith(".yaml"))
@@ -42,9 +97,12 @@ function runPreCommitHook(hook, files) {
4297run("python3", ["-m", "pre_commit", ...hookArgs]);
4398return;
4499}
100+if (runPreCommitFromTempVenv(hook, hookArgs)) {
101+return;
102+}
4510346104console.error(
47-`[check-workflows] missing pre-commit runtime for ${hook}: install pre-commit or python3 pre_commit.`,
105+`[check-workflows] missing pre-commit runtime for ${hook}: install pre-commit or Python venv support for pre-commit ${PRE_COMMIT_VERSION}.`,
48106);
49107process.exit(1);
50108}
@@ -57,7 +115,8 @@ if (commandExists("actionlint")) {
57115run("go", ["run", `github.com/rhysd/actionlint/cmd/actionlint@v${ACTIONLINT_VERSION}`]);
58116} else if (
59117commandExists("pre-commit") ||
60-commandExists("python3", ["-m", "pre_commit", "--version"])
118+commandExists("python3", ["-m", "pre_commit", "--version"]) ||
119+commandExists("python3", ["--version"])
61120) {
62121runPreCommitHook("actionlint", workflows);
63122} else {
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。