tuyoo-devflow 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +44 -0
- package/LICENSE +21 -0
- package/README.md +150 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +21 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/agent/doctor.d.ts +2 -0
- package/dist/commands/agent/doctor.js +70 -0
- package/dist/commands/agent/doctor.js.map +1 -0
- package/dist/commands/agent/index.d.ts +2 -0
- package/dist/commands/agent/index.js +8 -0
- package/dist/commands/agent/index.js.map +1 -0
- package/dist/commands/agent/install.d.ts +2 -0
- package/dist/commands/agent/install.js +300 -0
- package/dist/commands/agent/install.js.map +1 -0
- package/dist/commands/agent/shared.d.ts +11 -0
- package/dist/commands/agent/shared.js +33 -0
- package/dist/commands/agent/shared.js.map +1 -0
- package/dist/commands/agent/start.d.ts +3 -0
- package/dist/commands/agent/start.js +85 -0
- package/dist/commands/agent/start.js.map +1 -0
- package/dist/constants/versionPolicy.d.ts +12 -0
- package/dist/constants/versionPolicy.js +13 -0
- package/dist/constants/versionPolicy.js.map +1 -0
- package/dist/constants/whitelist.d.ts +3 -0
- package/dist/constants/whitelist.js +43 -0
- package/dist/constants/whitelist.js.map +1 -0
- package/dist/core/generator/linuxSystemd.d.ts +15 -0
- package/dist/core/generator/linuxSystemd.js +64 -0
- package/dist/core/generator/linuxSystemd.js.map +1 -0
- package/dist/core/generator/macLaunchd.d.ts +15 -0
- package/dist/core/generator/macLaunchd.js +104 -0
- package/dist/core/generator/macLaunchd.js.map +1 -0
- package/dist/core/generator/macScript.d.ts +2 -0
- package/dist/core/generator/macScript.js +20 -0
- package/dist/core/generator/macScript.js.map +1 -0
- package/dist/core/generator/winBat.d.ts +2 -0
- package/dist/core/generator/winBat.js +20 -0
- package/dist/core/generator/winBat.js.map +1 -0
- package/dist/core/jenkins/directLaunch.d.ts +2 -0
- package/dist/core/jenkins/directLaunch.js +22 -0
- package/dist/core/jenkins/directLaunch.js.map +1 -0
- package/dist/core/jenkins/downloadAgentJar.d.ts +1 -0
- package/dist/core/jenkins/downloadAgentJar.js +13 -0
- package/dist/core/jenkins/downloadAgentJar.js.map +1 -0
- package/dist/core/jenkins/launchArgs.d.ts +2 -0
- package/dist/core/jenkins/launchArgs.js +22 -0
- package/dist/core/jenkins/launchArgs.js.map +1 -0
- package/dist/core/jenkins/parseAgentCommand.d.ts +7 -0
- package/dist/core/jenkins/parseAgentCommand.js +108 -0
- package/dist/core/jenkins/parseAgentCommand.js.map +1 -0
- package/dist/core/log/redact.d.ts +2 -0
- package/dist/core/log/redact.js +26 -0
- package/dist/core/log/redact.js.map +1 -0
- package/dist/core/pipeline/setupPytuyooPipeline.d.ts +30 -0
- package/dist/core/pipeline/setupPytuyooPipeline.js +254 -0
- package/dist/core/pipeline/setupPytuyooPipeline.js.map +1 -0
- package/dist/core/platform.d.ts +5 -0
- package/dist/core/platform.js +27 -0
- package/dist/core/platform.js.map +1 -0
- package/dist/core/precheck/autoInstall.d.ts +9 -0
- package/dist/core/precheck/autoInstall.js +249 -0
- package/dist/core/precheck/autoInstall.js.map +1 -0
- package/dist/core/precheck/linuxGuard.d.ts +2 -0
- package/dist/core/precheck/linuxGuard.js +48 -0
- package/dist/core/precheck/linuxGuard.js.map +1 -0
- package/dist/core/precheck/network.d.ts +2 -0
- package/dist/core/precheck/network.js +42 -0
- package/dist/core/precheck/network.js.map +1 -0
- package/dist/core/precheck/systemInfo.d.ts +2 -0
- package/dist/core/precheck/systemInfo.js +37 -0
- package/dist/core/precheck/systemInfo.js.map +1 -0
- package/dist/core/precheck/tools.d.ts +12 -0
- package/dist/core/precheck/tools.js +135 -0
- package/dist/core/precheck/tools.js.map +1 -0
- package/dist/core/security/secretStore.d.ts +5 -0
- package/dist/core/security/secretStore.js +310 -0
- package/dist/core/security/secretStore.js.map +1 -0
- package/dist/core/shell/commandRunner.d.ts +17 -0
- package/dist/core/shell/commandRunner.js +94 -0
- package/dist/core/shell/commandRunner.js.map +1 -0
- package/dist/core/store/installCommandCache.d.ts +9 -0
- package/dist/core/store/installCommandCache.js +66 -0
- package/dist/core/store/installCommandCache.js.map +1 -0
- package/dist/core/store/profileStore.d.ts +4 -0
- package/dist/core/store/profileStore.js +43 -0
- package/dist/core/store/profileStore.js.map +1 -0
- package/dist/types.d.ts +41 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/CheckReport.d.ts +5 -0
- package/dist/ui/CheckReport.js +24 -0
- package/dist/ui/CheckReport.js.map +1 -0
- package/dist/ui/renderOnce.d.ts +2 -0
- package/dist/ui/renderOnce.js +9 -0
- package/dist/ui/renderOnce.js.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { checkbox, confirm, select } from "@inquirer/prompts";
|
|
2
|
+
import { safeErrorMessage } from "../log/redact.js";
|
|
3
|
+
import { runCommand } from "../shell/commandRunner.js";
|
|
4
|
+
import { TOOL_CHECK_NAMES } from "./tools.js";
|
|
5
|
+
function isLinuxRootUser() {
|
|
6
|
+
if (process.platform !== "linux") {
|
|
7
|
+
return false;
|
|
8
|
+
}
|
|
9
|
+
return typeof process.getuid === "function" && process.getuid() === 0;
|
|
10
|
+
}
|
|
11
|
+
function withLinuxSudo(command) {
|
|
12
|
+
if (process.platform !== "linux") {
|
|
13
|
+
return command;
|
|
14
|
+
}
|
|
15
|
+
return isLinuxRootUser() ? command : `sudo ${command}`;
|
|
16
|
+
}
|
|
17
|
+
async function ensureCommandAvailable(commandName) {
|
|
18
|
+
const check = await runCommand(`${commandName} --version`, { allowFailure: true });
|
|
19
|
+
if (check.code !== 0) {
|
|
20
|
+
throw new Error(`缺少命令 ${commandName},请先安装后重试。`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function detectArchForMinicondaLinux() {
|
|
24
|
+
return process.arch === "arm64" ? "aarch64" : "x86_64";
|
|
25
|
+
}
|
|
26
|
+
function detectArchForMinicondaMac() {
|
|
27
|
+
return process.arch === "arm64" ? "arm64" : "x86_64";
|
|
28
|
+
}
|
|
29
|
+
function minicondaCurlInstallCommand(platform) {
|
|
30
|
+
if (platform === "macos") {
|
|
31
|
+
const arch = detectArchForMinicondaMac();
|
|
32
|
+
const installer = `Miniconda3-latest-MacOSX-${arch}.sh`;
|
|
33
|
+
return [
|
|
34
|
+
`curl -fsSL "https://repo.anaconda.com/miniconda/${installer}" -o "$HOME/miniconda_installer.sh"`,
|
|
35
|
+
`bash "$HOME/miniconda_installer.sh" -b -u -p "$HOME/miniconda3"`,
|
|
36
|
+
`rm -f "$HOME/miniconda_installer.sh"`,
|
|
37
|
+
`"$HOME/miniconda3/bin/conda" init zsh`,
|
|
38
|
+
].join(" && ");
|
|
39
|
+
}
|
|
40
|
+
const arch = detectArchForMinicondaLinux();
|
|
41
|
+
const installer = `Miniconda3-latest-Linux-${arch}.sh`;
|
|
42
|
+
return [
|
|
43
|
+
`curl -fsSL "https://repo.anaconda.com/miniconda/${installer}" -o "/tmp/miniconda_installer.sh"`,
|
|
44
|
+
`bash "/tmp/miniconda_installer.sh" -b -u -p "$HOME/miniconda3"`,
|
|
45
|
+
`rm -f "/tmp/miniconda_installer.sh"`,
|
|
46
|
+
`"$HOME/miniconda3/bin/conda" init bash`,
|
|
47
|
+
].join(" && ");
|
|
48
|
+
}
|
|
49
|
+
async function chooseMinicondaMethod(platform) {
|
|
50
|
+
if (platform === "windows") {
|
|
51
|
+
return "curl";
|
|
52
|
+
}
|
|
53
|
+
if (platform === "linux") {
|
|
54
|
+
return "curl";
|
|
55
|
+
}
|
|
56
|
+
return await select({
|
|
57
|
+
message: "Miniconda 安装方式",
|
|
58
|
+
choices: [
|
|
59
|
+
{ name: "Homebrew(推荐)", value: "brew" },
|
|
60
|
+
{ name: "curl + bash", value: "curl" },
|
|
61
|
+
],
|
|
62
|
+
default: "brew",
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
async function buildInstallPlan(tool, platform) {
|
|
66
|
+
if (tool === "git") {
|
|
67
|
+
if (platform === "macos") {
|
|
68
|
+
await ensureCommandAvailable("brew");
|
|
69
|
+
return {
|
|
70
|
+
tool,
|
|
71
|
+
title: "Git(最新版本)",
|
|
72
|
+
command: "brew install git",
|
|
73
|
+
manualHint: "请手动执行: brew install git",
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
if (platform === "windows") {
|
|
77
|
+
await ensureCommandAvailable("winget");
|
|
78
|
+
return {
|
|
79
|
+
tool,
|
|
80
|
+
title: "Git(最新版本)",
|
|
81
|
+
command: "winget install --id Git.Git -e --accept-package-agreements --accept-source-agreements",
|
|
82
|
+
manualHint: "请手动执行: winget install --id Git.Git -e",
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
tool,
|
|
87
|
+
title: "Git(最新版本)",
|
|
88
|
+
command: withLinuxSudo("dnf install -y git"),
|
|
89
|
+
manualHint: "请手动执行: sudo dnf install -y git",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
if (tool === "java") {
|
|
93
|
+
if (platform === "macos") {
|
|
94
|
+
await ensureCommandAvailable("brew");
|
|
95
|
+
return {
|
|
96
|
+
tool,
|
|
97
|
+
title: "OpenJDK 21+",
|
|
98
|
+
command: "brew install openjdk@21 && sudo ln -sfn \"$(brew --prefix)/opt/openjdk@21/libexec/openjdk.jdk\" /Library/Java/JavaVirtualMachines/openjdk-21.jdk",
|
|
99
|
+
manualHint: "请手动执行: brew install openjdk@21(必要时配置 PATH 或创建系统链接)",
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (platform === "windows") {
|
|
103
|
+
await ensureCommandAvailable("winget");
|
|
104
|
+
return {
|
|
105
|
+
tool,
|
|
106
|
+
title: "OpenJDK 21+",
|
|
107
|
+
command: "winget install --id Microsoft.OpenJDK.21 -e --accept-package-agreements --accept-source-agreements",
|
|
108
|
+
manualHint: "请手动执行: winget install --id Microsoft.OpenJDK.21 -e",
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
tool,
|
|
113
|
+
title: "OpenJDK 21+",
|
|
114
|
+
command: withLinuxSudo("dnf install -y java-21-openjdk java-21-openjdk-devel"),
|
|
115
|
+
manualHint: "请手动执行: sudo dnf install -y java-21-openjdk java-21-openjdk-devel",
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
if (platform === "windows") {
|
|
119
|
+
await ensureCommandAvailable("winget");
|
|
120
|
+
return {
|
|
121
|
+
tool,
|
|
122
|
+
title: "Miniconda",
|
|
123
|
+
command: "winget install --id Anaconda.Miniconda3 -e --accept-package-agreements --accept-source-agreements",
|
|
124
|
+
manualHint: "请手动执行: winget install --id Anaconda.Miniconda3 -e",
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const method = await chooseMinicondaMethod(platform);
|
|
128
|
+
if (method === "brew") {
|
|
129
|
+
await ensureCommandAvailable("brew");
|
|
130
|
+
return {
|
|
131
|
+
tool,
|
|
132
|
+
title: "Miniconda",
|
|
133
|
+
command: "brew install --cask miniconda",
|
|
134
|
+
manualHint: "请手动执行: brew install --cask miniconda",
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
tool,
|
|
139
|
+
title: "Miniconda",
|
|
140
|
+
command: minicondaCurlInstallCommand(platform),
|
|
141
|
+
manualHint: "请手动下载 Miniconda 安装脚本并执行 bash 安装。",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
function toolDisplayName(tool) {
|
|
145
|
+
if (tool === "git") {
|
|
146
|
+
return "Git";
|
|
147
|
+
}
|
|
148
|
+
if (tool === "java") {
|
|
149
|
+
return "OpenJDK 21+";
|
|
150
|
+
}
|
|
151
|
+
return "Miniconda";
|
|
152
|
+
}
|
|
153
|
+
function mapFailedCheckToToolName(item) {
|
|
154
|
+
if (item.name === TOOL_CHECK_NAMES.git) {
|
|
155
|
+
return "git";
|
|
156
|
+
}
|
|
157
|
+
if (item.name === TOOL_CHECK_NAMES.java) {
|
|
158
|
+
return "java";
|
|
159
|
+
}
|
|
160
|
+
if (item.name === TOOL_CHECK_NAMES.miniconda) {
|
|
161
|
+
return "miniconda";
|
|
162
|
+
}
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
function unique(items) {
|
|
166
|
+
return [...new Set(items)];
|
|
167
|
+
}
|
|
168
|
+
export function getFailedToolKinds(toolChecks) {
|
|
169
|
+
const mapped = toolChecks
|
|
170
|
+
.filter((item) => item.status === "fail")
|
|
171
|
+
.map((item) => mapFailedCheckToToolName(item))
|
|
172
|
+
.filter((item) => item !== null);
|
|
173
|
+
return unique(mapped);
|
|
174
|
+
}
|
|
175
|
+
export async function guideAndInstallMissingTools(platform, failedToolChecks) {
|
|
176
|
+
const tools = getFailedToolKinds(failedToolChecks);
|
|
177
|
+
if (tools.length === 0) {
|
|
178
|
+
return {
|
|
179
|
+
detected: [],
|
|
180
|
+
selected: [],
|
|
181
|
+
installed: [],
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
const readable = tools.map((tool) => toolDisplayName(tool)).join("、");
|
|
185
|
+
const selected = await checkbox({
|
|
186
|
+
message: `检测到以下工具缺失或版本不符合要求:${readable}\n请选择要自动安装/修复的工具(空格选择,回车确认)`,
|
|
187
|
+
choices: tools.map((tool) => ({
|
|
188
|
+
name: toolDisplayName(tool),
|
|
189
|
+
value: tool,
|
|
190
|
+
checked: true,
|
|
191
|
+
})),
|
|
192
|
+
});
|
|
193
|
+
if (selected.length === 0) {
|
|
194
|
+
console.log("未选择任何工具,已跳过自动安装。");
|
|
195
|
+
return {
|
|
196
|
+
detected: tools,
|
|
197
|
+
selected: [],
|
|
198
|
+
installed: [],
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
const approved = await confirm({
|
|
202
|
+
message: `即将安装/修复:${selected.map((tool) => toolDisplayName(tool)).join("、")}。是否继续?`,
|
|
203
|
+
default: true,
|
|
204
|
+
});
|
|
205
|
+
if (!approved) {
|
|
206
|
+
console.log("已取消自动安装。");
|
|
207
|
+
return {
|
|
208
|
+
detected: tools,
|
|
209
|
+
selected,
|
|
210
|
+
installed: [],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
const installed = [];
|
|
214
|
+
for (const tool of selected) {
|
|
215
|
+
const plan = await buildInstallPlan(tool, platform);
|
|
216
|
+
console.log(`准备安装 ${plan.title}`);
|
|
217
|
+
console.log(`执行命令: ${plan.command}`);
|
|
218
|
+
console.log("安装过程日志如下(若长时间无输出会定期提示仍在执行):");
|
|
219
|
+
const runNow = await confirm({
|
|
220
|
+
message: `是否执行以上命令安装 ${plan.title}?`,
|
|
221
|
+
default: true,
|
|
222
|
+
});
|
|
223
|
+
if (!runNow) {
|
|
224
|
+
throw new Error(`已取消 ${plan.title} 自动安装。${plan.manualHint}`);
|
|
225
|
+
}
|
|
226
|
+
const startedAt = Date.now();
|
|
227
|
+
const result = await runCommand(plan.command, {
|
|
228
|
+
allowFailure: true,
|
|
229
|
+
streamOutput: true,
|
|
230
|
+
streamPrefix: `install:${plan.tool}`,
|
|
231
|
+
heartbeatIntervalMs: 15000,
|
|
232
|
+
heartbeatText: `${plan.title} 安装中,请稍候...`,
|
|
233
|
+
inheritStdin: true,
|
|
234
|
+
});
|
|
235
|
+
if (result.code !== 0) {
|
|
236
|
+
const detail = safeErrorMessage(result.stderr || result.stdout);
|
|
237
|
+
throw new Error(`${plan.title} 自动安装失败: ${detail}。${plan.manualHint}`);
|
|
238
|
+
}
|
|
239
|
+
const elapsedSec = Math.floor((Date.now() - startedAt) / 1000);
|
|
240
|
+
console.log(`${plan.title} 安装命令执行完成,耗时 ${elapsedSec}s。`);
|
|
241
|
+
installed.push(tool);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
detected: tools,
|
|
245
|
+
selected,
|
|
246
|
+
installed,
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
//# sourceMappingURL=autoInstall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autoInstall.js","sourceRoot":"","sources":["../../../src/core/precheck/autoInstall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { runCommand } from "../shell/commandRunner.js";
|
|
3
|
+
function parseOsRelease(content) {
|
|
4
|
+
const output = {};
|
|
5
|
+
for (const line of content.split("\n")) {
|
|
6
|
+
if (!line.includes("=")) {
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
const [key, rawValue] = line.split("=", 2);
|
|
10
|
+
output[key] = rawValue.replaceAll('"', "");
|
|
11
|
+
}
|
|
12
|
+
return output;
|
|
13
|
+
}
|
|
14
|
+
export async function checkLinuxGuards() {
|
|
15
|
+
if (process.platform !== "linux") {
|
|
16
|
+
return [];
|
|
17
|
+
}
|
|
18
|
+
const checks = [];
|
|
19
|
+
try {
|
|
20
|
+
const releaseRaw = await fs.readFile("/etc/os-release", "utf8");
|
|
21
|
+
const release = parseOsRelease(releaseRaw);
|
|
22
|
+
const isRocky9 = (release.ID ?? "").toLowerCase().includes("rocky") &&
|
|
23
|
+
(release.VERSION_ID ?? "").startsWith("9");
|
|
24
|
+
checks.push({
|
|
25
|
+
name: "Linux 发行版检查",
|
|
26
|
+
status: isRocky9 ? "pass" : "fail",
|
|
27
|
+
detail: release.PRETTY_NAME ?? "unknown",
|
|
28
|
+
hint: isRocky9 ? undefined : "当前仅支持 rocky9*,请更换系统后重试。",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
checks.push({
|
|
33
|
+
name: "Linux 发行版检查",
|
|
34
|
+
status: "fail",
|
|
35
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
36
|
+
hint: "无法读取 /etc/os-release。",
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const userCheck = await runCommand("id -u tywork", { allowFailure: true });
|
|
40
|
+
checks.push({
|
|
41
|
+
name: "tywork 用户检查",
|
|
42
|
+
status: userCheck.code === 0 ? "pass" : "fail",
|
|
43
|
+
detail: userCheck.code === 0 ? "存在 tywork 用户" : "不存在 tywork 用户",
|
|
44
|
+
hint: userCheck.code === 0 ? undefined : "请先创建 tywork 用户后再安装。",
|
|
45
|
+
});
|
|
46
|
+
return checks;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=linuxGuard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"linuxGuard.js","sourceRoot":"","sources":["../../../src/core/precheck/linuxGuard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAElC,OAAO,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAQvD,SAAS,cAAc,CAAC,OAAe;IACrC,MAAM,MAAM,GAAc,EAAE,CAAC;IAC7B,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QACD,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAsB,CAAC,GAAG,QAAQ,CAAC,UAAU,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAkB,EAAE,CAAC;IAEjC,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;QAC3C,MAAM,QAAQ,GACZ,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YAClD,CAAC,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAE7C,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;YAClC,MAAM,EAAE,OAAO,CAAC,WAAW,IAAI,SAAS;YACxC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,yBAAyB;SACvD,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,IAAI,CAAC;YACV,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;YAC9D,IAAI,EAAE,uBAAuB;SAC9B,CAAC,CAAC;IACL,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,UAAU,CAAC,cAAc,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3E,MAAM,CAAC,IAAI,CAAC;QACV,IAAI,EAAE,aAAa;QACnB,MAAM,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QAC9C,MAAM,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,eAAe;QAC/D,IAAI,EAAE,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,qBAAqB;KAC/D,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import net from "node:net";
|
|
2
|
+
import { getWhitelistTargets } from "../../constants/whitelist.js";
|
|
3
|
+
async function checkTcpTarget(target) {
|
|
4
|
+
return await new Promise((resolve) => {
|
|
5
|
+
const socket = new net.Socket();
|
|
6
|
+
const timeoutMs = target.timeoutMs ?? 4000;
|
|
7
|
+
let resolved = false;
|
|
8
|
+
const finish = (status, detail, hint) => {
|
|
9
|
+
if (resolved) {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
resolved = true;
|
|
13
|
+
socket.destroy();
|
|
14
|
+
resolve({
|
|
15
|
+
name: `网络连通: ${target.name}`,
|
|
16
|
+
status,
|
|
17
|
+
detail,
|
|
18
|
+
hint,
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
socket.setTimeout(timeoutMs);
|
|
22
|
+
socket.on("connect", () => {
|
|
23
|
+
finish("pass", `${target.host}:${target.port} 可访问`);
|
|
24
|
+
});
|
|
25
|
+
socket.on("timeout", () => {
|
|
26
|
+
finish("fail", `${target.host}:${target.port} 连接超时`, "请确认白名单和网络策略。");
|
|
27
|
+
});
|
|
28
|
+
socket.on("error", (error) => {
|
|
29
|
+
finish("fail", `${target.host}:${target.port} 连接失败 (${error.message})`, "请确认 DNS、防火墙、代理与白名单。");
|
|
30
|
+
});
|
|
31
|
+
socket.connect(target.port, target.host);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
export async function checkWhitelistConnectivity(jenkinsBaseUrl) {
|
|
35
|
+
const targets = getWhitelistTargets(jenkinsBaseUrl);
|
|
36
|
+
const results = [];
|
|
37
|
+
for (const target of targets) {
|
|
38
|
+
results.push(await checkTcpTarget(target));
|
|
39
|
+
}
|
|
40
|
+
return results;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=network.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/core/precheck/network.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAGnE,KAAK,UAAU,cAAc,CAAC,MAAqB;IACjD,OAAO,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QACnC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC;QAC3C,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,MAAM,MAAM,GAAG,CAAC,MAA6B,EAAE,MAAc,EAAE,IAAa,EAAE,EAAE;YAC9E,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO;YACT,CAAC;YACD,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,CAAC,OAAO,EAAE,CAAC;YACjB,OAAO,CAAC;gBACN,IAAI,EAAE,SAAS,MAAM,CAAC,IAAI,EAAE;gBAC5B,MAAM;gBACN,MAAM;gBACN,IAAI;aACL,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAE7B,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACxB,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,MAAM,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACxB,MAAM,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,OAAO,EAAE,cAAc,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC3B,MAAM,CACJ,MAAM,EACN,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,UAAU,KAAK,CAAC,OAAO,GAAG,EACvD,qBAAqB,CACtB,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,cAAsB;IACrE,MAAM,OAAO,GAAG,mBAAmB,CAAC,cAAc,CAAC,CAAC;IACpD,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
export function collectSystemInfoResults(platform, username) {
|
|
3
|
+
const shell = process.env.SHELL ?? process.env.ComSpec ?? "unknown";
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
name: "平台",
|
|
7
|
+
status: "pass",
|
|
8
|
+
detail: `${platform} (${process.platform})`,
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
name: "系统版本",
|
|
12
|
+
status: "pass",
|
|
13
|
+
detail: `${os.type()} ${os.release()}`,
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "CPU 架构",
|
|
17
|
+
status: "pass",
|
|
18
|
+
detail: process.arch,
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "当前用户",
|
|
22
|
+
status: "pass",
|
|
23
|
+
detail: username,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "Shell",
|
|
27
|
+
status: "pass",
|
|
28
|
+
detail: shell,
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "Node.js",
|
|
32
|
+
status: "pass",
|
|
33
|
+
detail: process.version,
|
|
34
|
+
},
|
|
35
|
+
];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=systemInfo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemInfo.js","sourceRoot":"","sources":["../../../src/core/precheck/systemInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAGzB,MAAM,UAAU,wBAAwB,CACtC,QAA2B,EAC3B,QAAgB;IAEhB,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC;IACpE,OAAO;QACL;YACE,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,GAAG,QAAQ,KAAK,OAAO,CAAC,QAAQ,GAAG;SAC5C;QACD;YACE,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,GAAG,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,EAAE;SACvC;QACD;YACE,IAAI,EAAE,QAAQ;YACd,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,OAAO,CAAC,IAAI;SACrB;QACD;YACE,IAAI,EAAE,MAAM;YACZ,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,QAAQ;SACjB;QACD;YACE,IAAI,EAAE,OAAO;YACb,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,KAAK;SACd;QACD;YACE,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,OAAO,CAAC,OAAO;SACxB;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { CheckResult, SupportedPlatform } from "../../types.js";
|
|
2
|
+
export declare const TOOL_CHECK_NAMES: {
|
|
3
|
+
readonly git: "Git 版本检查";
|
|
4
|
+
readonly java: "Java 版本检查";
|
|
5
|
+
readonly miniconda: "Miniconda 检查";
|
|
6
|
+
};
|
|
7
|
+
export interface JavaRuntimeInfo {
|
|
8
|
+
major: number | null;
|
|
9
|
+
isOpenJdk: boolean;
|
|
10
|
+
}
|
|
11
|
+
export declare function parseJavaRuntimeInfo(raw: string): JavaRuntimeInfo;
|
|
12
|
+
export declare function checkRequiredTools(platform: SupportedPlatform): Promise<CheckResult[]>;
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import semver from "semver";
|
|
2
|
+
import { VERSION_POLICY } from "../../constants/versionPolicy.js";
|
|
3
|
+
import { runCommand } from "../shell/commandRunner.js";
|
|
4
|
+
export const TOOL_CHECK_NAMES = {
|
|
5
|
+
git: "Git 版本检查",
|
|
6
|
+
java: "Java 版本检查",
|
|
7
|
+
miniconda: "Miniconda 检查",
|
|
8
|
+
};
|
|
9
|
+
function parseGitVersion(raw) {
|
|
10
|
+
const match = raw.match(/(\d+\.\d+\.\d+)/);
|
|
11
|
+
return match?.[1] ?? null;
|
|
12
|
+
}
|
|
13
|
+
function parseJavaMajor(versionText) {
|
|
14
|
+
const quoted = versionText.match(/"([^"]+)"/)?.[1];
|
|
15
|
+
if (!quoted) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (quoted.startsWith("1.")) {
|
|
19
|
+
const parts = quoted.split(".");
|
|
20
|
+
return Number(parts[1]);
|
|
21
|
+
}
|
|
22
|
+
return Number(quoted.split(".")[0]);
|
|
23
|
+
}
|
|
24
|
+
export function parseJavaRuntimeInfo(raw) {
|
|
25
|
+
const normalized = raw.toLowerCase();
|
|
26
|
+
const major = parseJavaMajor(raw);
|
|
27
|
+
const isOpenJdk = normalized.includes("openjdk");
|
|
28
|
+
return {
|
|
29
|
+
major,
|
|
30
|
+
isOpenJdk,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
function condaInstallHint(platform) {
|
|
34
|
+
if (platform === "macos") {
|
|
35
|
+
return "可自动安装(brew 或 curl bash),或手动执行: brew install --cask miniconda";
|
|
36
|
+
}
|
|
37
|
+
if (platform === "windows") {
|
|
38
|
+
return "可自动安装(winget),或手动安装 Miniconda 并确保 conda 在 PATH 中。";
|
|
39
|
+
}
|
|
40
|
+
return "可自动安装(curl bash),或手动安装 Miniconda3 并确保 conda 在 PATH 中。";
|
|
41
|
+
}
|
|
42
|
+
function gitInstallHint(platform) {
|
|
43
|
+
if (platform === "macos") {
|
|
44
|
+
return "可自动安装,或手动执行: brew install git";
|
|
45
|
+
}
|
|
46
|
+
if (platform === "windows") {
|
|
47
|
+
return "可自动安装,或手动执行: winget install --id Git.Git -e";
|
|
48
|
+
}
|
|
49
|
+
return "可自动安装,或手动执行: sudo dnf install -y git";
|
|
50
|
+
}
|
|
51
|
+
function javaInstallHint(platform) {
|
|
52
|
+
if (platform === "macos") {
|
|
53
|
+
return "可自动安装 OpenJDK,或手动执行: brew install openjdk@21";
|
|
54
|
+
}
|
|
55
|
+
if (platform === "windows") {
|
|
56
|
+
return "可自动安装 OpenJDK,或手动执行: winget install --id Microsoft.OpenJDK.21 -e";
|
|
57
|
+
}
|
|
58
|
+
return "可自动安装 OpenJDK,或手动执行: sudo dnf install -y java-21-openjdk java-21-openjdk-devel";
|
|
59
|
+
}
|
|
60
|
+
export async function checkRequiredTools(platform) {
|
|
61
|
+
const checks = [];
|
|
62
|
+
const gitResult = await runCommand("git --version", { allowFailure: true });
|
|
63
|
+
if (gitResult.code !== 0) {
|
|
64
|
+
checks.push({
|
|
65
|
+
name: TOOL_CHECK_NAMES.git,
|
|
66
|
+
status: "fail",
|
|
67
|
+
detail: "未检测到 Git",
|
|
68
|
+
hint: gitInstallHint(platform),
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
const version = parseGitVersion(gitResult.stdout);
|
|
73
|
+
const pass = Boolean(version && semver.gte(version, VERSION_POLICY.git.min));
|
|
74
|
+
checks.push({
|
|
75
|
+
name: TOOL_CHECK_NAMES.git,
|
|
76
|
+
status: pass ? "pass" : "fail",
|
|
77
|
+
detail: version ? `当前版本 ${version}` : "无法解析版本",
|
|
78
|
+
hint: pass ? undefined : `Git 版本需 >= ${VERSION_POLICY.git.min},${gitInstallHint(platform)}`,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
const javaResult = await runCommand("java -version", { allowFailure: true });
|
|
82
|
+
if (javaResult.code !== 0) {
|
|
83
|
+
checks.push({
|
|
84
|
+
name: TOOL_CHECK_NAMES.java,
|
|
85
|
+
status: "fail",
|
|
86
|
+
detail: "未检测到 Java",
|
|
87
|
+
hint: javaInstallHint(platform),
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
const javaOutput = javaResult.stderr || javaResult.stdout;
|
|
92
|
+
const runtimeInfo = parseJavaRuntimeInfo(javaOutput);
|
|
93
|
+
const pass = Boolean(runtimeInfo.major &&
|
|
94
|
+
runtimeInfo.major >= VERSION_POLICY.java.minMajor &&
|
|
95
|
+
runtimeInfo.isOpenJdk);
|
|
96
|
+
let detail = "无法解析版本";
|
|
97
|
+
if (runtimeInfo.major) {
|
|
98
|
+
detail = runtimeInfo.isOpenJdk
|
|
99
|
+
? `当前主版本 ${runtimeInfo.major}(OpenJDK)`
|
|
100
|
+
: `当前主版本 ${runtimeInfo.major}(非 OpenJDK)`;
|
|
101
|
+
}
|
|
102
|
+
let hint;
|
|
103
|
+
if (!pass) {
|
|
104
|
+
if (!runtimeInfo.major) {
|
|
105
|
+
hint = `无法识别 Java 版本信息,请安装 OpenJDK ${VERSION_POLICY.java.minMajor}+。${javaInstallHint(platform)}`;
|
|
106
|
+
}
|
|
107
|
+
else if (runtimeInfo.major < VERSION_POLICY.java.minMajor) {
|
|
108
|
+
hint = `Java 主版本需 >= ${VERSION_POLICY.java.minMajor},且必须为 OpenJDK。${javaInstallHint(platform)}`;
|
|
109
|
+
}
|
|
110
|
+
else if (!runtimeInfo.isOpenJdk) {
|
|
111
|
+
hint = `检测到非 OpenJDK 发行版,请切换为 OpenJDK ${VERSION_POLICY.java.minMajor}+。${javaInstallHint(platform)}`;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
hint = javaInstallHint(platform);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
checks.push({
|
|
118
|
+
name: TOOL_CHECK_NAMES.java,
|
|
119
|
+
status: pass ? "pass" : "fail",
|
|
120
|
+
detail,
|
|
121
|
+
hint,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
const condaResult = await runCommand("conda --version", { allowFailure: true });
|
|
125
|
+
checks.push({
|
|
126
|
+
name: TOOL_CHECK_NAMES.miniconda,
|
|
127
|
+
status: condaResult.code === 0 ? "pass" : "fail",
|
|
128
|
+
detail: condaResult.code === 0
|
|
129
|
+
? condaResult.stdout.trim() || condaResult.stderr.trim()
|
|
130
|
+
: "未检测到 conda",
|
|
131
|
+
hint: condaResult.code === 0 ? undefined : condaInstallHint(platform),
|
|
132
|
+
});
|
|
133
|
+
return checks;
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/core/precheck/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function ensureSecureStoreAvailable(): Promise<void>;
|
|
2
|
+
export declare function saveJenkinsSecret(profileId: string, secret: string): Promise<void>;
|
|
3
|
+
export declare function getJenkinsSecret(profileId: string): Promise<string>;
|
|
4
|
+
export declare function saveGitlabToken(token: string): Promise<void>;
|
|
5
|
+
export declare function getGitlabToken(): Promise<string | null>;
|