tuyoo-devflow 0.1.15 → 0.1.16
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
CHANGED
|
@@ -6,6 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.16] - 2026-04-22
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
|
|
13
|
+
- `agent doctor` / `agent install` 现在会先做工具检查,再做网络检查。
|
|
14
|
+
- GitLab 白名单检查新增 `git ls-remote` 仓库访问探测,用真实 Git 请求补足仅测 `443` 端口的盲区。
|
|
15
|
+
|
|
9
16
|
## [0.1.15] - 2026-04-22
|
|
10
17
|
|
|
11
18
|
### Fixed
|
|
@@ -7,8 +7,8 @@ import { CheckReport } from "../../ui/CheckReport.js";
|
|
|
7
7
|
import { renderOnce } from "../../ui/renderOnce.js";
|
|
8
8
|
export async function runDoctorChecks(platform, jenkinsBaseUrl, selectedNetworkTargets) {
|
|
9
9
|
const linuxResults = platform === "linux" ? await checkLinuxGuards() : [];
|
|
10
|
-
const networkResults = await checkWhitelistConnectivity(jenkinsBaseUrl, selectedNetworkTargets);
|
|
11
10
|
const toolResults = await checkRequiredTools(platform);
|
|
11
|
+
const networkResults = await checkWhitelistConnectivity(jenkinsBaseUrl, selectedNetworkTargets);
|
|
12
12
|
return {
|
|
13
13
|
linuxResults,
|
|
14
14
|
networkResults,
|
|
@@ -31,6 +31,7 @@ export async function printCheckSummary(checks) {
|
|
|
31
31
|
if (checks.linuxResults.length > 0) {
|
|
32
32
|
await renderOnce(_jsx(CheckReport, { title: "Linux \u524D\u7F6E\u68C0\u67E5", results: checks.linuxResults }));
|
|
33
33
|
}
|
|
34
|
+
await renderOnce(_jsx(CheckReport, { title: "\u5DE5\u5177\u4E0E\u7248\u672C\u68C0\u67E5", results: checks.toolResults }));
|
|
34
35
|
await renderOnce(_jsx(CheckReport, { title: "\u7F51\u7EDC\u767D\u540D\u5355\u68C0\u67E5", results: checks.networkResults.length > 0
|
|
35
36
|
? checks.networkResults
|
|
36
37
|
: [
|
|
@@ -40,7 +41,6 @@ export async function printCheckSummary(checks) {
|
|
|
40
41
|
detail: "未选择任何网络白名单检查项,本次已跳过。",
|
|
41
42
|
},
|
|
42
43
|
] }));
|
|
43
|
-
await renderOnce(_jsx(CheckReport, { title: "\u5DE5\u5177\u4E0E\u7248\u672C\u68C0\u67E5", results: checks.toolResults }));
|
|
44
44
|
}
|
|
45
45
|
export async function printFailedWhitelistReport(checks) {
|
|
46
46
|
const failedNetworkChecks = getFailedNetworkChecks(checks);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/agent/shared.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EACL,4BAA4B,EAC5B,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAQpD,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAA2B,EAC3B,cAAsB,EACtB,sBAA2C;IAE3C,MAAM,YAAY,GAAG,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC1E,MAAM,
|
|
1
|
+
{"version":3,"file":"shared.js","sourceRoot":"","sources":["../../../src/commands/agent/shared.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import { NetworkCheckResult, NetworkTargetKey } from "../../types.js";
|
|
2
|
+
export declare function isGitLabRepositoryReachableFromProbe(output: string): boolean;
|
|
2
3
|
export declare function checkWhitelistConnectivity(jenkinsBaseUrl: string, selectedTargetKeys?: NetworkTargetKey[]): Promise<NetworkCheckResult[]>;
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import dns from "node:dns/promises";
|
|
2
2
|
import net from "node:net";
|
|
3
3
|
import { getWhitelistTargets } from "../../constants/whitelist.js";
|
|
4
|
+
import { runCommand } from "../shell/commandRunner.js";
|
|
5
|
+
const GITLAB_REPOSITORY_PROBE_PATH = "liutongqing/pytuyoo-pipeline.git";
|
|
6
|
+
const GITLAB_REACHABLE_PATTERNS = [
|
|
7
|
+
"could not read username for",
|
|
8
|
+
"authentication failed",
|
|
9
|
+
"http basic: access denied",
|
|
10
|
+
"repository not found",
|
|
11
|
+
"the requested url returned error: 401",
|
|
12
|
+
"the requested url returned error: 403",
|
|
13
|
+
"the requested url returned error: 404",
|
|
14
|
+
"access denied",
|
|
15
|
+
];
|
|
16
|
+
function buildGitLabRepositoryProbeUrl(host) {
|
|
17
|
+
return `https://${host}/${GITLAB_REPOSITORY_PROBE_PATH}`;
|
|
18
|
+
}
|
|
19
|
+
export function isGitLabRepositoryReachableFromProbe(output) {
|
|
20
|
+
const normalized = output.trim().toLowerCase();
|
|
21
|
+
if (!normalized) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
return GITLAB_REACHABLE_PATTERNS.some((pattern) => normalized.includes(pattern));
|
|
25
|
+
}
|
|
4
26
|
async function resolveTargetAddresses(host) {
|
|
5
27
|
if (net.isIP(host)) {
|
|
6
28
|
return [host];
|
|
@@ -48,11 +70,61 @@ async function checkTcpTarget(target) {
|
|
|
48
70
|
socket.connect(target.port, target.host);
|
|
49
71
|
});
|
|
50
72
|
}
|
|
73
|
+
async function checkGitLabRepositoryAccess(target) {
|
|
74
|
+
const resolvedAddresses = await resolveTargetAddresses(target.host);
|
|
75
|
+
const gitCheck = await runCommand("command -v git", { allowFailure: true });
|
|
76
|
+
if (gitCheck.code !== 0) {
|
|
77
|
+
return {
|
|
78
|
+
name: "网络连通: GitLab 仓库访问",
|
|
79
|
+
status: "warn",
|
|
80
|
+
detail: "未检测到 git,已跳过 GitLab 仓库访问探测。",
|
|
81
|
+
hint: "请先修复 Git 工具检查,再重新执行 doctor/install。",
|
|
82
|
+
target,
|
|
83
|
+
resolvedAddresses,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const probeUrl = buildGitLabRepositoryProbeUrl(target.host);
|
|
87
|
+
const result = await runCommand(`GIT_TERMINAL_PROMPT=0 git ls-remote --heads "${probeUrl}"`, {
|
|
88
|
+
allowFailure: true,
|
|
89
|
+
});
|
|
90
|
+
const output = `${result.stderr}\n${result.stdout}`.trim();
|
|
91
|
+
if (result.code === 0) {
|
|
92
|
+
return {
|
|
93
|
+
name: "网络连通: GitLab 仓库访问",
|
|
94
|
+
status: "pass",
|
|
95
|
+
detail: `${probeUrl} 可通过 git 访问`,
|
|
96
|
+
target,
|
|
97
|
+
resolvedAddresses,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
if (isGitLabRepositoryReachableFromProbe(output)) {
|
|
101
|
+
return {
|
|
102
|
+
name: "网络连通: GitLab 仓库访问",
|
|
103
|
+
status: "pass",
|
|
104
|
+
detail: "GitLab 仓库访问探测已到达服务端(当前仓库可能需要认证或额外权限)。",
|
|
105
|
+
hint: "已验证到达 GitLab 服务端;如后续 clone 失败,请检查用户名、Token 与仓库权限。",
|
|
106
|
+
target,
|
|
107
|
+
resolvedAddresses,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
const detail = output.split("\n").map((line) => line.trim()).find(Boolean) ?? `${probeUrl} git 访问失败`;
|
|
111
|
+
return {
|
|
112
|
+
name: "网络连通: GitLab 仓库访问",
|
|
113
|
+
status: "fail",
|
|
114
|
+
detail,
|
|
115
|
+
hint: "仅 443 端口可达不足以保证 git clone 正常;请确认 GitLab 白名单、代理与出口策略。",
|
|
116
|
+
target,
|
|
117
|
+
resolvedAddresses,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
51
120
|
export async function checkWhitelistConnectivity(jenkinsBaseUrl, selectedTargetKeys) {
|
|
52
121
|
const targets = getWhitelistTargets(jenkinsBaseUrl, selectedTargetKeys);
|
|
53
122
|
const results = [];
|
|
54
123
|
for (const target of targets) {
|
|
55
124
|
results.push(await checkTcpTarget(target));
|
|
125
|
+
if (target.key === "gitlab") {
|
|
126
|
+
results.push(await checkGitLabRepositoryAccess(target));
|
|
127
|
+
}
|
|
56
128
|
}
|
|
57
129
|
return results;
|
|
58
130
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/core/precheck/network.ts"],"names":[],"mappings":"AAAA,OAAO,GAAG,MAAM,mBAAmB,CAAC;AACpC,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"network.js","sourceRoot":"","sources":["../../../src/core/precheck/network.ts"],"names":[],"mappings":"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"}
|