ai-project-manage-cli 6.0.106 → 6.0.108-beta.1
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/dist/index.js +979 -888
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -110,8 +110,8 @@ function toFsPath(inputPath) {
|
|
|
110
110
|
}
|
|
111
111
|
return `\\\\?\\${normalized}`;
|
|
112
112
|
}
|
|
113
|
-
function normalizeWorkdirPath(
|
|
114
|
-
let normalized =
|
|
113
|
+
function normalizeWorkdirPath(path19) {
|
|
114
|
+
let normalized = path19.trim().replace(/\\/g, "/").normalize("NFC");
|
|
115
115
|
if (normalized.startsWith("//?/")) {
|
|
116
116
|
normalized = normalized.slice(4);
|
|
117
117
|
}
|
|
@@ -326,9 +326,9 @@ function assertTemplateCopiedToApm(apmDir, workdir) {
|
|
|
326
326
|
"sessions"
|
|
327
327
|
];
|
|
328
328
|
for (const item of required) {
|
|
329
|
-
const
|
|
330
|
-
if (!existsSync(toFsPath(
|
|
331
|
-
throw new Error(`[apm] \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${
|
|
329
|
+
const path19 = join2(apmDir, item);
|
|
330
|
+
if (!existsSync(toFsPath(path19))) {
|
|
331
|
+
throw new Error(`[apm] \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path19}`);
|
|
332
332
|
}
|
|
333
333
|
}
|
|
334
334
|
const leakedRules = join2(workdir, "rules");
|
|
@@ -790,14 +790,14 @@ function projectDocumentLocalPath(apmRoot, documentPath) {
|
|
|
790
790
|
const normalized = normalizeLocalDocumentPath(documentPath);
|
|
791
791
|
return join4(projectDocumentsDir(apmRoot), ...normalized.split("/"));
|
|
792
792
|
}
|
|
793
|
-
function normalizeLocalDocumentPath(
|
|
794
|
-
const trimmed =
|
|
793
|
+
function normalizeLocalDocumentPath(path19) {
|
|
794
|
+
const trimmed = path19.trim().replace(/\\/g, "/");
|
|
795
795
|
if (!trimmed || trimmed.startsWith("/") || /^[a-zA-Z]:/.test(trimmed)) {
|
|
796
|
-
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${
|
|
796
|
+
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path19}`);
|
|
797
797
|
}
|
|
798
798
|
const segments = trimmed.split("/").filter(Boolean);
|
|
799
799
|
if (segments.some((segment) => segment === ".." || segment === ".")) {
|
|
800
|
-
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${
|
|
800
|
+
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path19}`);
|
|
801
801
|
}
|
|
802
802
|
return segments.join("/");
|
|
803
803
|
}
|
|
@@ -848,15 +848,15 @@ function diffManifestPaths(remote, local) {
|
|
|
848
848
|
(local?.documents ?? []).map((doc) => [doc.path, doc.contentHash])
|
|
849
849
|
);
|
|
850
850
|
const download = [];
|
|
851
|
-
for (const [
|
|
852
|
-
if (localMap.get(
|
|
853
|
-
download.push(
|
|
851
|
+
for (const [path19, hash] of remoteMap) {
|
|
852
|
+
if (localMap.get(path19) !== hash) {
|
|
853
|
+
download.push(path19);
|
|
854
854
|
}
|
|
855
855
|
}
|
|
856
856
|
const deleteLocal = [];
|
|
857
|
-
for (const
|
|
858
|
-
if (!remoteMap.has(
|
|
859
|
-
deleteLocal.push(
|
|
857
|
+
for (const path19 of localMap.keys()) {
|
|
858
|
+
if (!remoteMap.has(path19)) {
|
|
859
|
+
deleteLocal.push(path19);
|
|
860
860
|
}
|
|
861
861
|
}
|
|
862
862
|
return { download, deleteLocal };
|
|
@@ -916,8 +916,8 @@ ${diagnostic ?? ""}`
|
|
|
916
916
|
}
|
|
917
917
|
}
|
|
918
918
|
let deleted = 0;
|
|
919
|
-
for (const
|
|
920
|
-
const absPath = toFsPath(projectDocumentLocalPath(targetApmDir,
|
|
919
|
+
for (const path19 of deleteLocal) {
|
|
920
|
+
const absPath = toFsPath(projectDocumentLocalPath(targetApmDir, path19));
|
|
921
921
|
if (existsSync2(absPath)) {
|
|
922
922
|
rmSync(absPath, { force: true });
|
|
923
923
|
deleted += 1;
|
|
@@ -962,21 +962,21 @@ async function syncRepositoryProjectDocumentsPush(cfg, workdirPath, apmRoot) {
|
|
|
962
962
|
])
|
|
963
963
|
);
|
|
964
964
|
let synced = 0;
|
|
965
|
-
for (const
|
|
966
|
-
const absPath = toFsPath(projectDocumentLocalPath(targetApmDir,
|
|
965
|
+
for (const path19 of localPaths) {
|
|
966
|
+
const absPath = toFsPath(projectDocumentLocalPath(targetApmDir, path19));
|
|
967
967
|
const content = readFileSync3(absPath, "utf8");
|
|
968
968
|
const contentHash = hashLocalFileContent(content);
|
|
969
|
-
if (remoteHashByPath.get(
|
|
969
|
+
if (remoteHashByPath.get(path19) === contentHash) {
|
|
970
970
|
continue;
|
|
971
971
|
}
|
|
972
972
|
await api.cli.upsertRepositoryProjectDocument({
|
|
973
973
|
repositoryId,
|
|
974
|
-
path:
|
|
974
|
+
path: path19,
|
|
975
975
|
content,
|
|
976
|
-
description: remoteDescriptionByPath.get(
|
|
976
|
+
description: remoteDescriptionByPath.get(path19) ?? void 0
|
|
977
977
|
});
|
|
978
978
|
synced += 1;
|
|
979
|
-
console.log(`[apm] \u5DF2\u540C\u6B65\u4ED3\u5E93\u9879\u76EE\u6587\u6863: ${
|
|
979
|
+
console.log(`[apm] \u5DF2\u540C\u6B65\u4ED3\u5E93\u9879\u76EE\u6587\u6863: ${path19}`);
|
|
980
980
|
}
|
|
981
981
|
if (synced === 0) {
|
|
982
982
|
console.log("[apm] \u4ED3\u5E93\u9879\u76EE\u6587\u6863\u65E0\u53D8\u5316\uFF0C\u8DF3\u8FC7\u63A8\u9001");
|
|
@@ -1228,6 +1228,7 @@ var TASK_STATUS_LABEL = {
|
|
|
1228
1228
|
IN_PROGRESS: "\u8FDB\u884C\u4E2D",
|
|
1229
1229
|
COMPLETED: "\u5DF2\u5B8C\u6210",
|
|
1230
1230
|
FAILED: "\u5DF2\u5931\u8D25",
|
|
1231
|
+
CLOSED: "\u5DF2\u5173\u95ED",
|
|
1231
1232
|
SUSPENDED: "\u5DF2\u6682\u505C"
|
|
1232
1233
|
};
|
|
1233
1234
|
function taskStatusLabel(status) {
|
|
@@ -1265,6 +1266,9 @@ function shouldDeleteMode2(input) {
|
|
|
1265
1266
|
if (input.taskStatus === "FAILED") {
|
|
1266
1267
|
return { delete: true, reason: "\u4EFB\u52A1\u5DF2\u5931\u8D25" };
|
|
1267
1268
|
}
|
|
1269
|
+
if (input.taskStatus === "CLOSED") {
|
|
1270
|
+
return { delete: true, reason: "\u4EFB\u52A1\u5DF2\u5173\u95ED" };
|
|
1271
|
+
}
|
|
1268
1272
|
return { delete: false, reason: "" };
|
|
1269
1273
|
}
|
|
1270
1274
|
function buildSessionBranchRow(input) {
|
|
@@ -1589,13 +1593,13 @@ async function downloadAttachment(cfg, attachmentId) {
|
|
|
1589
1593
|
return Buffer.from(await res.arrayBuffer());
|
|
1590
1594
|
}
|
|
1591
1595
|
function loadManifest(dir) {
|
|
1592
|
-
const
|
|
1593
|
-
if (!existsSync4(
|
|
1596
|
+
const path19 = join6(dir, MANIFEST_FILE2);
|
|
1597
|
+
if (!existsSync4(path19)) {
|
|
1594
1598
|
return { version: 1, attachments: {} };
|
|
1595
1599
|
}
|
|
1596
1600
|
try {
|
|
1597
1601
|
const parsed = JSON.parse(
|
|
1598
|
-
readFileSync5(
|
|
1602
|
+
readFileSync5(path19, "utf8")
|
|
1599
1603
|
);
|
|
1600
1604
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
1601
1605
|
return parsed;
|
|
@@ -1676,8 +1680,8 @@ function sanitizeSkillDirName(name) {
|
|
|
1676
1680
|
function listBaseSkillDirNames() {
|
|
1677
1681
|
if (!existsSync5(BASE_SKILLS_TEMPLATE_DIR)) return [];
|
|
1678
1682
|
return readdirSync3(BASE_SKILLS_TEMPLATE_DIR).filter((name) => {
|
|
1679
|
-
const
|
|
1680
|
-
return statSync2(
|
|
1683
|
+
const path19 = join7(BASE_SKILLS_TEMPLATE_DIR, name);
|
|
1684
|
+
return statSync2(path19).isDirectory();
|
|
1681
1685
|
});
|
|
1682
1686
|
}
|
|
1683
1687
|
function syncAgentsGuide(apmDir) {
|
|
@@ -1689,8 +1693,8 @@ function syncAgentsGuide(apmDir) {
|
|
|
1689
1693
|
function listBaseRuleFileNames() {
|
|
1690
1694
|
if (!existsSync5(BASE_RULES_TEMPLATE_DIR)) return [];
|
|
1691
1695
|
return readdirSync3(BASE_RULES_TEMPLATE_DIR).filter((name) => {
|
|
1692
|
-
const
|
|
1693
|
-
return statSync2(
|
|
1696
|
+
const path19 = join7(BASE_RULES_TEMPLATE_DIR, name);
|
|
1697
|
+
return statSync2(path19).isFile();
|
|
1694
1698
|
});
|
|
1695
1699
|
}
|
|
1696
1700
|
function syncBaseRules(rulesDir) {
|
|
@@ -1753,13 +1757,13 @@ function ruleLocalFileName(ruleName) {
|
|
|
1753
1757
|
return `${sanitized}.md`;
|
|
1754
1758
|
}
|
|
1755
1759
|
function loadManifest2(rulesDir) {
|
|
1756
|
-
const
|
|
1757
|
-
if (!existsSync6(toFsPath(
|
|
1760
|
+
const path19 = join8(rulesDir, MANIFEST_FILE3);
|
|
1761
|
+
if (!existsSync6(toFsPath(path19))) {
|
|
1758
1762
|
return { version: 1, rules: {} };
|
|
1759
1763
|
}
|
|
1760
1764
|
try {
|
|
1761
1765
|
const parsed = JSON.parse(
|
|
1762
|
-
readFileSync6(toFsPath(
|
|
1766
|
+
readFileSync6(toFsPath(path19), "utf8")
|
|
1763
1767
|
);
|
|
1764
1768
|
if (parsed?.version === 1 && parsed.rules && typeof parsed.rules === "object") {
|
|
1765
1769
|
return parsed;
|
|
@@ -2654,93 +2658,17 @@ function validateAgentWsMessage(value, kind) {
|
|
|
2654
2658
|
return validateMessagePush(o);
|
|
2655
2659
|
}
|
|
2656
2660
|
|
|
2657
|
-
// src/commands/deploy/deploy-log-utils.ts
|
|
2658
|
-
import { setTimeout as delay } from "node:timers/promises";
|
|
2659
|
-
var DEPLOY_SPAWN_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
2660
|
-
var DEPLOY_LOG_SYNC_MAX_CHUNK_BYTES = 4 * 1024 * 1024;
|
|
2661
|
-
var DEPLOY_COMPLETE_LOG_MAX_BYTES = 9 * 1024 * 1024;
|
|
2662
|
-
var DEPLOY_LOG_SYNC_MAX_ATTEMPTS = 3;
|
|
2663
|
-
async function retryDeployLogSync(fn, attempts = DEPLOY_LOG_SYNC_MAX_ATTEMPTS) {
|
|
2664
|
-
let lastError;
|
|
2665
|
-
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
2666
|
-
try {
|
|
2667
|
-
return await fn();
|
|
2668
|
-
} catch (error) {
|
|
2669
|
-
lastError = error;
|
|
2670
|
-
if (attempt < attempts) {
|
|
2671
|
-
await delay(1e3 * attempt);
|
|
2672
|
-
}
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
throw lastError;
|
|
2676
|
-
}
|
|
2677
|
-
function splitUtf8StringByMaxBytes(value, maxBytes) {
|
|
2678
|
-
if (maxBytes <= 0) {
|
|
2679
|
-
throw new Error("maxBytes must be positive");
|
|
2680
|
-
}
|
|
2681
|
-
const bytes = Buffer.from(value, "utf8");
|
|
2682
|
-
if (bytes.length <= maxBytes) {
|
|
2683
|
-
return [value];
|
|
2684
|
-
}
|
|
2685
|
-
const chunks = [];
|
|
2686
|
-
let offset = 0;
|
|
2687
|
-
while (offset < bytes.length) {
|
|
2688
|
-
let end = Math.min(offset + maxBytes, bytes.length);
|
|
2689
|
-
while (end > offset && (bytes[end] & 192) === 128) {
|
|
2690
|
-
end -= 1;
|
|
2691
|
-
}
|
|
2692
|
-
if (end <= offset) {
|
|
2693
|
-
end = Math.min(offset + maxBytes, bytes.length);
|
|
2694
|
-
}
|
|
2695
|
-
chunks.push(bytes.subarray(offset, end).toString("utf8"));
|
|
2696
|
-
offset = end;
|
|
2697
|
-
}
|
|
2698
|
-
return chunks;
|
|
2699
|
-
}
|
|
2700
|
-
function truncateDeployLogForComplete(log2) {
|
|
2701
|
-
const bytes = Buffer.from(log2, "utf8");
|
|
2702
|
-
if (bytes.length <= DEPLOY_COMPLETE_LOG_MAX_BYTES) {
|
|
2703
|
-
return { log: log2, truncated: false };
|
|
2704
|
-
}
|
|
2705
|
-
const tailBudget = Math.max(DEPLOY_COMPLETE_LOG_MAX_BYTES - 512, 1024);
|
|
2706
|
-
const prefix = `[apm] \u65E5\u5FD7\u8FC7\u957F\uFF08${Math.ceil(bytes.length / 1024)}KB\uFF09\uFF0C\u4EC5\u4FDD\u7559\u672B\u5C3E ${Math.floor(tailBudget / 1024)}KB
|
|
2707
|
-
`;
|
|
2708
|
-
let tail = bytes.subarray(bytes.length - tailBudget).toString("utf8");
|
|
2709
|
-
const brokenPrefix = tail.indexOf("\uFFFD");
|
|
2710
|
-
if (brokenPrefix >= 0) {
|
|
2711
|
-
const newline = tail.indexOf("\n", brokenPrefix);
|
|
2712
|
-
tail = newline >= 0 ? tail.slice(newline + 1) : tail.slice(brokenPrefix + 1);
|
|
2713
|
-
}
|
|
2714
|
-
return { log: prefix + tail, truncated: true };
|
|
2715
|
-
}
|
|
2716
|
-
|
|
2717
2661
|
// src/commands/deploy/deploy-execute.ts
|
|
2718
|
-
import
|
|
2662
|
+
import path11 from "node:path";
|
|
2719
2663
|
|
|
2720
2664
|
// src/commands/deploy/internal/apm-config.ts
|
|
2721
|
-
import { existsSync as
|
|
2722
|
-
import {
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
process.cwd(),
|
|
2727
|
-
options?.configPath ?? resolve3(workspaceApmDir(), "apm.config.json")
|
|
2728
|
-
);
|
|
2729
|
-
if (!existsSync11(p)) {
|
|
2730
|
-
console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
|
|
2731
|
-
process.exit(1);
|
|
2732
|
-
}
|
|
2733
|
-
try {
|
|
2734
|
-
const raw = readFileSync10(p, "utf8");
|
|
2735
|
-
return JSON.parse(raw);
|
|
2736
|
-
} catch (e) {
|
|
2737
|
-
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
2738
|
-
process.exit(1);
|
|
2739
|
-
}
|
|
2740
|
-
}
|
|
2741
|
-
function req(v, field) {
|
|
2665
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11 } from "node:fs";
|
|
2666
|
+
import { resolve as resolve4 } from "node:path";
|
|
2667
|
+
|
|
2668
|
+
// src/commands/deploy/internal/config/config-validation.ts
|
|
2669
|
+
function req(v, field, section) {
|
|
2742
2670
|
if (v === void 0 || v === null || typeof v === "string" && !v.trim()) {
|
|
2743
|
-
console.error(`apm.config.json \u4E2D
|
|
2671
|
+
console.error(`apm.config.json \u4E2D ${section}.${field} \u4E0D\u80FD\u4E3A\u7A7A`);
|
|
2744
2672
|
process.exit(1);
|
|
2745
2673
|
}
|
|
2746
2674
|
return v;
|
|
@@ -2755,17 +2683,19 @@ function reqTopLevelName(cfg) {
|
|
|
2755
2683
|
}
|
|
2756
2684
|
return n;
|
|
2757
2685
|
}
|
|
2758
|
-
function
|
|
2686
|
+
function reqPositiveInt(v, field, section) {
|
|
2759
2687
|
const n = Number(v);
|
|
2760
2688
|
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1) {
|
|
2761
|
-
console.error(`apm.config.json \u4E2D
|
|
2689
|
+
console.error(`apm.config.json \u4E2D ${section}.${field} \u987B\u4E3A\u6B63\u6574\u6570`);
|
|
2762
2690
|
process.exit(1);
|
|
2763
2691
|
}
|
|
2764
2692
|
return n;
|
|
2765
2693
|
}
|
|
2694
|
+
|
|
2695
|
+
// src/commands/deploy/internal/config/docker-backend-config.ts
|
|
2766
2696
|
function resolveBackendDeployFromApmConfig(cfg) {
|
|
2767
2697
|
const b = cfg.backendDeploy ?? {};
|
|
2768
|
-
const protoRaw = req(b.remoteProtocol, "remoteProtocol").trim().toLowerCase();
|
|
2698
|
+
const protoRaw = req(b.remoteProtocol, "remoteProtocol", "backendDeploy").trim().toLowerCase();
|
|
2769
2699
|
if (protoRaw !== "http" && protoRaw !== "https") {
|
|
2770
2700
|
console.error(
|
|
2771
2701
|
"apm.config.json \u4E2D backendDeploy.remoteProtocol \u53EA\u80FD\u4E3A http \u6216 https"
|
|
@@ -2786,12 +2716,20 @@ function resolveBackendDeployFromApmConfig(cfg) {
|
|
|
2786
2716
|
}
|
|
2787
2717
|
return {
|
|
2788
2718
|
name: reqTopLevelName(cfg),
|
|
2789
|
-
registryHost: req(b.registryHost, "registryHost").trim(),
|
|
2790
|
-
registryNamespace: req(
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2719
|
+
registryHost: req(b.registryHost, "registryHost", "backendDeploy").trim(),
|
|
2720
|
+
registryNamespace: req(
|
|
2721
|
+
b.registryNamespace,
|
|
2722
|
+
"registryNamespace",
|
|
2723
|
+
"backendDeploy"
|
|
2724
|
+
).trim(),
|
|
2725
|
+
registryUser: req(b.registryUser, "registryUser", "backendDeploy").trim(),
|
|
2726
|
+
registryPassword: req(
|
|
2727
|
+
b.registryPassword,
|
|
2728
|
+
"registryPassword",
|
|
2729
|
+
"backendDeploy"
|
|
2730
|
+
).trim(),
|
|
2731
|
+
remoteHost: req(b.remoteHost, "remoteHost", "backendDeploy").trim(),
|
|
2732
|
+
remotePort: reqPositiveInt(b.remotePort, "remotePort", "backendDeploy"),
|
|
2795
2733
|
remoteProtocol,
|
|
2796
2734
|
caPath: b.caPath?.trim(),
|
|
2797
2735
|
certPath: b.certPath?.trim(),
|
|
@@ -2801,64 +2739,30 @@ function resolveBackendDeployFromApmConfig(cfg) {
|
|
|
2801
2739
|
dockerNetwork: b.dockerNetwork?.trim() || void 0
|
|
2802
2740
|
};
|
|
2803
2741
|
}
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
console.error(`apm.config.json \u4E2D frontendDeploy.${field} \u4E0D\u80FD\u4E3A\u7A7A`);
|
|
2807
|
-
process.exit(1);
|
|
2808
|
-
}
|
|
2809
|
-
return v;
|
|
2810
|
-
}
|
|
2742
|
+
|
|
2743
|
+
// src/commands/deploy/internal/config/frontend-minio-config.ts
|
|
2811
2744
|
function resolveFrontendDeployFromApmConfig(cfg) {
|
|
2812
2745
|
const f = cfg.frontendDeploy ?? {};
|
|
2813
2746
|
const port = Number(f.port);
|
|
2814
2747
|
return {
|
|
2815
|
-
endpoint:
|
|
2748
|
+
endpoint: req(f.endpoint, "endpoint", "frontendDeploy").trim(),
|
|
2816
2749
|
port: Number.isFinite(port) && port > 0 ? port : 9e3,
|
|
2817
2750
|
useSsl: Boolean(f.useSsl),
|
|
2818
|
-
accessKey:
|
|
2819
|
-
secretKey:
|
|
2820
|
-
bucket:
|
|
2821
|
-
};
|
|
2822
|
-
}
|
|
2823
|
-
function reqWd(v, field) {
|
|
2824
|
-
if (v === void 0 || v === null || typeof v === "string" && !v.trim()) {
|
|
2825
|
-
console.error(`apm.config.json \u4E2D wisdomDeploy.${field} \u4E0D\u80FD\u4E3A\u7A7A`);
|
|
2826
|
-
process.exit(1);
|
|
2827
|
-
}
|
|
2828
|
-
return v;
|
|
2829
|
-
}
|
|
2830
|
-
function reqWisdomPositiveInt(v, field) {
|
|
2831
|
-
const n = Number(v);
|
|
2832
|
-
if (!Number.isFinite(n) || !Number.isInteger(n) || n < 1) {
|
|
2833
|
-
console.error(`apm.config.json \u4E2D wisdomDeploy.${field} \u987B\u4E3A\u6B63\u6574\u6570`);
|
|
2834
|
-
process.exit(1);
|
|
2835
|
-
}
|
|
2836
|
-
return n;
|
|
2837
|
-
}
|
|
2838
|
-
function resolveWisdomDeployFromApmConfig(cfg) {
|
|
2839
|
-
const w = cfg.wisdomDeploy ?? {};
|
|
2840
|
-
return {
|
|
2841
|
-
host: reqWd(w.host, "host").trim(),
|
|
2842
|
-
port: reqWisdomPositiveInt(w.port, "port"),
|
|
2843
|
-
username: reqWd(w.username, "username").trim(),
|
|
2844
|
-
password: reqWd(w.password, "password").trim(),
|
|
2845
|
-
remotePath: reqWd(w.remotePath, "remotePath").trim()
|
|
2751
|
+
accessKey: req(f.accessKey, "accessKey", "frontendDeploy").trim(),
|
|
2752
|
+
secretKey: req(f.secretKey, "secretKey", "frontendDeploy").trim(),
|
|
2753
|
+
bucket: req(f.bucket, "bucket", "frontendDeploy").trim()
|
|
2846
2754
|
};
|
|
2847
2755
|
}
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
process.exit(1);
|
|
2859
|
-
}
|
|
2860
|
-
return v;
|
|
2861
|
-
}
|
|
2756
|
+
|
|
2757
|
+
// src/commands/deploy/internal/config/maven-repo.ts
|
|
2758
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10 } from "node:fs";
|
|
2759
|
+
import { homedir as homedir2 } from "node:os";
|
|
2760
|
+
import { join as join13, resolve as resolve3 } from "node:path";
|
|
2761
|
+
var MAVEN_REPO_ENV_KEYS = [
|
|
2762
|
+
"MAVEN_LOCAL_REPO",
|
|
2763
|
+
"M2_REPO",
|
|
2764
|
+
"MAVEN_REPOSITORY"
|
|
2765
|
+
];
|
|
2862
2766
|
function readEnvVar(env, name) {
|
|
2863
2767
|
if (env[name] !== void 0) {
|
|
2864
2768
|
return env[name];
|
|
@@ -2888,11 +2792,6 @@ function expandUserPath(pathStr, env = process.env) {
|
|
|
2888
2792
|
}
|
|
2889
2793
|
return resolve3(expanded);
|
|
2890
2794
|
}
|
|
2891
|
-
var MAVEN_REPO_ENV_KEYS = [
|
|
2892
|
-
"MAVEN_LOCAL_REPO",
|
|
2893
|
-
"M2_REPO",
|
|
2894
|
-
"MAVEN_REPOSITORY"
|
|
2895
|
-
];
|
|
2896
2795
|
function readMavenLocalRepoFromMavenOpts(mavenOpts, env = process.env) {
|
|
2897
2796
|
const match = mavenOpts.match(/-Dmaven\.repo\.local=(?:"([^"]+)"|(\S+))/);
|
|
2898
2797
|
const raw = match?.[1]?.trim() || match?.[2]?.trim();
|
|
@@ -2907,9 +2806,9 @@ function readMavenLocalRepoFromEnv(env = process.env) {
|
|
|
2907
2806
|
}
|
|
2908
2807
|
const mavenOpts = readEnvVar(env, "MAVEN_OPTS")?.trim();
|
|
2909
2808
|
if (mavenOpts) {
|
|
2910
|
-
const
|
|
2911
|
-
if (
|
|
2912
|
-
return { path:
|
|
2809
|
+
const path19 = readMavenLocalRepoFromMavenOpts(mavenOpts, env);
|
|
2810
|
+
if (path19) {
|
|
2811
|
+
return { path: path19, key: "MAVEN_OPTS" };
|
|
2913
2812
|
}
|
|
2914
2813
|
}
|
|
2915
2814
|
return null;
|
|
@@ -2956,6 +2855,18 @@ function resolveMavenLocalRepoWithSource() {
|
|
|
2956
2855
|
sourceDetail: "~/.m2/repository"
|
|
2957
2856
|
};
|
|
2958
2857
|
}
|
|
2858
|
+
|
|
2859
|
+
// src/commands/deploy/internal/config/wisdom-config.ts
|
|
2860
|
+
function resolveWisdomDeployFromApmConfig(cfg) {
|
|
2861
|
+
const w = cfg.wisdomDeploy ?? {};
|
|
2862
|
+
return {
|
|
2863
|
+
host: req(w.host, "host", "wisdomDeploy").trim(),
|
|
2864
|
+
port: reqPositiveInt(w.port, "port", "wisdomDeploy"),
|
|
2865
|
+
username: req(w.username, "username", "wisdomDeploy").trim(),
|
|
2866
|
+
password: req(w.password, "password", "wisdomDeploy").trim(),
|
|
2867
|
+
remotePath: req(w.remotePath, "remotePath", "wisdomDeploy").trim()
|
|
2868
|
+
};
|
|
2869
|
+
}
|
|
2959
2870
|
function resolveWisdomDeployMode(raw) {
|
|
2960
2871
|
if (raw === void 0 || raw === null || raw === "") {
|
|
2961
2872
|
return "default";
|
|
@@ -2969,14 +2880,27 @@ function resolveWisdomDeployMode(raw) {
|
|
|
2969
2880
|
);
|
|
2970
2881
|
process.exit(1);
|
|
2971
2882
|
}
|
|
2883
|
+
function posixDirname(p) {
|
|
2884
|
+
const normalized = p.replace(/\\/g, "/");
|
|
2885
|
+
const idx = normalized.lastIndexOf("/");
|
|
2886
|
+
if (idx <= 0) {
|
|
2887
|
+
return normalized.startsWith("/") ? "/" : ".";
|
|
2888
|
+
}
|
|
2889
|
+
return normalized.slice(0, idx);
|
|
2890
|
+
}
|
|
2891
|
+
function posixBasename(p) {
|
|
2892
|
+
const normalized = p.replace(/\\/g, "/");
|
|
2893
|
+
const idx = normalized.lastIndexOf("/");
|
|
2894
|
+
return idx >= 0 ? normalized.slice(idx + 1) : normalized;
|
|
2895
|
+
}
|
|
2972
2896
|
function resolveWisdomBackendDeployFromApmConfig(cfg) {
|
|
2973
2897
|
const projectName = reqTopLevelName(cfg);
|
|
2974
2898
|
const w = cfg.wisdomDeploy ?? {};
|
|
2975
2899
|
const h = cfg.healthCheck ?? {};
|
|
2976
|
-
const jarPath =
|
|
2900
|
+
const jarPath = req(w.jarPath, "jarPath", "wisdomDeploy").trim();
|
|
2977
2901
|
const remoteAppDir = posixDirname(jarPath);
|
|
2978
|
-
const healthPort = Number(
|
|
2979
|
-
const healthTimeout = Number(
|
|
2902
|
+
const healthPort = Number(req(h.port, "port", "healthCheck"));
|
|
2903
|
+
const healthTimeout = Number(req(h.timeout, "timeout", "healthCheck"));
|
|
2980
2904
|
if (!Number.isFinite(healthPort) || !Number.isInteger(healthPort) || healthPort < 1) {
|
|
2981
2905
|
console.error("apm.config.json \u4E2D healthCheck.port \u987B\u4E3A\u6B63\u6574\u6570");
|
|
2982
2906
|
process.exit(1);
|
|
@@ -2988,11 +2912,11 @@ function resolveWisdomBackendDeployFromApmConfig(cfg) {
|
|
|
2988
2912
|
const mavenLocalRepo = resolveMavenLocalRepoWithSource();
|
|
2989
2913
|
return {
|
|
2990
2914
|
projectName,
|
|
2991
|
-
host:
|
|
2992
|
-
port:
|
|
2993
|
-
username:
|
|
2994
|
-
password:
|
|
2995
|
-
remoteVueDistDir:
|
|
2915
|
+
host: req(w.host, "host", "wisdomDeploy").trim(),
|
|
2916
|
+
port: reqPositiveInt(w.port, "port", "wisdomDeploy"),
|
|
2917
|
+
username: req(w.username, "username", "wisdomDeploy").trim(),
|
|
2918
|
+
password: req(w.password, "password", "wisdomDeploy").trim(),
|
|
2919
|
+
remoteVueDistDir: req(w.remotePath, "remotePath", "wisdomDeploy").trim(),
|
|
2996
2920
|
remoteAppDir,
|
|
2997
2921
|
remoteLibDir: `${remoteAppDir}/lib`,
|
|
2998
2922
|
startupJar: posixBasename(jarPath),
|
|
@@ -3001,35 +2925,51 @@ function resolveWisdomBackendDeployFromApmConfig(cfg) {
|
|
|
3001
2925
|
mavenLocalRepoSource: mavenLocalRepo.source,
|
|
3002
2926
|
mavenLocalRepoSourceDetail: mavenLocalRepo.sourceDetail,
|
|
3003
2927
|
healthCheckPort: healthPort,
|
|
3004
|
-
healthCheckContext:
|
|
2928
|
+
healthCheckContext: req(h.context, "context", "healthCheck").trim(),
|
|
3005
2929
|
healthCheckTimeout: healthTimeout,
|
|
3006
2930
|
mode: resolveWisdomDeployMode(w.mode)
|
|
3007
2931
|
};
|
|
3008
2932
|
}
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
2933
|
+
|
|
2934
|
+
// src/commands/deploy/internal/apm-config.ts
|
|
2935
|
+
function loadApmConfig(options) {
|
|
2936
|
+
const p = resolve4(
|
|
2937
|
+
process.cwd(),
|
|
2938
|
+
options?.configPath ?? resolve4(workspaceApmDir(), "apm.config.json")
|
|
2939
|
+
);
|
|
2940
|
+
if (!existsSync12(p)) {
|
|
2941
|
+
console.error(`\u672A\u627E\u5230\u914D\u7F6E\u6587\u4EF6\uFF1A${p}`);
|
|
2942
|
+
process.exit(1);
|
|
2943
|
+
}
|
|
2944
|
+
try {
|
|
2945
|
+
const raw = readFileSync11(p, "utf8");
|
|
2946
|
+
return JSON.parse(raw);
|
|
2947
|
+
} catch (e) {
|
|
2948
|
+
console.error(`\u65E0\u6CD5\u89E3\u6790 apm.config.json\uFF1A${p}`, e);
|
|
2949
|
+
process.exit(1);
|
|
3014
2950
|
}
|
|
3015
|
-
return normalized.slice(0, idx);
|
|
3016
|
-
}
|
|
3017
|
-
function posixBasename(p) {
|
|
3018
|
-
const normalized = p.replace(/\\/g, "/");
|
|
3019
|
-
const idx = normalized.lastIndexOf("/");
|
|
3020
|
-
return idx >= 0 ? normalized.slice(idx + 1) : normalized;
|
|
3021
2951
|
}
|
|
3022
2952
|
|
|
3023
2953
|
// src/commands/deploy/internal/deploy-hints.ts
|
|
2954
|
+
function isProductionDeployEnv(env) {
|
|
2955
|
+
const normalized = env.trim().toLowerCase();
|
|
2956
|
+
return normalized === "online" || normalized === "production" || normalized === "prod";
|
|
2957
|
+
}
|
|
3024
2958
|
function formatMissingWisdomDeployLines() {
|
|
3025
2959
|
return [
|
|
3026
2960
|
"[apm] \u65E0\u6CD5\u6267\u884C apm deploy\uFF1A\u8BF7\u5728 apm.config.json \u4E2D\u914D\u7F6E wisdomDeploy\uFF08host\u3001remotePath\uFF09"
|
|
3027
2961
|
];
|
|
3028
2962
|
}
|
|
3029
2963
|
function formatWisdomFrontendBuildNotConfiguredLines(env, packageJsonPath) {
|
|
2964
|
+
if (isProductionDeployEnv(env)) {
|
|
2965
|
+
return [
|
|
2966
|
+
`[apm] \u65E0\u6CD5\u6267\u884C\u524D\u7AEF\u90E8\u7F72\uFF1A${packageJsonPath} \u4E2D\u672A\u627E\u5230 build:${env} \u6216 build \u811A\u672C`,
|
|
2967
|
+
"[apm] \u8BF7\u914D\u7F6E npm run build:online \u6216 npm run build \u540E\u518D\u8BD5"
|
|
2968
|
+
];
|
|
2969
|
+
}
|
|
3030
2970
|
return [
|
|
3031
2971
|
`[apm] \u65E0\u6CD5\u6267\u884C\u524D\u7AEF\u90E8\u7F72\uFF1A${packageJsonPath} \u4E2D\u672A\u627E\u5230 build:${env} \u811A\u672C`,
|
|
3032
|
-
"[apm] \u8BF7\u914D\u7F6E npm run build:test
|
|
2972
|
+
"[apm] \u8BF7\u914D\u7F6E npm run build:test \u540E\u518D\u8BD5"
|
|
3033
2973
|
];
|
|
3034
2974
|
}
|
|
3035
2975
|
|
|
@@ -3047,7 +2987,7 @@ var DeployExecutionError = class extends Error {
|
|
|
3047
2987
|
|
|
3048
2988
|
// src/commands/deploy/deploy-debug-log.ts
|
|
3049
2989
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
3050
|
-
import { existsSync as
|
|
2990
|
+
import { existsSync as existsSync15 } from "node:fs";
|
|
3051
2991
|
import { dirname as dirname5, join as join16 } from "node:path";
|
|
3052
2992
|
|
|
3053
2993
|
// src/commands/deploy/internal/deploy-artifact-minio.ts
|
|
@@ -3153,14 +3093,14 @@ var MinioClient = class {
|
|
|
3153
3093
|
async deleteObjectsByPrefix(bucket, prefix) {
|
|
3154
3094
|
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
3155
3095
|
const keys = [];
|
|
3156
|
-
await new Promise((
|
|
3096
|
+
await new Promise((resolve6, reject) => {
|
|
3157
3097
|
objectsStream.on("data", (obj) => {
|
|
3158
3098
|
if (obj.name) {
|
|
3159
3099
|
keys.push(obj.name);
|
|
3160
3100
|
}
|
|
3161
3101
|
});
|
|
3162
3102
|
objectsStream.on("error", reject);
|
|
3163
|
-
objectsStream.on("end",
|
|
3103
|
+
objectsStream.on("end", resolve6);
|
|
3164
3104
|
});
|
|
3165
3105
|
const chunkSize = 500;
|
|
3166
3106
|
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
@@ -3306,15 +3246,15 @@ import { dirname as dirname4 } from "node:path";
|
|
|
3306
3246
|
|
|
3307
3247
|
// src/commands/daemon.ts
|
|
3308
3248
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
3309
|
-
import { setTimeout as
|
|
3310
|
-
import { existsSync as
|
|
3249
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
3250
|
+
import { existsSync as existsSync14, mkdirSync as mkdirSync6, unlinkSync as unlinkSync2, writeFileSync as writeFileSync11 } from "fs";
|
|
3311
3251
|
import { join as join15 } from "path";
|
|
3312
3252
|
|
|
3313
3253
|
// src/commands/connect-lock.ts
|
|
3314
3254
|
import {
|
|
3315
|
-
existsSync as
|
|
3255
|
+
existsSync as existsSync13,
|
|
3316
3256
|
mkdirSync as mkdirSync5,
|
|
3317
|
-
readFileSync as
|
|
3257
|
+
readFileSync as readFileSync12,
|
|
3318
3258
|
unlinkSync,
|
|
3319
3259
|
writeFileSync as writeFileSync10
|
|
3320
3260
|
} from "fs";
|
|
@@ -3346,9 +3286,9 @@ function waitForPm2LockHandoff(timeoutMs = 5e3) {
|
|
|
3346
3286
|
}
|
|
3347
3287
|
}
|
|
3348
3288
|
function readConnectLock() {
|
|
3349
|
-
if (!
|
|
3289
|
+
if (!existsSync13(CONNECT_LOCK_PATH)) return null;
|
|
3350
3290
|
try {
|
|
3351
|
-
const raw =
|
|
3291
|
+
const raw = readFileSync12(CONNECT_LOCK_PATH, "utf8");
|
|
3352
3292
|
const parsed = JSON.parse(raw);
|
|
3353
3293
|
if (typeof parsed.pid !== "number" || parsed.mode !== "foreground" && parsed.mode !== "pm2" || typeof parsed.startedAt !== "string") {
|
|
3354
3294
|
return null;
|
|
@@ -3405,7 +3345,7 @@ function releaseConnectLock() {
|
|
|
3405
3345
|
}
|
|
3406
3346
|
function forceReleaseConnectLock() {
|
|
3407
3347
|
try {
|
|
3408
|
-
if (
|
|
3348
|
+
if (existsSync13(CONNECT_LOCK_PATH)) {
|
|
3409
3349
|
unlinkSync(CONNECT_LOCK_PATH);
|
|
3410
3350
|
}
|
|
3411
3351
|
} catch {
|
|
@@ -3555,14 +3495,14 @@ function resolvePm2FromNpmRoot() {
|
|
|
3555
3495
|
if (!root) return null;
|
|
3556
3496
|
for (const rel of ["pm2/bin/pm2", "pm2/bin/pm2.js"]) {
|
|
3557
3497
|
const candidate = join15(root, ...rel.split("/"));
|
|
3558
|
-
if (
|
|
3498
|
+
if (existsSync14(candidate)) {
|
|
3559
3499
|
return candidate;
|
|
3560
3500
|
}
|
|
3561
3501
|
}
|
|
3562
3502
|
return null;
|
|
3563
3503
|
}
|
|
3564
|
-
function isPm2NodeScript(
|
|
3565
|
-
return
|
|
3504
|
+
function isPm2NodeScript(path19) {
|
|
3505
|
+
return path19.endsWith(".js") || /[\\/]pm2[\\/]bin[\\/]pm2$/.test(path19);
|
|
3566
3506
|
}
|
|
3567
3507
|
function buildPm2SpawnTarget(binPath) {
|
|
3568
3508
|
if (isPm2NodeScript(binPath)) {
|
|
@@ -3592,7 +3532,7 @@ function spawnPm2At(binPath, args, options = {}) {
|
|
|
3592
3532
|
return spawnPm2Target(buildPm2SpawnTarget(binPath), args, options);
|
|
3593
3533
|
}
|
|
3594
3534
|
function verifyPm2Bin(pm2Bin) {
|
|
3595
|
-
if (!pm2Bin.trim() || !
|
|
3535
|
+
if (!pm2Bin.trim() || !existsSync14(pm2Bin)) {
|
|
3596
3536
|
return false;
|
|
3597
3537
|
}
|
|
3598
3538
|
const result = spawnPm2At(pm2Bin, ["--version"], {
|
|
@@ -3731,7 +3671,7 @@ function ensureGlobalPm2(options) {
|
|
|
3731
3671
|
}
|
|
3732
3672
|
function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
3733
3673
|
const fromArgv = entryArg?.trim();
|
|
3734
|
-
if (fromArgv &&
|
|
3674
|
+
if (fromArgv && existsSync14(fromArgv)) {
|
|
3735
3675
|
return fromArgv;
|
|
3736
3676
|
}
|
|
3737
3677
|
const npmResult = spawnSync2(useNpmShell2 ? "npm.cmd" : "npm", ["root", "-g"], {
|
|
@@ -3743,7 +3683,7 @@ function resolveApmEntryPath(entryArg = process.argv[1]) {
|
|
|
3743
3683
|
const globalRoot = npmResult.stdout?.toString().trim();
|
|
3744
3684
|
if (globalRoot) {
|
|
3745
3685
|
const candidate = join15(globalRoot, CLI_PACKAGE_NAME, "dist", "index.js");
|
|
3746
|
-
if (
|
|
3686
|
+
if (existsSync14(candidate)) {
|
|
3747
3687
|
return candidate;
|
|
3748
3688
|
}
|
|
3749
3689
|
}
|
|
@@ -3934,7 +3874,7 @@ function writeEcosystemFile(options) {
|
|
|
3934
3874
|
formatConnectPm2EcosystemFile(ecosystem),
|
|
3935
3875
|
"utf8"
|
|
3936
3876
|
);
|
|
3937
|
-
if (
|
|
3877
|
+
if (existsSync14(LEGACY_PM2_ECOSYSTEM_PATH)) {
|
|
3938
3878
|
try {
|
|
3939
3879
|
unlinkSync2(LEGACY_PM2_ECOSYSTEM_PATH);
|
|
3940
3880
|
} catch {
|
|
@@ -3963,7 +3903,7 @@ async function runDaemonStart(options) {
|
|
|
3963
3903
|
const cfg = await prepareEcosystem(options.server);
|
|
3964
3904
|
removePm2ConnectProcesses();
|
|
3965
3905
|
runPm2(["start", PM2_ECOSYSTEM_PATH, "--update-env"], { inherit: true });
|
|
3966
|
-
await
|
|
3906
|
+
await delay(1e3);
|
|
3967
3907
|
if (!isPm2ConnectOnline()) {
|
|
3968
3908
|
console.error(
|
|
3969
3909
|
`[apm] ${PM2_APP_NAME} \u542F\u52A8\u540E\u672A\u5904\u4E8E online \u72B6\u6001\uFF0C\u8BF7\u6267\u884C: apm daemon logs -n 200`
|
|
@@ -3996,7 +3936,7 @@ async function runDaemonStop() {
|
|
|
3996
3936
|
});
|
|
3997
3937
|
for (let i = 0; i < 10; i += 1) {
|
|
3998
3938
|
if (!isPm2ConnectOnline()) break;
|
|
3999
|
-
await
|
|
3939
|
+
await delay(500);
|
|
4000
3940
|
}
|
|
4001
3941
|
if (isPm2ConnectOnline()) {
|
|
4002
3942
|
console.log(`[apm] \u4F18\u96C5\u505C\u6B62\u8D85\u65F6\uFF0C\u5F3A\u5236\u79FB\u9664 ${PM2_APP_NAME}\u2026`);
|
|
@@ -4231,12 +4171,12 @@ function logExecuteDeployContext(input) {
|
|
|
4231
4171
|
`cwdMatchProcess=${input.cwd === input.processCwd ? "yes" : "no"} (connect \u901A\u5E38\u4E3A no)`
|
|
4232
4172
|
);
|
|
4233
4173
|
logLine(
|
|
4234
|
-
`apm.config=${input.apmConfigPath} exists=${
|
|
4174
|
+
`apm.config=${input.apmConfigPath} exists=${existsSync15(
|
|
4235
4175
|
input.apmConfigPath
|
|
4236
4176
|
)}`
|
|
4237
4177
|
);
|
|
4238
4178
|
logLine(
|
|
4239
|
-
`package.json=${packageJsonPath} exists=${
|
|
4179
|
+
`package.json=${packageJsonPath} exists=${existsSync15(packageJsonPath)}`
|
|
4240
4180
|
);
|
|
4241
4181
|
logLine(
|
|
4242
4182
|
`flags captureOutput=${input.captureOutput} packOnly=${Boolean(
|
|
@@ -4292,18 +4232,64 @@ function logWisdomFrontendDeployContext(input) {
|
|
|
4292
4232
|
logLine(
|
|
4293
4233
|
`buildKey=build:${input.env} buildCmd=${input.buildCmd ?? "(missing)"}`
|
|
4294
4234
|
);
|
|
4295
|
-
logLine(`distDir=${input.distDir} exists=${
|
|
4235
|
+
logLine(`distDir=${input.distDir} exists=${existsSync15(input.distDir)}`);
|
|
4296
4236
|
logLine(
|
|
4297
4237
|
`packOnly=${input.packOnly} archiveDeployArtifact=${input.archiveDeployArtifact}`
|
|
4298
4238
|
);
|
|
4299
4239
|
}
|
|
4300
4240
|
|
|
4301
4241
|
// src/commands/deploy/internal/wisdom-deploy.ts
|
|
4302
|
-
import { existsSync as
|
|
4303
|
-
import
|
|
4242
|
+
import { existsSync as existsSync19, readFileSync as readFileSync15, statSync as statSync9 } from "node:fs";
|
|
4243
|
+
import path10 from "node:path";
|
|
4304
4244
|
|
|
4305
4245
|
// src/commands/deploy/deploy-shell-run.ts
|
|
4306
4246
|
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
4247
|
+
|
|
4248
|
+
// src/commands/deploy/deploy-log-utils.ts
|
|
4249
|
+
import { setTimeout as delay2 } from "node:timers/promises";
|
|
4250
|
+
var DEPLOY_SPAWN_MAX_BUFFER_BYTES = 50 * 1024 * 1024;
|
|
4251
|
+
var DEPLOY_LOG_SYNC_MAX_CHUNK_BYTES = 4 * 1024 * 1024;
|
|
4252
|
+
var DEPLOY_LOG_SYNC_MAX_ATTEMPTS = 3;
|
|
4253
|
+
async function retryDeployLogSync(fn, attempts = DEPLOY_LOG_SYNC_MAX_ATTEMPTS) {
|
|
4254
|
+
let lastError;
|
|
4255
|
+
for (let attempt = 1; attempt <= attempts; attempt += 1) {
|
|
4256
|
+
try {
|
|
4257
|
+
return await fn();
|
|
4258
|
+
} catch (error) {
|
|
4259
|
+
lastError = error;
|
|
4260
|
+
if (attempt < attempts) {
|
|
4261
|
+
await delay2(1e3 * attempt);
|
|
4262
|
+
}
|
|
4263
|
+
}
|
|
4264
|
+
}
|
|
4265
|
+
throw lastError;
|
|
4266
|
+
}
|
|
4267
|
+
var retryDeployStatusComplete = retryDeployLogSync;
|
|
4268
|
+
function splitUtf8StringByMaxBytes(value, maxBytes) {
|
|
4269
|
+
if (maxBytes <= 0) {
|
|
4270
|
+
throw new Error("maxBytes must be positive");
|
|
4271
|
+
}
|
|
4272
|
+
const bytes = Buffer.from(value, "utf8");
|
|
4273
|
+
if (bytes.length <= maxBytes) {
|
|
4274
|
+
return [value];
|
|
4275
|
+
}
|
|
4276
|
+
const chunks = [];
|
|
4277
|
+
let offset = 0;
|
|
4278
|
+
while (offset < bytes.length) {
|
|
4279
|
+
let end = Math.min(offset + maxBytes, bytes.length);
|
|
4280
|
+
while (end > offset && (bytes[end] & 192) === 128) {
|
|
4281
|
+
end -= 1;
|
|
4282
|
+
}
|
|
4283
|
+
if (end <= offset) {
|
|
4284
|
+
end = Math.min(offset + maxBytes, bytes.length);
|
|
4285
|
+
}
|
|
4286
|
+
chunks.push(bytes.subarray(offset, end).toString("utf8"));
|
|
4287
|
+
offset = end;
|
|
4288
|
+
}
|
|
4289
|
+
return chunks;
|
|
4290
|
+
}
|
|
4291
|
+
|
|
4292
|
+
// src/commands/deploy/deploy-shell-run.ts
|
|
4307
4293
|
function runDeployShellCommand(command, cwd, captureOutput) {
|
|
4308
4294
|
logRunDeployShellContext({ command, cwd, captureOutput });
|
|
4309
4295
|
const shellEnv = buildDeployShellEnv();
|
|
@@ -4346,43 +4332,93 @@ function runDeployShellCommand(command, cwd, captureOutput) {
|
|
|
4346
4332
|
return output;
|
|
4347
4333
|
}
|
|
4348
4334
|
|
|
4349
|
-
// src/commands/deploy/internal/wisdom-backend
|
|
4335
|
+
// src/commands/deploy/internal/wisdom-backend/index.ts
|
|
4336
|
+
import path9 from "node:path";
|
|
4337
|
+
|
|
4338
|
+
// src/commands/deploy/internal/wisdom-backend/jar-incremental.ts
|
|
4350
4339
|
import {
|
|
4351
|
-
|
|
4352
|
-
mkdirSync as mkdirSync7,
|
|
4340
|
+
mkdirSync as mkdirSync8,
|
|
4353
4341
|
readdirSync as readdirSync5,
|
|
4354
|
-
readFileSync as
|
|
4355
|
-
statSync as
|
|
4356
|
-
writeFileSync as
|
|
4342
|
+
readFileSync as readFileSync14,
|
|
4343
|
+
statSync as statSync7,
|
|
4344
|
+
writeFileSync as writeFileSync13
|
|
4357
4345
|
} from "node:fs";
|
|
4358
|
-
import
|
|
4359
|
-
import path3 from "node:path";
|
|
4360
|
-
import { Client as Client2 } from "ssh2";
|
|
4346
|
+
import path6 from "node:path";
|
|
4361
4347
|
import JSZip2 from "jszip";
|
|
4362
|
-
import SftpClient2 from "ssh2-sftp-client";
|
|
4363
4348
|
|
|
4364
|
-
// src/commands/deploy/internal/wisdom-
|
|
4365
|
-
import {
|
|
4349
|
+
// src/commands/deploy/internal/wisdom-backend/manifest.ts
|
|
4350
|
+
import {
|
|
4351
|
+
existsSync as existsSync16,
|
|
4352
|
+
mkdirSync as mkdirSync7,
|
|
4353
|
+
readFileSync as readFileSync13,
|
|
4354
|
+
statSync as statSync6,
|
|
4355
|
+
writeFileSync as writeFileSync12
|
|
4356
|
+
} from "node:fs";
|
|
4366
4357
|
import path2 from "node:path";
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4358
|
+
function deployCacheDir() {
|
|
4359
|
+
return path2.join(workspaceApmDir(), "deploy", ".deploy_cache");
|
|
4360
|
+
}
|
|
4361
|
+
function manifestFilePath() {
|
|
4362
|
+
return path2.join(deployCacheDir(), "manifest.json");
|
|
4363
|
+
}
|
|
4364
|
+
function relativeKey(projectRoot, filePath) {
|
|
4365
|
+
return path2.relative(projectRoot, filePath).split(path2.sep).join("/");
|
|
4366
|
+
}
|
|
4367
|
+
function fileSignature(filePath) {
|
|
4368
|
+
const stat2 = statSync6(filePath);
|
|
4369
|
+
return { size: stat2.size, mtime: stat2.mtimeMs / 1e3 };
|
|
4370
|
+
}
|
|
4371
|
+
function loadManifest3() {
|
|
4372
|
+
const manifestPath2 = manifestFilePath();
|
|
4373
|
+
if (!existsSync16(manifestPath2)) {
|
|
4374
|
+
return {};
|
|
4382
4375
|
}
|
|
4376
|
+
return JSON.parse(readFileSync13(manifestPath2, "utf8"));
|
|
4383
4377
|
}
|
|
4384
|
-
|
|
4385
|
-
|
|
4378
|
+
function saveManifest3(manifest) {
|
|
4379
|
+
const dir = deployCacheDir();
|
|
4380
|
+
mkdirSync7(dir, { recursive: true });
|
|
4381
|
+
writeFileSync12(manifestFilePath(), JSON.stringify(manifest, null, 2), "utf8");
|
|
4382
|
+
}
|
|
4383
|
+
function updateManifestEntries(manifest, entries, projectRoot) {
|
|
4384
|
+
for (const entry of entries) {
|
|
4385
|
+
manifest[relativeKey(projectRoot, entry.path)] = fileSignature(entry.path);
|
|
4386
|
+
}
|
|
4387
|
+
return manifest;
|
|
4388
|
+
}
|
|
4389
|
+
function deployCacheDirectory() {
|
|
4390
|
+
return deployCacheDir();
|
|
4391
|
+
}
|
|
4392
|
+
|
|
4393
|
+
// src/commands/deploy/internal/wisdom-backend/internal-utils.ts
|
|
4394
|
+
import path5 from "node:path";
|
|
4395
|
+
|
|
4396
|
+
// src/commands/deploy/internal/wisdom-sftp.ts
|
|
4397
|
+
import { unlink as unlink2 } from "node:fs/promises";
|
|
4398
|
+
import path4 from "node:path";
|
|
4399
|
+
import SftpClient from "ssh2-sftp-client";
|
|
4400
|
+
|
|
4401
|
+
// src/commands/deploy/internal/artifact-packaging.ts
|
|
4402
|
+
import { readdir as readdir2, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
|
|
4403
|
+
import path3 from "node:path";
|
|
4404
|
+
import JSZip from "jszip";
|
|
4405
|
+
async function addDirToZip(dir, zipFolder) {
|
|
4406
|
+
const entries = await readdir2(dir, { withFileTypes: true });
|
|
4407
|
+
for (const entry of entries) {
|
|
4408
|
+
const fullPath = path3.join(dir, entry.name);
|
|
4409
|
+
if (entry.isDirectory()) {
|
|
4410
|
+
const folder = zipFolder.folder(entry.name);
|
|
4411
|
+
if (folder) {
|
|
4412
|
+
await addDirToZip(fullPath, folder);
|
|
4413
|
+
}
|
|
4414
|
+
} else {
|
|
4415
|
+
const content = await readFile3(fullPath);
|
|
4416
|
+
zipFolder.file(entry.name, content);
|
|
4417
|
+
}
|
|
4418
|
+
}
|
|
4419
|
+
}
|
|
4420
|
+
async function zipDirectory(distDir, zipPath) {
|
|
4421
|
+
console.error(`\u538B\u7F29\u76EE\u5F55: ${distDir}`);
|
|
4386
4422
|
const zip = new JSZip();
|
|
4387
4423
|
await addDirToZip(distDir, zip);
|
|
4388
4424
|
const content = await zip.generateAsync({
|
|
@@ -4395,6 +4431,65 @@ async function zipDirectory(distDir, zipPath) {
|
|
|
4395
4431
|
console.error(`\u5DF2\u751F\u6210: ${zipPath} (${sizeMb} MB)`);
|
|
4396
4432
|
return content.length;
|
|
4397
4433
|
}
|
|
4434
|
+
function resolveProjectNameForDeploy(cfg, cwd, options) {
|
|
4435
|
+
const name = (cfg.name ?? "").trim();
|
|
4436
|
+
if (options?.requireName && !name) {
|
|
4437
|
+
throw new DeployExecutionError(
|
|
4438
|
+
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09",
|
|
4439
|
+
1
|
|
4440
|
+
);
|
|
4441
|
+
}
|
|
4442
|
+
if (name) {
|
|
4443
|
+
return name;
|
|
4444
|
+
}
|
|
4445
|
+
return path3.basename(cwd);
|
|
4446
|
+
}
|
|
4447
|
+
function resolveArtifactNamePrefix(cfg) {
|
|
4448
|
+
const nameRaw = resolveProjectNameForDeploy(cfg, process.cwd(), {
|
|
4449
|
+
requireName: true
|
|
4450
|
+
});
|
|
4451
|
+
if (nameRaw.includes(":")) {
|
|
4452
|
+
throw new DeployExecutionError("apm.config.json \u7684 name \u4E0D\u80FD\u5305\u542B ':'", 1);
|
|
4453
|
+
}
|
|
4454
|
+
try {
|
|
4455
|
+
return sanitizeRelativePath(nameRaw.replace(/\\/g, "/"));
|
|
4456
|
+
} catch {
|
|
4457
|
+
throw new DeployExecutionError(
|
|
4458
|
+
"apm.config.json \u7684 name \u975E\u6CD5\uFF08\u8DEF\u5F84\u7247\u6BB5\u4E0D\u80FD\u4E3A . \u6216 ..\uFF09",
|
|
4459
|
+
1
|
|
4460
|
+
);
|
|
4461
|
+
}
|
|
4462
|
+
}
|
|
4463
|
+
async function packDirectoryWithMinioArchive(input) {
|
|
4464
|
+
const resolvedZipPath = path3.resolve(input.zipPath);
|
|
4465
|
+
let zipSizeBytes = 0;
|
|
4466
|
+
let artifactUploaded = false;
|
|
4467
|
+
try {
|
|
4468
|
+
zipSizeBytes = await zipDirectory(input.localDir, resolvedZipPath);
|
|
4469
|
+
if (input.skipMessage) {
|
|
4470
|
+
console.error(input.skipMessage);
|
|
4471
|
+
}
|
|
4472
|
+
const artifact = await uploadDeployArtifactZip({
|
|
4473
|
+
zipPath: resolvedZipPath,
|
|
4474
|
+
projectName: input.projectName,
|
|
4475
|
+
kind: input.kind,
|
|
4476
|
+
uploadWithoutRunId: input.uploadWithoutRunId
|
|
4477
|
+
});
|
|
4478
|
+
artifactUploaded = artifact !== null;
|
|
4479
|
+
if (artifactUploaded && input.successMessage) {
|
|
4480
|
+
console.error(input.successMessage);
|
|
4481
|
+
}
|
|
4482
|
+
return { zipSizeBytes, artifactUploaded };
|
|
4483
|
+
} finally {
|
|
4484
|
+
try {
|
|
4485
|
+
await unlink(resolvedZipPath);
|
|
4486
|
+
console.error(`\u5DF2\u6E05\u7406\u672C\u5730\u4E34\u65F6\u6587\u4EF6: ${resolvedZipPath}`);
|
|
4487
|
+
} catch {
|
|
4488
|
+
}
|
|
4489
|
+
}
|
|
4490
|
+
}
|
|
4491
|
+
|
|
4492
|
+
// src/commands/deploy/internal/wisdom-sftp.ts
|
|
4398
4493
|
var SFTP_UPLOAD_MAX_ATTEMPTS = 3;
|
|
4399
4494
|
var SFTP_FAST_PUT_OPTIONS = {
|
|
4400
4495
|
chunkSize: 64 * 1024,
|
|
@@ -4413,7 +4508,7 @@ function buildSftpConnectOptions(settings) {
|
|
|
4413
4508
|
};
|
|
4414
4509
|
}
|
|
4415
4510
|
async function sleep(ms) {
|
|
4416
|
-
await new Promise((
|
|
4511
|
+
await new Promise((resolve6) => setTimeout(resolve6, ms));
|
|
4417
4512
|
}
|
|
4418
4513
|
async function uploadZipWithRetry(settings, localZip, remoteZipPath) {
|
|
4419
4514
|
let lastError;
|
|
@@ -4457,7 +4552,7 @@ async function ensureRemoteDir(sftp, dir) {
|
|
|
4457
4552
|
}
|
|
4458
4553
|
}
|
|
4459
4554
|
function execCommand(client, command) {
|
|
4460
|
-
return new Promise((
|
|
4555
|
+
return new Promise((resolve6, reject) => {
|
|
4461
4556
|
client.exec(command, (err, stream) => {
|
|
4462
4557
|
if (err) return reject(err);
|
|
4463
4558
|
let stdout = "";
|
|
@@ -4467,7 +4562,7 @@ function execCommand(client, command) {
|
|
|
4467
4562
|
reject(new Error(`\u8FDC\u7A0B\u547D\u4EE4\u5931\u8D25 (${code}): ${stderr || stdout}`));
|
|
4468
4563
|
return;
|
|
4469
4564
|
}
|
|
4470
|
-
|
|
4565
|
+
resolve6(stdout);
|
|
4471
4566
|
}).on("data", (data) => {
|
|
4472
4567
|
stdout += data.toString();
|
|
4473
4568
|
});
|
|
@@ -4534,8 +4629,8 @@ function resolveDeployArtifactUpload(input) {
|
|
|
4534
4629
|
return { upload: false, uploadWithoutRunId: false };
|
|
4535
4630
|
}
|
|
4536
4631
|
async function runWisdomSftpDeploy(params) {
|
|
4537
|
-
const zipPath =
|
|
4538
|
-
const resolvedZipPath =
|
|
4632
|
+
const zipPath = path4.join(params.localDir, "..", ".deploy-sftp-dist.zip");
|
|
4633
|
+
const resolvedZipPath = path4.resolve(zipPath);
|
|
4539
4634
|
const packOnly = Boolean(params.packOnly);
|
|
4540
4635
|
const archiveDeployArtifact = Boolean(params.archiveDeployArtifact);
|
|
4541
4636
|
const deploymentRunId = resolveDeploymentRunIdFromEnv();
|
|
@@ -4546,38 +4641,44 @@ async function runWisdomSftpDeploy(params) {
|
|
|
4546
4641
|
});
|
|
4547
4642
|
let zipSizeBytes = 0;
|
|
4548
4643
|
let artifactUploaded = false;
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4644
|
+
if (packOnly && artifactUpload.upload) {
|
|
4645
|
+
const packed = await packDirectoryWithMinioArchive({
|
|
4646
|
+
localDir: params.localDir,
|
|
4647
|
+
zipPath: resolvedZipPath,
|
|
4648
|
+
projectName: params.projectName,
|
|
4649
|
+
kind: "frontend",
|
|
4650
|
+
uploadWithoutRunId: artifactUpload.uploadWithoutRunId,
|
|
4651
|
+
skipMessage: "[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7 SFTP \u8FDC\u7A0B\u4E0A\u4F20",
|
|
4652
|
+
successMessage: "\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09"
|
|
4653
|
+
});
|
|
4654
|
+
zipSizeBytes = packed.zipSizeBytes;
|
|
4655
|
+
artifactUploaded = packed.artifactUploaded;
|
|
4656
|
+
} else {
|
|
4657
|
+
try {
|
|
4658
|
+
zipSizeBytes = await zipDirectory(params.localDir, resolvedZipPath);
|
|
4552
4659
|
await uploadAndMaybeExtract(
|
|
4553
4660
|
params.settings,
|
|
4554
4661
|
resolvedZipPath,
|
|
4555
4662
|
params.extract
|
|
4556
4663
|
);
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
artifactUploaded = artifact !== null;
|
|
4568
|
-
}
|
|
4569
|
-
if (artifactUploaded) {
|
|
4570
|
-
if (packOnly) {
|
|
4571
|
-
console.error("\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09");
|
|
4572
|
-
} else {
|
|
4664
|
+
if (artifactUpload.upload) {
|
|
4665
|
+
const artifact = await uploadDeployArtifactZip({
|
|
4666
|
+
zipPath: resolvedZipPath,
|
|
4667
|
+
projectName: params.projectName,
|
|
4668
|
+
kind: "frontend",
|
|
4669
|
+
uploadWithoutRunId: artifactUpload.uploadWithoutRunId
|
|
4670
|
+
});
|
|
4671
|
+
artifactUploaded = artifact !== null;
|
|
4672
|
+
}
|
|
4673
|
+
if (artifactUploaded) {
|
|
4573
4674
|
console.error("[apm] SFTP \u90E8\u7F72\u5B8C\u6210\uFF0C\u90E8\u7F72\u4EA7\u7269\u5DF2\u5F52\u6863 MinIO");
|
|
4574
4675
|
}
|
|
4575
|
-
}
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
|
|
4579
|
-
|
|
4580
|
-
|
|
4676
|
+
} finally {
|
|
4677
|
+
try {
|
|
4678
|
+
await unlink2(resolvedZipPath);
|
|
4679
|
+
console.error(`\u5DF2\u6E05\u7406\u672C\u5730\u4E34\u65F6\u6587\u4EF6: ${resolvedZipPath}`);
|
|
4680
|
+
} catch {
|
|
4681
|
+
}
|
|
4581
4682
|
}
|
|
4582
4683
|
}
|
|
4583
4684
|
return {
|
|
@@ -4592,7 +4693,7 @@ async function runWisdomSftpDeploy(params) {
|
|
|
4592
4693
|
};
|
|
4593
4694
|
}
|
|
4594
4695
|
|
|
4595
|
-
// src/commands/deploy/internal/wisdom-backend-
|
|
4696
|
+
// src/commands/deploy/internal/wisdom-backend/internal-utils.ts
|
|
4596
4697
|
var SPRINGBOOT_JAVA_OPTS = "-XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -Xms512M -Xmx1G";
|
|
4597
4698
|
var MAVEN_MODULE = "jeecg-module-system/jeecg-system-start";
|
|
4598
4699
|
var MAVEN_PROFILE = "dev";
|
|
@@ -4605,11 +4706,11 @@ function log(message) {
|
|
|
4605
4706
|
}
|
|
4606
4707
|
function fail(message) {
|
|
4607
4708
|
log(`ERROR: ${message}`);
|
|
4608
|
-
|
|
4709
|
+
throw new DeployExecutionError(message, 1);
|
|
4609
4710
|
}
|
|
4610
4711
|
function expandPath(pathStr) {
|
|
4611
4712
|
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
4612
|
-
return
|
|
4713
|
+
return path5.resolve(pathStr.replace(/^~(?=\/|\\|$)/, home));
|
|
4613
4714
|
}
|
|
4614
4715
|
function quoteForShell(value) {
|
|
4615
4716
|
if (process.platform === "win32") {
|
|
@@ -4623,34 +4724,14 @@ function formatMavenLocalRepoArg(repoPath) {
|
|
|
4623
4724
|
}
|
|
4624
4725
|
return `-Dmaven.repo.local=${repoPath}`;
|
|
4625
4726
|
}
|
|
4626
|
-
function deployCacheDir() {
|
|
4627
|
-
return path3.join(workspaceApmDir(), "deploy", ".deploy_cache");
|
|
4628
|
-
}
|
|
4629
|
-
function manifestFilePath() {
|
|
4630
|
-
return path3.join(deployCacheDir(), "manifest.json");
|
|
4631
|
-
}
|
|
4632
4727
|
function getTargetDir(projectRoot) {
|
|
4633
|
-
return
|
|
4634
|
-
}
|
|
4635
|
-
function relativeKey(projectRoot, filePath) {
|
|
4636
|
-
return path3.relative(projectRoot, filePath).split(path3.sep).join("/");
|
|
4637
|
-
}
|
|
4638
|
-
function fileSignature(filePath) {
|
|
4639
|
-
const stat2 = statSync6(filePath);
|
|
4640
|
-
return { size: stat2.size, mtime: stat2.mtimeMs / 1e3 };
|
|
4641
|
-
}
|
|
4642
|
-
function loadManifest3() {
|
|
4643
|
-
const manifestPath2 = manifestFilePath();
|
|
4644
|
-
if (!existsSync15(manifestPath2)) {
|
|
4645
|
-
return {};
|
|
4646
|
-
}
|
|
4647
|
-
return JSON.parse(readFileSync12(manifestPath2, "utf8"));
|
|
4728
|
+
return path5.join(projectRoot, MAVEN_MODULE, "target");
|
|
4648
4729
|
}
|
|
4649
|
-
function
|
|
4650
|
-
|
|
4651
|
-
mkdirSync7(dir, { recursive: true });
|
|
4652
|
-
writeFileSync12(manifestFilePath(), JSON.stringify(manifest, null, 2), "utf8");
|
|
4730
|
+
function stripAnsi(text) {
|
|
4731
|
+
return text.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "");
|
|
4653
4732
|
}
|
|
4733
|
+
|
|
4734
|
+
// src/commands/deploy/internal/wisdom-backend/jar-incremental.ts
|
|
4654
4735
|
function isProjectLibJar(jarName) {
|
|
4655
4736
|
return jarName.startsWith("jeecg-");
|
|
4656
4737
|
}
|
|
@@ -4658,12 +4739,12 @@ function shouldUploadLibFile(localPath, remoteAttr, manifest, projectRoot) {
|
|
|
4658
4739
|
if (!remoteAttr) {
|
|
4659
4740
|
return [false, "\u8FDC\u7A0B\u4E0D\u5B58\u5728\uFF0C\u8DF3\u8FC7"];
|
|
4660
4741
|
}
|
|
4661
|
-
const localSize =
|
|
4742
|
+
const localSize = statSync7(localPath).size;
|
|
4662
4743
|
const remoteSize = remoteAttr.size;
|
|
4663
4744
|
if (localSize !== remoteSize) {
|
|
4664
4745
|
return [true, `\u5927\u5C0F\u53D8\u5316 ${remoteSize} -> ${localSize}`];
|
|
4665
4746
|
}
|
|
4666
|
-
if (isProjectLibJar(
|
|
4747
|
+
if (isProjectLibJar(path6.basename(localPath)) && manifest) {
|
|
4667
4748
|
const key = relativeKey(projectRoot, localPath);
|
|
4668
4749
|
const current = fileSignature(localPath);
|
|
4669
4750
|
const previous = manifest[key];
|
|
@@ -4683,7 +4764,7 @@ function listLibFilesToUpload(localLibDir, remoteStats, projectRoot, manifest =
|
|
|
4683
4764
|
const entries = [];
|
|
4684
4765
|
const jarFiles = readdirSync5(localLibDir).filter((name) => name.endsWith(".jar")).sort();
|
|
4685
4766
|
for (const jarName of jarFiles) {
|
|
4686
|
-
const jarPath =
|
|
4767
|
+
const jarPath = path6.join(localLibDir, jarName);
|
|
4687
4768
|
const remoteAttr = remoteStats.get(jarName);
|
|
4688
4769
|
const [shouldUpload, reason] = shouldUploadLibFile(
|
|
4689
4770
|
jarPath,
|
|
@@ -4697,20 +4778,14 @@ function listLibFilesToUpload(localLibDir, remoteStats, projectRoot, manifest =
|
|
|
4697
4778
|
}
|
|
4698
4779
|
return entries;
|
|
4699
4780
|
}
|
|
4700
|
-
function updateManifestEntries(manifest, entries, projectRoot) {
|
|
4701
|
-
for (const entry of entries) {
|
|
4702
|
-
manifest[relativeKey(projectRoot, entry.path)] = fileSignature(entry.path);
|
|
4703
|
-
}
|
|
4704
|
-
return manifest;
|
|
4705
|
-
}
|
|
4706
4781
|
async function createUpdatePackage(entries, packageName) {
|
|
4707
|
-
const dir =
|
|
4708
|
-
|
|
4709
|
-
const zipPath =
|
|
4710
|
-
log(`\u521B\u5EFA\u66F4\u65B0\u5305: ${
|
|
4782
|
+
const dir = deployCacheDirectory();
|
|
4783
|
+
mkdirSync8(dir, { recursive: true });
|
|
4784
|
+
const zipPath = path6.join(dir, packageName);
|
|
4785
|
+
log(`\u521B\u5EFA\u66F4\u65B0\u5305: ${path6.basename(zipPath)}\uFF08${entries.length} \u4E2A\u6587\u4EF6\uFF09`);
|
|
4711
4786
|
const zip = new JSZip2();
|
|
4712
4787
|
for (const entry of entries) {
|
|
4713
|
-
const content =
|
|
4788
|
+
const content = readFileSync14(entry.path);
|
|
4714
4789
|
zip.file(entry.arcname, content);
|
|
4715
4790
|
log(` \u6253\u5305: ${entry.arcname} (${entry.reason})`);
|
|
4716
4791
|
}
|
|
@@ -4719,9 +4794,21 @@ async function createUpdatePackage(entries, packageName) {
|
|
|
4719
4794
|
compression: "DEFLATE",
|
|
4720
4795
|
compressionOptions: { level: 6 }
|
|
4721
4796
|
});
|
|
4722
|
-
|
|
4797
|
+
writeFileSync13(zipPath, buffer);
|
|
4723
4798
|
return zipPath;
|
|
4724
4799
|
}
|
|
4800
|
+
function listAllLibFilesForArchive(libDir) {
|
|
4801
|
+
return readdirSync5(libDir).filter((name) => name.endsWith(".jar")).sort().map((jarName) => ({
|
|
4802
|
+
path: path6.join(libDir, jarName),
|
|
4803
|
+
arcname: jarName,
|
|
4804
|
+
reason: "\u4EC5\u6253\u5305\u5F52\u6863"
|
|
4805
|
+
}));
|
|
4806
|
+
}
|
|
4807
|
+
|
|
4808
|
+
// src/commands/deploy/internal/wisdom-backend/maven-build.ts
|
|
4809
|
+
import { existsSync as existsSync18, readdirSync as readdirSync6, statSync as statSync8 } from "node:fs";
|
|
4810
|
+
import path7 from "node:path";
|
|
4811
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
4725
4812
|
function getMvnExecutable() {
|
|
4726
4813
|
const isWin = process.platform === "win32";
|
|
4727
4814
|
const candidates = isWin ? ["mvn.cmd", "mvn.bat", "mvn"] : ["mvn"];
|
|
@@ -4768,14 +4855,14 @@ function runMavenBuild(projectRoot, mavenLocalRepo, repoSource) {
|
|
|
4768
4855
|
}
|
|
4769
4856
|
function locateLibDir(projectRoot) {
|
|
4770
4857
|
const targetDir = getTargetDir(projectRoot);
|
|
4771
|
-
if (!
|
|
4858
|
+
if (!existsSync18(targetDir)) {
|
|
4772
4859
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
4773
4860
|
}
|
|
4774
|
-
const libDir =
|
|
4775
|
-
if (!
|
|
4861
|
+
const libDir = path7.join(targetDir, "lib");
|
|
4862
|
+
if (!existsSync18(libDir) || !statSync8(libDir).isDirectory()) {
|
|
4776
4863
|
fail(`lib \u76EE\u5F55\u4E0D\u5B58\u5728: ${libDir}`);
|
|
4777
4864
|
}
|
|
4778
|
-
const libJars =
|
|
4865
|
+
const libJars = readdirSync6(libDir).filter((name) => name.endsWith(".jar"));
|
|
4779
4866
|
if (libJars.length === 0) {
|
|
4780
4867
|
fail(`lib \u76EE\u5F55\u4E0B\u6CA1\u6709\u4F9D\u8D56 JAR: ${libDir}`);
|
|
4781
4868
|
}
|
|
@@ -4784,124 +4871,24 @@ function locateLibDir(projectRoot) {
|
|
|
4784
4871
|
}
|
|
4785
4872
|
function locateMainJar(projectRoot) {
|
|
4786
4873
|
const targetDir = getTargetDir(projectRoot);
|
|
4787
|
-
if (!
|
|
4874
|
+
if (!existsSync18(targetDir)) {
|
|
4788
4875
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
4789
4876
|
}
|
|
4790
|
-
const jarFiles =
|
|
4877
|
+
const jarFiles = readdirSync6(targetDir).filter((name) => name.endsWith(".jar") && !name.endsWith(".jar.original")).map((name) => path7.join(targetDir, name)).sort((a, b) => statSync8(b).mtimeMs - statSync8(a).mtimeMs);
|
|
4791
4878
|
if (jarFiles.length === 0) {
|
|
4792
4879
|
fail(`target \u76EE\u5F55\u4E0B\u6CA1\u6709\u4E3B JAR: ${targetDir}`);
|
|
4793
4880
|
}
|
|
4794
4881
|
const mainJar = jarFiles[0];
|
|
4795
|
-
log(`\u5B9A\u4F4D\u4E3B JAR \u4EA7\u7269: ${
|
|
4882
|
+
log(`\u5B9A\u4F4D\u4E3B JAR \u4EA7\u7269: ${path7.basename(mainJar)}`);
|
|
4796
4883
|
return mainJar;
|
|
4797
4884
|
}
|
|
4798
|
-
|
|
4799
|
-
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
|
|
4805
|
-
username: config.username,
|
|
4806
|
-
password: config.password,
|
|
4807
|
-
readyTimeout: 3e4,
|
|
4808
|
-
tryKeyboard: true
|
|
4809
|
-
});
|
|
4810
|
-
});
|
|
4811
|
-
const sftp = new SftpClient2();
|
|
4812
|
-
await sftp.connect({
|
|
4813
|
-
host: config.host,
|
|
4814
|
-
port: config.port,
|
|
4815
|
-
username: config.username,
|
|
4816
|
-
password: config.password,
|
|
4817
|
-
readyTimeout: 3e4,
|
|
4818
|
-
tryKeyboard: true
|
|
4819
|
-
});
|
|
4820
|
-
return { client, sftp };
|
|
4821
|
-
}
|
|
4822
|
-
async function closeSsh(conn) {
|
|
4823
|
-
try {
|
|
4824
|
-
await conn.sftp.end();
|
|
4825
|
-
} catch {
|
|
4826
|
-
}
|
|
4827
|
-
conn.client.end();
|
|
4828
|
-
}
|
|
4829
|
-
async function getRemoteFileStats(sftp, remoteDir) {
|
|
4830
|
-
const stats = /* @__PURE__ */ new Map();
|
|
4831
|
-
try {
|
|
4832
|
-
const listing = await sftp.list(remoteDir);
|
|
4833
|
-
for (const item of listing) {
|
|
4834
|
-
if (item.name.endsWith(".jar")) {
|
|
4835
|
-
stats.set(item.name, { filename: item.name, size: item.size });
|
|
4836
|
-
}
|
|
4837
|
-
}
|
|
4838
|
-
} catch {
|
|
4839
|
-
}
|
|
4840
|
-
return stats;
|
|
4841
|
-
}
|
|
4842
|
-
async function uploadUpdatePackage(sftp, zipPath, config) {
|
|
4843
|
-
const remoteDir = config.remoteVueDistDir.replace(/\/$/, "");
|
|
4844
|
-
const remotePath = `${remoteDir}/${path3.basename(zipPath)}`;
|
|
4845
|
-
log(`\u4E0A\u4F20\u66F4\u65B0\u5305 -> ${remotePath}`);
|
|
4846
|
-
try {
|
|
4847
|
-
await sftp.fastPut(zipPath, remotePath);
|
|
4848
|
-
log("\u66F4\u65B0\u5305\u4E0A\u4F20\u6210\u529F");
|
|
4849
|
-
} catch (err) {
|
|
4850
|
-
fail(`\u66F4\u65B0\u5305\u4E0A\u4F20\u5931\u8D25: ${err instanceof Error ? err.message : err}`);
|
|
4851
|
-
}
|
|
4852
|
-
return remotePath;
|
|
4853
|
-
}
|
|
4854
|
-
async function uploadFullJar(sftp, localJarPath, config) {
|
|
4855
|
-
const remoteDir = config.remoteAppDir.replace(/\/$/, "");
|
|
4856
|
-
const remotePath = `${remoteDir}/${config.startupJar}`;
|
|
4857
|
-
log(`\u4E0A\u4F20\u5168\u91CF JAR (${path3.basename(localJarPath)}) -> ${remotePath}`);
|
|
4858
|
-
try {
|
|
4859
|
-
await sftp.mkdir(remoteDir, true);
|
|
4860
|
-
await sftp.fastPut(localJarPath, remotePath);
|
|
4861
|
-
log("\u5168\u91CF JAR \u4E0A\u4F20\u6210\u529F");
|
|
4862
|
-
} catch (err) {
|
|
4863
|
-
fail(`\u5168\u91CF JAR \u4E0A\u4F20\u5931\u8D25: ${err instanceof Error ? err.message : err}`);
|
|
4864
|
-
}
|
|
4865
|
-
}
|
|
4866
|
-
async function runRemoteCommand(client, command, options) {
|
|
4867
|
-
const check = options?.check ?? true;
|
|
4868
|
-
const stream = options?.stream ?? false;
|
|
4869
|
-
const label = options?.label ?? "\u8FDC\u7A0B\u547D\u4EE4";
|
|
4870
|
-
return new Promise((resolve5, reject) => {
|
|
4871
|
-
client.exec(command, (err, execStream) => {
|
|
4872
|
-
if (err) {
|
|
4873
|
-
reject(err);
|
|
4874
|
-
return;
|
|
4875
|
-
}
|
|
4876
|
-
let out = "";
|
|
4877
|
-
let errText = "";
|
|
4878
|
-
execStream.on("data", (data) => {
|
|
4879
|
-
const text = data.toString();
|
|
4880
|
-
out += text;
|
|
4881
|
-
if (stream) {
|
|
4882
|
-
process.stdout.write(text);
|
|
4883
|
-
}
|
|
4884
|
-
});
|
|
4885
|
-
execStream.stderr.on("data", (data) => {
|
|
4886
|
-
errText += data.toString();
|
|
4887
|
-
});
|
|
4888
|
-
execStream.on("close", (code) => {
|
|
4889
|
-
if (stream && out && !out.endsWith("\n")) {
|
|
4890
|
-
process.stdout.write("\n");
|
|
4891
|
-
}
|
|
4892
|
-
if (check && code !== 0) {
|
|
4893
|
-
const combined = `${out}
|
|
4894
|
-
${errText}`.trim();
|
|
4895
|
-
fail(
|
|
4896
|
-
`${label}\u5931\u8D25 (exit ${code})` + (combined ? `
|
|
4897
|
-
\u8F93\u51FA: ${combined}` : "")
|
|
4898
|
-
);
|
|
4899
|
-
}
|
|
4900
|
-
resolve5({ exitCode: code, out: out.trim(), err: errText.trim() });
|
|
4901
|
-
});
|
|
4902
|
-
});
|
|
4903
|
-
});
|
|
4904
|
-
}
|
|
4885
|
+
|
|
4886
|
+
// src/commands/deploy/internal/wisdom-backend/remote-deploy.ts
|
|
4887
|
+
import path8 from "node:path";
|
|
4888
|
+
import { Client as Client2 } from "ssh2";
|
|
4889
|
+
import SftpClient2 from "ssh2-sftp-client";
|
|
4890
|
+
|
|
4891
|
+
// src/commands/deploy/internal/wisdom-backend/remote-scripts.ts
|
|
4905
4892
|
function buildExtractUpdatePackageScript(remoteZipPath, remoteLibDir) {
|
|
4906
4893
|
const quotedZip = shellSingleQuote(remoteZipPath);
|
|
4907
4894
|
const quotedLib = shellSingleQuote(remoteLibDir);
|
|
@@ -4925,39 +4912,6 @@ done < <(find "$TMP" -name '*.jar' -type f -print0)
|
|
|
4925
4912
|
echo "UPDATED_COUNT=$updated"
|
|
4926
4913
|
`.trim();
|
|
4927
4914
|
}
|
|
4928
|
-
async function extractUpdatePackageOnRemote(client, config, remoteZipPath) {
|
|
4929
|
-
const script = buildExtractUpdatePackageScript(
|
|
4930
|
-
remoteZipPath,
|
|
4931
|
-
config.remoteLibDir
|
|
4932
|
-
);
|
|
4933
|
-
const { out } = await runRemoteCommand(client, script, {
|
|
4934
|
-
label: "\u8FDC\u7A0B\u89E3\u538B"
|
|
4935
|
-
});
|
|
4936
|
-
const match = out.match(/UPDATED_COUNT=(\d+)/);
|
|
4937
|
-
if (!match) {
|
|
4938
|
-
fail(`\u8FDC\u7A0B\u89E3\u538B\u5931\u8D25\uFF0C\u672A\u83B7\u53D6\u66F4\u65B0\u6570\u91CF
|
|
4939
|
-
\u8F93\u51FA: ${out || "(\u7A7A)"}`);
|
|
4940
|
-
}
|
|
4941
|
-
const updated = Number.parseInt(match[1], 10);
|
|
4942
|
-
log(`lib \u89E3\u538B\u5B8C\u6210: \u8986\u76D6 ${updated} \u4E2A`);
|
|
4943
|
-
return updated;
|
|
4944
|
-
}
|
|
4945
|
-
function springbootOutputIndicatesSuccess(action, combined) {
|
|
4946
|
-
const lower = combined.toLowerCase();
|
|
4947
|
-
if (action === "health") {
|
|
4948
|
-
return combined.includes("\u5065\u5EB7\u68C0\u67E5\u901A\u8FC7");
|
|
4949
|
-
}
|
|
4950
|
-
if (action === "start" || action === "restart") {
|
|
4951
|
-
return combined.includes("is starting") || lower.includes("is running");
|
|
4952
|
-
}
|
|
4953
|
-
if (action === "stop") {
|
|
4954
|
-
return combined.includes("is stopping") || lower.includes("not running") || lower.includes("please check it");
|
|
4955
|
-
}
|
|
4956
|
-
if (action === "status") {
|
|
4957
|
-
return lower.includes("running") || lower.includes("not running");
|
|
4958
|
-
}
|
|
4959
|
-
return true;
|
|
4960
|
-
}
|
|
4961
4915
|
function buildRemoteStatusScript(remoteAppDir, appName) {
|
|
4962
4916
|
const dir = shellSingleQuote(remoteAppDir);
|
|
4963
4917
|
const jar = shellSingleQuote(appName);
|
|
@@ -5056,6 +5010,150 @@ echo -e "\\033[31m\u5065\u5EB7\u68C0\u67E5\u8D85\u65F6 (\${timeout}s): \${check_
|
|
|
5056
5010
|
exit 1
|
|
5057
5011
|
`.trim();
|
|
5058
5012
|
}
|
|
5013
|
+
function springbootOutputIndicatesSuccess(action, combined) {
|
|
5014
|
+
const lower = combined.toLowerCase();
|
|
5015
|
+
if (action === "health") {
|
|
5016
|
+
return combined.includes("\u5065\u5EB7\u68C0\u67E5\u901A\u8FC7");
|
|
5017
|
+
}
|
|
5018
|
+
if (action === "start" || action === "restart") {
|
|
5019
|
+
return combined.includes("is starting") || lower.includes("is running");
|
|
5020
|
+
}
|
|
5021
|
+
if (action === "stop") {
|
|
5022
|
+
return combined.includes("is stopping") || lower.includes("not running") || lower.includes("please check it");
|
|
5023
|
+
}
|
|
5024
|
+
if (action === "status") {
|
|
5025
|
+
return lower.includes("running") || lower.includes("not running");
|
|
5026
|
+
}
|
|
5027
|
+
return true;
|
|
5028
|
+
}
|
|
5029
|
+
|
|
5030
|
+
// src/commands/deploy/internal/wisdom-backend/remote-deploy.ts
|
|
5031
|
+
async function connectSsh(config) {
|
|
5032
|
+
const client = new Client2();
|
|
5033
|
+
log(`\u8FDE\u63A5\u670D\u52A1\u5668 ${config.username}@${config.host}:${config.port}`);
|
|
5034
|
+
await new Promise((resolve6, reject) => {
|
|
5035
|
+
client.on("ready", () => resolve6()).on("error", (err) => reject(err)).connect({
|
|
5036
|
+
host: config.host,
|
|
5037
|
+
port: config.port,
|
|
5038
|
+
username: config.username,
|
|
5039
|
+
password: config.password,
|
|
5040
|
+
readyTimeout: 3e4,
|
|
5041
|
+
tryKeyboard: true
|
|
5042
|
+
});
|
|
5043
|
+
});
|
|
5044
|
+
const sftp = new SftpClient2();
|
|
5045
|
+
await sftp.connect({
|
|
5046
|
+
host: config.host,
|
|
5047
|
+
port: config.port,
|
|
5048
|
+
username: config.username,
|
|
5049
|
+
password: config.password,
|
|
5050
|
+
readyTimeout: 3e4,
|
|
5051
|
+
tryKeyboard: true
|
|
5052
|
+
});
|
|
5053
|
+
return { client, sftp };
|
|
5054
|
+
}
|
|
5055
|
+
async function closeSsh(conn) {
|
|
5056
|
+
try {
|
|
5057
|
+
await conn.sftp.end();
|
|
5058
|
+
} catch {
|
|
5059
|
+
}
|
|
5060
|
+
conn.client.end();
|
|
5061
|
+
}
|
|
5062
|
+
async function getRemoteFileStats(sftp, remoteDir) {
|
|
5063
|
+
const stats = /* @__PURE__ */ new Map();
|
|
5064
|
+
try {
|
|
5065
|
+
const listing = await sftp.list(remoteDir);
|
|
5066
|
+
for (const item of listing) {
|
|
5067
|
+
if (item.name.endsWith(".jar")) {
|
|
5068
|
+
stats.set(item.name, { filename: item.name, size: item.size });
|
|
5069
|
+
}
|
|
5070
|
+
}
|
|
5071
|
+
} catch {
|
|
5072
|
+
}
|
|
5073
|
+
return stats;
|
|
5074
|
+
}
|
|
5075
|
+
async function uploadUpdatePackage(sftp, zipPath, config) {
|
|
5076
|
+
const remoteDir = config.remoteVueDistDir.replace(/\/$/, "");
|
|
5077
|
+
const remotePath = `${remoteDir}/${path8.basename(zipPath)}`;
|
|
5078
|
+
log(`\u4E0A\u4F20\u66F4\u65B0\u5305 -> ${remotePath}`);
|
|
5079
|
+
try {
|
|
5080
|
+
await sftp.fastPut(zipPath, remotePath);
|
|
5081
|
+
log("\u66F4\u65B0\u5305\u4E0A\u4F20\u6210\u529F");
|
|
5082
|
+
} catch (err) {
|
|
5083
|
+
fail(`\u66F4\u65B0\u5305\u4E0A\u4F20\u5931\u8D25: ${err instanceof Error ? err.message : err}`);
|
|
5084
|
+
}
|
|
5085
|
+
return remotePath;
|
|
5086
|
+
}
|
|
5087
|
+
async function uploadFullJar(sftp, localJarPath, config) {
|
|
5088
|
+
const remoteDir = config.remoteAppDir.replace(/\/$/, "");
|
|
5089
|
+
const remotePath = `${remoteDir}/${config.startupJar}`;
|
|
5090
|
+
log(`\u4E0A\u4F20\u5168\u91CF JAR (${path8.basename(localJarPath)}) -> ${remotePath}`);
|
|
5091
|
+
try {
|
|
5092
|
+
await sftp.mkdir(remoteDir, true);
|
|
5093
|
+
await sftp.fastPut(localJarPath, remotePath);
|
|
5094
|
+
log("\u5168\u91CF JAR \u4E0A\u4F20\u6210\u529F");
|
|
5095
|
+
} catch (err) {
|
|
5096
|
+
fail(`\u5168\u91CF JAR \u4E0A\u4F20\u5931\u8D25: ${err instanceof Error ? err.message : err}`);
|
|
5097
|
+
}
|
|
5098
|
+
}
|
|
5099
|
+
async function runRemoteCommand(client, command, options) {
|
|
5100
|
+
const check = options?.check ?? true;
|
|
5101
|
+
const stream = options?.stream ?? false;
|
|
5102
|
+
const label = options?.label ?? "\u8FDC\u7A0B\u547D\u4EE4";
|
|
5103
|
+
return new Promise((resolve6, reject) => {
|
|
5104
|
+
client.exec(command, (err, execStream) => {
|
|
5105
|
+
if (err) {
|
|
5106
|
+
reject(err);
|
|
5107
|
+
return;
|
|
5108
|
+
}
|
|
5109
|
+
let out = "";
|
|
5110
|
+
let errText = "";
|
|
5111
|
+
execStream.on("data", (data) => {
|
|
5112
|
+
const text = data.toString();
|
|
5113
|
+
out += text;
|
|
5114
|
+
if (stream) {
|
|
5115
|
+
process.stdout.write(text);
|
|
5116
|
+
}
|
|
5117
|
+
});
|
|
5118
|
+
execStream.stderr.on("data", (data) => {
|
|
5119
|
+
errText += data.toString();
|
|
5120
|
+
});
|
|
5121
|
+
execStream.on("close", (code) => {
|
|
5122
|
+
if (stream && out && !out.endsWith("\n")) {
|
|
5123
|
+
process.stdout.write("\n");
|
|
5124
|
+
}
|
|
5125
|
+
if (check && code !== 0) {
|
|
5126
|
+
const combined = `${out}
|
|
5127
|
+
${errText}`.trim();
|
|
5128
|
+
fail(
|
|
5129
|
+
`${label}\u5931\u8D25 (exit ${code})` + (combined ? `
|
|
5130
|
+
\u8F93\u51FA: ${combined}` : "")
|
|
5131
|
+
);
|
|
5132
|
+
}
|
|
5133
|
+
resolve6({ exitCode: code, out: out.trim(), err: errText.trim() });
|
|
5134
|
+
});
|
|
5135
|
+
});
|
|
5136
|
+
});
|
|
5137
|
+
}
|
|
5138
|
+
async function extractUpdatePackageOnRemote(client, config, remoteZipPath) {
|
|
5139
|
+
const script = buildExtractUpdatePackageScript(
|
|
5140
|
+
remoteZipPath,
|
|
5141
|
+
config.remoteLibDir
|
|
5142
|
+
);
|
|
5143
|
+
const { out } = await runRemoteCommand(client, script, {
|
|
5144
|
+
label: "\u8FDC\u7A0B\u89E3\u538B"
|
|
5145
|
+
});
|
|
5146
|
+
const match = out.match(/UPDATED_COUNT=(\d+)/);
|
|
5147
|
+
if (!match) {
|
|
5148
|
+
fail(`\u8FDC\u7A0B\u89E3\u538B\u5931\u8D25\uFF0C\u672A\u83B7\u53D6\u66F4\u65B0\u6570\u91CF
|
|
5149
|
+
\u8F93\u51FA: ${out || "(\u7A7A)"}`);
|
|
5150
|
+
}
|
|
5151
|
+
const updated = Number.parseInt(match[1], 10);
|
|
5152
|
+
log(`lib \u89E3\u538B\u5B8C\u6210: \u8986\u76D6 ${updated} \u4E2A`);
|
|
5153
|
+
return updated;
|
|
5154
|
+
}
|
|
5155
|
+
|
|
5156
|
+
// src/commands/deploy/internal/wisdom-backend/health-check.ts
|
|
5059
5157
|
async function runRemoteServiceScript(client, script, action) {
|
|
5060
5158
|
const { exitCode, out, err } = await runRemoteCommand(client, script, {
|
|
5061
5159
|
check: false,
|
|
@@ -5081,9 +5179,6 @@ ${combined}`);
|
|
|
5081
5179
|
}
|
|
5082
5180
|
return combined;
|
|
5083
5181
|
}
|
|
5084
|
-
function stripAnsi(text) {
|
|
5085
|
-
return text.replace(/\x1b\[[0-?]*[ -/]*[@-~]/g, "");
|
|
5086
|
-
}
|
|
5087
5182
|
async function getRunningJar(client, config) {
|
|
5088
5183
|
const script = buildRemoteStatusScript(
|
|
5089
5184
|
config.remoteAppDir,
|
|
@@ -5112,19 +5207,14 @@ async function restartRemoteService(client, config) {
|
|
|
5112
5207
|
const script = buildRemoteRestartScript(config.remoteAppDir);
|
|
5113
5208
|
await runRemoteServiceScript(client, script, "restart");
|
|
5114
5209
|
}
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
path: path3.join(libDir, jarName),
|
|
5118
|
-
arcname: jarName,
|
|
5119
|
-
reason: "\u4EC5\u6253\u5305\u5F52\u6863"
|
|
5120
|
-
}));
|
|
5121
|
-
}
|
|
5210
|
+
|
|
5211
|
+
// src/commands/deploy/internal/wisdom-backend/index.ts
|
|
5122
5212
|
async function runWisdomBackendDeploy(options) {
|
|
5123
|
-
const projectRoot =
|
|
5213
|
+
const projectRoot = path9.resolve(options.projectRoot ?? process.cwd());
|
|
5124
5214
|
const config = options.config;
|
|
5125
5215
|
const packOnly = Boolean(options.packOnly);
|
|
5126
5216
|
log(`=== \u81EA\u52A8\u90E8\u7F72: ${config.projectName} ===`);
|
|
5127
|
-
log(`\u914D\u7F6E\u6587\u4EF6: ${
|
|
5217
|
+
log(`\u914D\u7F6E\u6587\u4EF6: ${path9.join(workspaceApmDir(), "apm.config.json")}`);
|
|
5128
5218
|
log(`\u9879\u76EE\u6839\u76EE\u5F55: ${projectRoot}`);
|
|
5129
5219
|
log(
|
|
5130
5220
|
`\u90E8\u7F72\u6A21\u5F0F: ${config.mode}${config.mode === "full" ? "\uFF08\u5168\u91CF JAR\uFF0C\u8DF3\u8FC7 lib \u68C0\u67E5\uFF09" : "\uFF08\u589E\u91CF lib \u66F4\u65B0\uFF09"}${packOnly ? "\uFF1B\u4EC5\u6253\u5305\uFF08\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\uFF09" : ""}`
|
|
@@ -5141,7 +5231,7 @@ async function runWisdomBackendDeploy(options) {
|
|
|
5141
5231
|
[
|
|
5142
5232
|
{
|
|
5143
5233
|
path: mainJar,
|
|
5144
|
-
arcname:
|
|
5234
|
+
arcname: path9.basename(mainJar),
|
|
5145
5235
|
reason: "\u5168\u91CF JAR \u5F52\u6863"
|
|
5146
5236
|
}
|
|
5147
5237
|
],
|
|
@@ -5179,7 +5269,7 @@ async function runWisdomBackendDeploy(options) {
|
|
|
5179
5269
|
[
|
|
5180
5270
|
{
|
|
5181
5271
|
path: mainJar,
|
|
5182
|
-
arcname:
|
|
5272
|
+
arcname: path9.basename(mainJar),
|
|
5183
5273
|
reason: "\u5168\u91CF JAR \u5F52\u6863"
|
|
5184
5274
|
}
|
|
5185
5275
|
],
|
|
@@ -5263,15 +5353,15 @@ function isWisdomDeployConfigured(cfg) {
|
|
|
5263
5353
|
return Boolean(w?.host?.trim() && w?.remotePath?.trim());
|
|
5264
5354
|
}
|
|
5265
5355
|
function detectWisdomProjectType(cwd) {
|
|
5266
|
-
return
|
|
5356
|
+
return existsSync19(path10.join(cwd, "package.json")) ? "frontend" : "backend";
|
|
5267
5357
|
}
|
|
5268
5358
|
function readPackageScripts(cwd) {
|
|
5269
|
-
const pkgPath =
|
|
5270
|
-
if (!
|
|
5359
|
+
const pkgPath = path10.join(cwd, "package.json");
|
|
5360
|
+
if (!existsSync19(pkgPath)) {
|
|
5271
5361
|
return {};
|
|
5272
5362
|
}
|
|
5273
5363
|
try {
|
|
5274
|
-
const raw =
|
|
5364
|
+
const raw = readFileSync15(pkgPath, "utf8");
|
|
5275
5365
|
const parsed = JSON.parse(raw);
|
|
5276
5366
|
return parsed.scripts ?? {};
|
|
5277
5367
|
} catch {
|
|
@@ -5284,20 +5374,23 @@ function resolveFrontendBuildCommand(env, cwd) {
|
|
|
5284
5374
|
if (scripts[buildKey]?.trim()) {
|
|
5285
5375
|
return `npm run build:${env}`;
|
|
5286
5376
|
}
|
|
5377
|
+
if (isProductionDeployEnv(env) && scripts.build?.trim()) {
|
|
5378
|
+
return "npm run build";
|
|
5379
|
+
}
|
|
5287
5380
|
return null;
|
|
5288
5381
|
}
|
|
5289
5382
|
function resolveFrontendDistDir(cwd) {
|
|
5290
5383
|
const candidates = ["dist", "apps/web/dist"];
|
|
5291
5384
|
for (const rel of candidates) {
|
|
5292
|
-
const full =
|
|
5385
|
+
const full = path10.join(cwd, rel);
|
|
5293
5386
|
try {
|
|
5294
|
-
if (
|
|
5387
|
+
if (existsSync19(full) && statSync9(full).isDirectory()) {
|
|
5295
5388
|
return full;
|
|
5296
5389
|
}
|
|
5297
5390
|
} catch {
|
|
5298
5391
|
}
|
|
5299
5392
|
}
|
|
5300
|
-
return
|
|
5393
|
+
return path10.join(cwd, "dist");
|
|
5301
5394
|
}
|
|
5302
5395
|
async function executeWisdomFrontendDeploy(options) {
|
|
5303
5396
|
const { cwd, cfg, captureOutput, packOnly, archiveDeployArtifact } = options;
|
|
@@ -5314,7 +5407,7 @@ async function executeWisdomFrontendDeploy(options) {
|
|
|
5314
5407
|
if (!buildCmd) {
|
|
5315
5408
|
const lines = formatWisdomFrontendBuildNotConfiguredLines(
|
|
5316
5409
|
options.env,
|
|
5317
|
-
|
|
5410
|
+
path10.join(cwd, "package.json")
|
|
5318
5411
|
);
|
|
5319
5412
|
throw new DeployExecutionError(lines.join("\n"), 1, lines.join("\n"));
|
|
5320
5413
|
}
|
|
@@ -5322,16 +5415,9 @@ async function executeWisdomFrontendDeploy(options) {
|
|
|
5322
5415
|
`[apm] Vue\uFF1A${buildCmd}` + (packOnly ? "\uFF08\u4EC5\u6253\u5305\uFF0C\u8DF3\u8FC7 SFTP\uFF09" : " \u2192 SFTP \u4E0A\u4F20\u5E76\u8FDC\u7A0B\u89E3\u538B" + (archiveDeployArtifact ? " \u2192 \u5E73\u53F0\u90E8\u7F72\u4EA7\u7269\u5F52\u6863" : ""))
|
|
5323
5416
|
);
|
|
5324
5417
|
runDeployShellCommand(buildCmd, cwd, captureOutput);
|
|
5325
|
-
|
|
5326
|
-
|
|
5327
|
-
|
|
5328
|
-
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09",
|
|
5329
|
-
1
|
|
5330
|
-
);
|
|
5331
|
-
}
|
|
5332
|
-
if (!projectName) {
|
|
5333
|
-
projectName = path4.basename(cwd);
|
|
5334
|
-
}
|
|
5418
|
+
const projectName = resolveProjectNameForDeploy(cfg, cwd, {
|
|
5419
|
+
requireName: packOnly || archiveDeployArtifact
|
|
5420
|
+
});
|
|
5335
5421
|
const settings = resolveWisdomDeployFromApmConfig(cfg);
|
|
5336
5422
|
await runWisdomSftpDeploy({
|
|
5337
5423
|
localDir: distDir,
|
|
@@ -5359,12 +5445,12 @@ async function executeWisdomBackendDeployFlow(options) {
|
|
|
5359
5445
|
});
|
|
5360
5446
|
}
|
|
5361
5447
|
async function executeWisdomDeploy(options) {
|
|
5362
|
-
const cwd =
|
|
5448
|
+
const cwd = path10.resolve(options.cwd);
|
|
5363
5449
|
const captureOutput = options.captureOutput ?? false;
|
|
5364
5450
|
const packOnly = Boolean(options.packOnly);
|
|
5365
5451
|
const archiveDeployArtifact = Boolean(options.archiveDeployArtifact);
|
|
5366
5452
|
const projectType = detectWisdomProjectType(cwd);
|
|
5367
|
-
const configPath = options.configPath ??
|
|
5453
|
+
const configPath = options.configPath ?? path10.join(workspaceApmDir(cwd), "apm.config.json");
|
|
5368
5454
|
const cfg = loadApmConfig({ configPath });
|
|
5369
5455
|
console.error(
|
|
5370
5456
|
`[apm] ${projectType === "frontend" ? "Vue \u524D\u7AEF" : "Java \u540E\u7AEF"}${packOnly ? "\uFF08\u4EC5\u6253\u5305\uFF09" : ""}`
|
|
@@ -5527,7 +5613,7 @@ async function executeDeploy(options) {
|
|
|
5527
5613
|
throw new DeployExecutionError("[apm] executeDeploy \u7F3A\u5C11\u5DE5\u4F5C\u76EE\u5F55 cwd", 1);
|
|
5528
5614
|
}
|
|
5529
5615
|
const cwd = resolveWorkdirPath(cwdInput);
|
|
5530
|
-
const apmConfigPath = options.configPath ??
|
|
5616
|
+
const apmConfigPath = options.configPath ?? path11.join(workspaceApmDir(cwd), "apm.config.json");
|
|
5531
5617
|
const captureOutput = options.captureOutput ?? false;
|
|
5532
5618
|
const outputParts = [];
|
|
5533
5619
|
logExecuteDeployContext({
|
|
@@ -5596,11 +5682,36 @@ function printDeployExecutionError(error) {
|
|
|
5596
5682
|
console.error(error.message);
|
|
5597
5683
|
}
|
|
5598
5684
|
|
|
5599
|
-
// src/commands/
|
|
5600
|
-
|
|
5601
|
-
|
|
5602
|
-
|
|
5685
|
+
// src/commands/deploy/platform/deploy-console-capture.ts
|
|
5686
|
+
function captureDeployConsole(logSyncer) {
|
|
5687
|
+
const chunks = [];
|
|
5688
|
+
const appendLog = (line) => {
|
|
5689
|
+
if (!line) return;
|
|
5690
|
+
chunks.push(line);
|
|
5691
|
+
logSyncer.updateLog(chunks.join("\n"));
|
|
5692
|
+
};
|
|
5693
|
+
const originalLog = console.log;
|
|
5694
|
+
const originalError = console.error;
|
|
5695
|
+
console.log = (...args) => {
|
|
5696
|
+
appendLog(args.map(String).join(" "));
|
|
5697
|
+
originalLog.apply(console, args);
|
|
5698
|
+
};
|
|
5699
|
+
console.error = (...args) => {
|
|
5700
|
+
appendLog(args.map(String).join(" "));
|
|
5701
|
+
originalError.apply(console, args);
|
|
5702
|
+
};
|
|
5703
|
+
return {
|
|
5704
|
+
appendLog,
|
|
5705
|
+
restore: () => {
|
|
5706
|
+
console.log = originalLog;
|
|
5707
|
+
console.error = originalError;
|
|
5708
|
+
},
|
|
5709
|
+
getLog: () => chunks.join("\n")
|
|
5710
|
+
};
|
|
5603
5711
|
}
|
|
5712
|
+
|
|
5713
|
+
// src/commands/deploy/platform/deploy-log-syncer.ts
|
|
5714
|
+
var DEPLOY_LOG_SYNC_INTERVAL_MS = 1e4;
|
|
5604
5715
|
function logDeploySyncFailure(error) {
|
|
5605
5716
|
console.error(
|
|
5606
5717
|
"[apm] deploy log sync failed:",
|
|
@@ -5610,7 +5721,9 @@ function logDeploySyncFailure(error) {
|
|
|
5610
5721
|
function createDeployLogSyncer(api, deploymentRunId) {
|
|
5611
5722
|
let lastSyncedLog = "";
|
|
5612
5723
|
let latestLog = "";
|
|
5613
|
-
let
|
|
5724
|
+
let lastRunAt = 0;
|
|
5725
|
+
let timer;
|
|
5726
|
+
let syncChain = Promise.resolve();
|
|
5614
5727
|
const syncDelta = async (delta, append) => {
|
|
5615
5728
|
const chunks = splitUtf8StringByMaxBytes(
|
|
5616
5729
|
delta,
|
|
@@ -5635,29 +5748,58 @@ function createDeployLogSyncer(api, deploymentRunId) {
|
|
|
5635
5748
|
if (!delta) {
|
|
5636
5749
|
return;
|
|
5637
5750
|
}
|
|
5638
|
-
await syncDelta(delta, lastSyncedLog.length > 0);
|
|
5639
|
-
lastSyncedLog = latestLog;
|
|
5751
|
+
await syncDelta(delta, lastSyncedLog.length > 0);
|
|
5752
|
+
lastSyncedLog = latestLog;
|
|
5753
|
+
};
|
|
5754
|
+
const enqueueSync = () => {
|
|
5755
|
+
syncChain = syncChain.then(async () => {
|
|
5756
|
+
try {
|
|
5757
|
+
await syncIfChanged();
|
|
5758
|
+
lastRunAt = Date.now();
|
|
5759
|
+
} catch (error) {
|
|
5760
|
+
logDeploySyncFailure(error);
|
|
5761
|
+
}
|
|
5762
|
+
});
|
|
5763
|
+
};
|
|
5764
|
+
const schedule = () => {
|
|
5765
|
+
const now = Date.now();
|
|
5766
|
+
const elapsed = now - lastRunAt;
|
|
5767
|
+
if (elapsed >= DEPLOY_LOG_SYNC_INTERVAL_MS) {
|
|
5768
|
+
if (timer) {
|
|
5769
|
+
clearTimeout(timer);
|
|
5770
|
+
timer = void 0;
|
|
5771
|
+
}
|
|
5772
|
+
enqueueSync();
|
|
5773
|
+
return;
|
|
5774
|
+
}
|
|
5775
|
+
if (timer) {
|
|
5776
|
+
return;
|
|
5777
|
+
}
|
|
5778
|
+
timer = setTimeout(() => {
|
|
5779
|
+
timer = void 0;
|
|
5780
|
+
enqueueSync();
|
|
5781
|
+
}, DEPLOY_LOG_SYNC_INTERVAL_MS - elapsed);
|
|
5782
|
+
};
|
|
5783
|
+
const stopTimer = () => {
|
|
5784
|
+
if (timer) {
|
|
5785
|
+
clearTimeout(timer);
|
|
5786
|
+
timer = void 0;
|
|
5787
|
+
}
|
|
5640
5788
|
};
|
|
5641
|
-
timer = setInterval(() => {
|
|
5642
|
-
void syncIfChanged().catch(logDeploySyncFailure);
|
|
5643
|
-
}, DEPLOY_LOG_SYNC_INTERVAL_MS);
|
|
5644
5789
|
return {
|
|
5645
5790
|
updateLog(log2) {
|
|
5646
5791
|
latestLog = log2;
|
|
5792
|
+
schedule();
|
|
5647
5793
|
},
|
|
5648
5794
|
async flush() {
|
|
5649
|
-
|
|
5650
|
-
|
|
5651
|
-
timer = null;
|
|
5652
|
-
}
|
|
5795
|
+
stopTimer();
|
|
5796
|
+
await syncChain;
|
|
5653
5797
|
await syncIfChanged();
|
|
5654
5798
|
},
|
|
5655
5799
|
async flushSafe() {
|
|
5656
|
-
|
|
5657
|
-
clearInterval(timer);
|
|
5658
|
-
timer = null;
|
|
5659
|
-
}
|
|
5800
|
+
stopTimer();
|
|
5660
5801
|
try {
|
|
5802
|
+
await syncChain;
|
|
5661
5803
|
await syncIfChanged();
|
|
5662
5804
|
return true;
|
|
5663
5805
|
} catch (error) {
|
|
@@ -5666,15 +5808,12 @@ function createDeployLogSyncer(api, deploymentRunId) {
|
|
|
5666
5808
|
}
|
|
5667
5809
|
},
|
|
5668
5810
|
dispose() {
|
|
5669
|
-
|
|
5670
|
-
clearInterval(timer);
|
|
5671
|
-
timer = null;
|
|
5672
|
-
}
|
|
5811
|
+
stopTimer();
|
|
5673
5812
|
}
|
|
5674
5813
|
};
|
|
5675
5814
|
}
|
|
5676
5815
|
async function finalizeTaskDeployment(api, deploymentRunId, logSyncer, input) {
|
|
5677
|
-
|
|
5816
|
+
await logSyncer.flushSafe();
|
|
5678
5817
|
const payload = {
|
|
5679
5818
|
id: deploymentRunId,
|
|
5680
5819
|
status: input.status
|
|
@@ -5682,76 +5821,48 @@ async function finalizeTaskDeployment(api, deploymentRunId, logSyncer, input) {
|
|
|
5682
5821
|
if (input.error) {
|
|
5683
5822
|
payload.error = input.error;
|
|
5684
5823
|
}
|
|
5685
|
-
|
|
5686
|
-
|
|
5687
|
-
|
|
5688
|
-
await retryDeployLogSync(() => api.cli.completeTaskDeployment(payload));
|
|
5824
|
+
await retryDeployStatusComplete(
|
|
5825
|
+
() => api.cli.completeTaskDeployment(payload)
|
|
5826
|
+
);
|
|
5689
5827
|
}
|
|
5690
|
-
function
|
|
5691
|
-
|
|
5692
|
-
const appendLog = (line) => {
|
|
5693
|
-
if (!line) return;
|
|
5694
|
-
chunks.push(line);
|
|
5695
|
-
logSyncer.updateLog(chunks.join("\n"));
|
|
5696
|
-
};
|
|
5697
|
-
const originalLog = console.log;
|
|
5698
|
-
const originalError = console.error;
|
|
5699
|
-
console.log = (...args) => {
|
|
5700
|
-
appendLog(args.map(String).join(" "));
|
|
5701
|
-
originalLog.apply(console, args);
|
|
5702
|
-
};
|
|
5703
|
-
console.error = (...args) => {
|
|
5704
|
-
appendLog(args.map(String).join(" "));
|
|
5705
|
-
originalError.apply(console, args);
|
|
5706
|
-
};
|
|
5707
|
-
return {
|
|
5708
|
-
appendLog,
|
|
5709
|
-
restore: () => {
|
|
5710
|
-
console.log = originalLog;
|
|
5711
|
-
console.error = originalError;
|
|
5712
|
-
},
|
|
5713
|
-
getLog: () => chunks.join("\n")
|
|
5714
|
-
};
|
|
5828
|
+
async function ensureDeploymentStatusSynced(api, deploymentRunId, logSyncer, outcome) {
|
|
5829
|
+
await finalizeTaskDeployment(api, deploymentRunId, logSyncer, outcome);
|
|
5715
5830
|
}
|
|
5716
|
-
|
|
5717
|
-
|
|
5718
|
-
|
|
5719
|
-
|
|
5720
|
-
|
|
5721
|
-
|
|
5722
|
-
status: "DEPLOYING"
|
|
5723
|
-
});
|
|
5724
|
-
const workdir = requireRemoteWorkdir(msg.workdir);
|
|
5725
|
-
const displayCommand = resolveDeployCommand(msg.environment, msg.packOnly);
|
|
5726
|
-
console.log(
|
|
5727
|
-
`[apm] deploy start id=${deploymentRunId} env=${msg.environment} cwd=${workdir}`
|
|
5831
|
+
|
|
5832
|
+
// src/commands/deploy/platform/deploy-run-coordinator.ts
|
|
5833
|
+
function logDeployStatusSyncFailure(error) {
|
|
5834
|
+
console.error(
|
|
5835
|
+
"[apm] deploy status sync failed:",
|
|
5836
|
+
error instanceof Error ? error.message : String(error)
|
|
5728
5837
|
);
|
|
5729
|
-
|
|
5838
|
+
}
|
|
5839
|
+
async function runTrackedDeploy(input) {
|
|
5840
|
+
const { api, deploymentRunId, run } = input;
|
|
5841
|
+
let deploymentStarted = true;
|
|
5842
|
+
let outcome = null;
|
|
5843
|
+
let statusSynced = false;
|
|
5844
|
+
let deployError;
|
|
5730
5845
|
const logSyncer = createDeployLogSyncer(api, deploymentRunId);
|
|
5731
5846
|
const previousDeploymentRunId = process.env[APM_DEPLOYMENT_RUN_ID_ENV];
|
|
5732
5847
|
process.env[APM_DEPLOYMENT_RUN_ID_ENV] = deploymentRunId;
|
|
5733
5848
|
const capture = captureDeployConsole(logSyncer);
|
|
5734
|
-
const
|
|
5735
|
-
|
|
5736
|
-
|
|
5737
|
-
|
|
5738
|
-
|
|
5739
|
-
|
|
5740
|
-
|
|
5849
|
+
const ensureStatusSynced = async () => {
|
|
5850
|
+
if (statusSynced || !outcome) {
|
|
5851
|
+
return;
|
|
5852
|
+
}
|
|
5853
|
+
logSyncer.updateLog(capture.getLog());
|
|
5854
|
+
await ensureDeploymentStatusSynced(
|
|
5855
|
+
api,
|
|
5856
|
+
deploymentRunId,
|
|
5857
|
+
logSyncer,
|
|
5858
|
+
outcome
|
|
5859
|
+
);
|
|
5860
|
+
statusSynced = true;
|
|
5741
5861
|
};
|
|
5742
5862
|
try {
|
|
5743
|
-
|
|
5744
|
-
const output = await executeDeploy(deployOptions);
|
|
5745
|
-
if (output.trim()) {
|
|
5746
|
-
capture.appendLog(output);
|
|
5747
|
-
}
|
|
5748
|
-
await finalizeTaskDeployment(api, deploymentRunId, logSyncer, {
|
|
5749
|
-
status: "SUCCESS",
|
|
5750
|
-
fullLog: capture.getLog()
|
|
5751
|
-
});
|
|
5752
|
-
console.log(`[apm] deploy success id=${deploymentRunId}`);
|
|
5863
|
+
outcome = await run(capture.appendLog);
|
|
5753
5864
|
} catch (error) {
|
|
5754
|
-
|
|
5865
|
+
deployError = error instanceof DeployExecutionError ? error : new DeployExecutionError(
|
|
5755
5866
|
error instanceof Error ? error.message : String(error),
|
|
5756
5867
|
1
|
|
5757
5868
|
);
|
|
@@ -5760,22 +5871,18 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
5760
5871
|
} else {
|
|
5761
5872
|
capture.appendLog(deployError.message);
|
|
5762
5873
|
}
|
|
5763
|
-
|
|
5764
|
-
await finalizeTaskDeployment(api, deploymentRunId, logSyncer, {
|
|
5765
|
-
status: "FAILED",
|
|
5766
|
-
fullLog: capture.getLog(),
|
|
5767
|
-
error: deployError.message
|
|
5768
|
-
});
|
|
5769
|
-
} catch (finalizeError) {
|
|
5770
|
-
console.error(
|
|
5771
|
-
`[apm] deploy finalize failed id=${deploymentRunId}:`,
|
|
5772
|
-
finalizeError instanceof Error ? finalizeError.message : String(finalizeError)
|
|
5773
|
-
);
|
|
5774
|
-
}
|
|
5775
|
-
console.error(
|
|
5776
|
-
`[apm] deploy failed id=${deploymentRunId}: ${deployError.message}`
|
|
5777
|
-
);
|
|
5874
|
+
outcome = { status: "FAILED", error: deployError.message };
|
|
5778
5875
|
} finally {
|
|
5876
|
+
if (deploymentStarted && !statusSynced) {
|
|
5877
|
+
if (!outcome) {
|
|
5878
|
+
outcome = { status: "FAILED", error: "\u90E8\u7F72\u672A\u5B8C\u6210" };
|
|
5879
|
+
}
|
|
5880
|
+
try {
|
|
5881
|
+
await ensureStatusSynced();
|
|
5882
|
+
} catch (error) {
|
|
5883
|
+
logDeployStatusSyncFailure(error);
|
|
5884
|
+
}
|
|
5885
|
+
}
|
|
5779
5886
|
capture.restore();
|
|
5780
5887
|
if (previousDeploymentRunId === void 0) {
|
|
5781
5888
|
delete process.env[APM_DEPLOYMENT_RUN_ID_ENV];
|
|
@@ -5784,6 +5891,58 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
5784
5891
|
}
|
|
5785
5892
|
logSyncer.dispose();
|
|
5786
5893
|
}
|
|
5894
|
+
return { outcome, error: deployError };
|
|
5895
|
+
}
|
|
5896
|
+
|
|
5897
|
+
// src/commands/connect/deploy-run.ts
|
|
5898
|
+
function resolveDeployCommand(environment, packOnly) {
|
|
5899
|
+
return packOnly ? `apm deploy ${environment} --pack-only` : `apm deploy ${environment}`;
|
|
5900
|
+
}
|
|
5901
|
+
async function handleInboundDeploy(cfg, msg, signal) {
|
|
5902
|
+
if (signal.aborted) return;
|
|
5903
|
+
const api = createApmApiClient(cfg);
|
|
5904
|
+
const deploymentRunId = msg.deploymentRunId;
|
|
5905
|
+
await api.cli.updateTaskDeploymentStatus({
|
|
5906
|
+
id: deploymentRunId,
|
|
5907
|
+
status: "DEPLOYING"
|
|
5908
|
+
});
|
|
5909
|
+
const { error: deployError } = await runTrackedDeploy({
|
|
5910
|
+
api,
|
|
5911
|
+
deploymentRunId,
|
|
5912
|
+
run: async (appendLog) => {
|
|
5913
|
+
const workdir = requireRemoteWorkdir(msg.workdir);
|
|
5914
|
+
const displayCommand = resolveDeployCommand(
|
|
5915
|
+
msg.environment,
|
|
5916
|
+
msg.packOnly
|
|
5917
|
+
);
|
|
5918
|
+
console.log(
|
|
5919
|
+
`[apm] deploy start id=${deploymentRunId} env=${msg.environment} cwd=${workdir}`
|
|
5920
|
+
);
|
|
5921
|
+
console.log(`[apm] deploy command: ${displayCommand}`);
|
|
5922
|
+
if (signal.aborted) {
|
|
5923
|
+
return { status: "FAILED", error: "\u90E8\u7F72\u5DF2\u53D6\u6D88" };
|
|
5924
|
+
}
|
|
5925
|
+
const deployOptions = {
|
|
5926
|
+
env: msg.environment,
|
|
5927
|
+
cwd: workdir,
|
|
5928
|
+
packOnly: msg.packOnly,
|
|
5929
|
+
captureOutput: true,
|
|
5930
|
+
archiveDeployArtifact: true,
|
|
5931
|
+
deployTrigger: "connect"
|
|
5932
|
+
};
|
|
5933
|
+
const output = await executeDeploy(deployOptions);
|
|
5934
|
+
if (output.trim()) {
|
|
5935
|
+
appendLog(output);
|
|
5936
|
+
}
|
|
5937
|
+
console.log(`[apm] deploy success id=${deploymentRunId}`);
|
|
5938
|
+
return { status: "SUCCESS" };
|
|
5939
|
+
}
|
|
5940
|
+
});
|
|
5941
|
+
if (deployError) {
|
|
5942
|
+
console.error(
|
|
5943
|
+
`[apm] deploy failed id=${deploymentRunId}: ${deployError.message}`
|
|
5944
|
+
);
|
|
5945
|
+
}
|
|
5787
5946
|
}
|
|
5788
5947
|
|
|
5789
5948
|
// src/commands/connect/abort-signal-debug.ts
|
|
@@ -6053,17 +6212,17 @@ ${JSON.stringify(event, null, 2)}
|
|
|
6053
6212
|
}
|
|
6054
6213
|
|
|
6055
6214
|
// src/commands/connect/agent-session-registry.ts
|
|
6056
|
-
import { existsSync as
|
|
6057
|
-
import { dirname as dirname6, resolve as
|
|
6215
|
+
import { existsSync as existsSync20, mkdirSync as mkdirSync9, readFileSync as readFileSync16, writeFileSync as writeFileSync14 } from "node:fs";
|
|
6216
|
+
import { dirname as dirname6, resolve as resolve5 } from "node:path";
|
|
6058
6217
|
function registryPath(workdir, sessionId) {
|
|
6059
|
-
return
|
|
6218
|
+
return resolve5(workdir, ".apm", "sessions", sessionId, "cursor-agents.json");
|
|
6060
6219
|
}
|
|
6061
|
-
function readRegistry(
|
|
6062
|
-
if (!
|
|
6220
|
+
function readRegistry(path19) {
|
|
6221
|
+
if (!existsSync20(path19)) {
|
|
6063
6222
|
return {};
|
|
6064
6223
|
}
|
|
6065
6224
|
try {
|
|
6066
|
-
const parsed = JSON.parse(
|
|
6225
|
+
const parsed = JSON.parse(readFileSync16(path19, "utf8"));
|
|
6067
6226
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
6068
6227
|
const result = {};
|
|
6069
6228
|
for (const [key, value] of Object.entries(
|
|
@@ -6079,9 +6238,9 @@ function readRegistry(path13) {
|
|
|
6079
6238
|
}
|
|
6080
6239
|
return {};
|
|
6081
6240
|
}
|
|
6082
|
-
function writeRegistry(
|
|
6083
|
-
|
|
6084
|
-
|
|
6241
|
+
function writeRegistry(path19, registry) {
|
|
6242
|
+
mkdirSync9(dirname6(path19), { recursive: true });
|
|
6243
|
+
writeFileSync14(path19, `${JSON.stringify(registry, null, 2)}
|
|
6085
6244
|
`, "utf8");
|
|
6086
6245
|
}
|
|
6087
6246
|
function loadSessionAgentId(workdir, sessionId, user) {
|
|
@@ -6089,19 +6248,19 @@ function loadSessionAgentId(workdir, sessionId, user) {
|
|
|
6089
6248
|
return registry[user];
|
|
6090
6249
|
}
|
|
6091
6250
|
function saveSessionAgentId(workdir, sessionId, user, agentId) {
|
|
6092
|
-
const
|
|
6093
|
-
const registry = readRegistry(
|
|
6251
|
+
const path19 = registryPath(workdir, sessionId);
|
|
6252
|
+
const registry = readRegistry(path19);
|
|
6094
6253
|
registry[user] = agentId;
|
|
6095
|
-
writeRegistry(
|
|
6254
|
+
writeRegistry(path19, registry);
|
|
6096
6255
|
}
|
|
6097
6256
|
function clearSessionAgentId(workdir, sessionId, user) {
|
|
6098
|
-
const
|
|
6099
|
-
const registry = readRegistry(
|
|
6257
|
+
const path19 = registryPath(workdir, sessionId);
|
|
6258
|
+
const registry = readRegistry(path19);
|
|
6100
6259
|
if (!(user in registry)) {
|
|
6101
6260
|
return;
|
|
6102
6261
|
}
|
|
6103
6262
|
delete registry[user];
|
|
6104
|
-
writeRegistry(
|
|
6263
|
+
writeRegistry(path19, registry);
|
|
6105
6264
|
}
|
|
6106
6265
|
|
|
6107
6266
|
// src/commands/connect/cursor-message-log.ts
|
|
@@ -6531,20 +6690,20 @@ async function ensureMessageHasReply(cfg, sessionId, messageId, fallback) {
|
|
|
6531
6690
|
}
|
|
6532
6691
|
|
|
6533
6692
|
// src/commands/connect/cli-version-sync.ts
|
|
6534
|
-
import { existsSync as
|
|
6693
|
+
import { existsSync as existsSync21, readFileSync as readFileSync17, writeFileSync as writeFileSync15 } from "fs";
|
|
6535
6694
|
import { join as join17 } from "path";
|
|
6536
6695
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
6537
6696
|
function manifestPath(apmDir) {
|
|
6538
6697
|
return join17(apmDir, CLI_VERSION_FILE);
|
|
6539
6698
|
}
|
|
6540
6699
|
function loadManifest4(apmDir) {
|
|
6541
|
-
const
|
|
6542
|
-
if (!
|
|
6700
|
+
const path19 = toFsPath(manifestPath(apmDir));
|
|
6701
|
+
if (!existsSync21(path19)) {
|
|
6543
6702
|
return null;
|
|
6544
6703
|
}
|
|
6545
6704
|
try {
|
|
6546
6705
|
const parsed = JSON.parse(
|
|
6547
|
-
|
|
6706
|
+
readFileSync17(path19, "utf8")
|
|
6548
6707
|
);
|
|
6549
6708
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
6550
6709
|
return parsed;
|
|
@@ -6555,7 +6714,7 @@ function loadManifest4(apmDir) {
|
|
|
6555
6714
|
}
|
|
6556
6715
|
function saveManifest4(apmDir, cliVersion) {
|
|
6557
6716
|
const manifest = { version: 1, cliVersion };
|
|
6558
|
-
|
|
6717
|
+
writeFileSync15(
|
|
6559
6718
|
toFsPath(manifestPath(apmDir)),
|
|
6560
6719
|
`${JSON.stringify(manifest, null, 2)}
|
|
6561
6720
|
`,
|
|
@@ -6634,7 +6793,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
6634
6793
|
);
|
|
6635
6794
|
}
|
|
6636
6795
|
const queuedAt = Date.now();
|
|
6637
|
-
return new Promise((
|
|
6796
|
+
return new Promise((resolve6) => {
|
|
6638
6797
|
waiters.push(() => {
|
|
6639
6798
|
active += 1;
|
|
6640
6799
|
const waitedMs = Date.now() - queuedAt;
|
|
@@ -6645,7 +6804,7 @@ function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {})
|
|
|
6645
6804
|
)}s\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`
|
|
6646
6805
|
);
|
|
6647
6806
|
}
|
|
6648
|
-
|
|
6807
|
+
resolve6();
|
|
6649
6808
|
});
|
|
6650
6809
|
});
|
|
6651
6810
|
};
|
|
@@ -6820,11 +6979,11 @@ async function handleInboundMessage(cfg, msg, signal, ctx) {
|
|
|
6820
6979
|
}
|
|
6821
6980
|
function interruptibleSleep(ms, signal) {
|
|
6822
6981
|
if (signal.aborted) return Promise.resolve();
|
|
6823
|
-
return new Promise((
|
|
6824
|
-
const timer = setTimeout(
|
|
6982
|
+
return new Promise((resolve6) => {
|
|
6983
|
+
const timer = setTimeout(resolve6, ms);
|
|
6825
6984
|
const onAbort = () => {
|
|
6826
6985
|
clearTimeout(timer);
|
|
6827
|
-
|
|
6986
|
+
resolve6();
|
|
6828
6987
|
};
|
|
6829
6988
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
6830
6989
|
});
|
|
@@ -6964,7 +7123,7 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
6964
7123
|
});
|
|
6965
7124
|
}
|
|
6966
7125
|
function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
6967
|
-
return new Promise((
|
|
7126
|
+
return new Promise((resolve6, reject) => {
|
|
6968
7127
|
const ws = new WebSocket(url);
|
|
6969
7128
|
let stopHeartbeat;
|
|
6970
7129
|
let settled = false;
|
|
@@ -6993,7 +7152,7 @@ function connectOnce(url, ctx, connectionAbort, onConnected) {
|
|
|
6993
7152
|
finish(() => reject(new Error("shutdown")));
|
|
6994
7153
|
return;
|
|
6995
7154
|
}
|
|
6996
|
-
finish(
|
|
7155
|
+
finish(resolve6);
|
|
6997
7156
|
});
|
|
6998
7157
|
ws.on("error", (err) => {
|
|
6999
7158
|
console.error("[apm] WebSocket \u9519\u8BEF:", err.message);
|
|
@@ -7273,14 +7432,6 @@ function normalizeDeployEnvironment(env) {
|
|
|
7273
7432
|
if (normalized === "online") return "ONLINE";
|
|
7274
7433
|
return null;
|
|
7275
7434
|
}
|
|
7276
|
-
async function completeTrackedDeploy(api, deploymentRunId, logSyncer, input) {
|
|
7277
|
-
logSyncer.updateLog(input.log);
|
|
7278
|
-
await finalizeTaskDeployment(api, deploymentRunId, logSyncer, {
|
|
7279
|
-
status: input.status,
|
|
7280
|
-
fullLog: input.log,
|
|
7281
|
-
error: input.error
|
|
7282
|
-
});
|
|
7283
|
-
}
|
|
7284
7435
|
async function runDeployWithBackendTracking(options) {
|
|
7285
7436
|
const cfg = await tryReadApmConfig();
|
|
7286
7437
|
if (!cfg || !resolveApiKey(cfg)) {
|
|
@@ -7318,67 +7469,25 @@ async function runDeployWithBackendTracking(options) {
|
|
|
7318
7469
|
id: deploymentRunId,
|
|
7319
7470
|
status: "DEPLOYING"
|
|
7320
7471
|
});
|
|
7321
|
-
const
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
};
|
|
7336
|
-
console.error = (...args) => {
|
|
7337
|
-
appendLog(args.map(String).join(" "));
|
|
7338
|
-
originalError.apply(console, args);
|
|
7339
|
-
};
|
|
7340
|
-
try {
|
|
7341
|
-
const output = await executeDeploy({
|
|
7342
|
-
...options,
|
|
7343
|
-
captureOutput: true,
|
|
7344
|
-
archiveDeployArtifact: true
|
|
7345
|
-
});
|
|
7346
|
-
if (output.trim()) {
|
|
7347
|
-
appendLog(output);
|
|
7348
|
-
}
|
|
7349
|
-
const log2 = chunks.join("\n");
|
|
7350
|
-
await completeTrackedDeploy(api, deploymentRunId, logSyncer, {
|
|
7351
|
-
status: "SUCCESS",
|
|
7352
|
-
log: log2
|
|
7353
|
-
});
|
|
7354
|
-
console.log(`[apm] deploy success id=${deploymentRunId}`);
|
|
7355
|
-
} catch (error) {
|
|
7356
|
-
const deployError = error instanceof DeployExecutionError ? error : new DeployExecutionError(
|
|
7357
|
-
error instanceof Error ? error.message : String(error),
|
|
7358
|
-
1
|
|
7359
|
-
);
|
|
7360
|
-
if (deployError.output.trim()) {
|
|
7361
|
-
appendLog(deployError.output);
|
|
7362
|
-
} else {
|
|
7363
|
-
appendLog(deployError.message);
|
|
7472
|
+
const { error: deployError } = await runTrackedDeploy({
|
|
7473
|
+
api,
|
|
7474
|
+
deploymentRunId,
|
|
7475
|
+
run: async (appendLog) => {
|
|
7476
|
+
const output = await executeDeploy({
|
|
7477
|
+
...options,
|
|
7478
|
+
captureOutput: true,
|
|
7479
|
+
archiveDeployArtifact: true
|
|
7480
|
+
});
|
|
7481
|
+
if (output.trim()) {
|
|
7482
|
+
appendLog(output);
|
|
7483
|
+
}
|
|
7484
|
+
console.log(`[apm] deploy success id=${deploymentRunId}`);
|
|
7485
|
+
return { status: "SUCCESS" };
|
|
7364
7486
|
}
|
|
7365
|
-
|
|
7366
|
-
|
|
7367
|
-
status: "FAILED",
|
|
7368
|
-
log: log2,
|
|
7369
|
-
error: deployError.message
|
|
7370
|
-
});
|
|
7487
|
+
});
|
|
7488
|
+
if (deployError) {
|
|
7371
7489
|
printDeployExecutionError(deployError);
|
|
7372
7490
|
process.exit(deployError.exitCode);
|
|
7373
|
-
} finally {
|
|
7374
|
-
if (previousDeploymentRunId === void 0) {
|
|
7375
|
-
delete process.env[APM_DEPLOYMENT_RUN_ID_ENV];
|
|
7376
|
-
} else {
|
|
7377
|
-
process.env[APM_DEPLOYMENT_RUN_ID_ENV] = previousDeploymentRunId;
|
|
7378
|
-
}
|
|
7379
|
-
console.log = originalLog;
|
|
7380
|
-
console.error = originalError;
|
|
7381
|
-
logSyncer.dispose();
|
|
7382
7491
|
}
|
|
7383
7492
|
}
|
|
7384
7493
|
|
|
@@ -7431,29 +7540,29 @@ function registerDeployMainCommand(program) {
|
|
|
7431
7540
|
}
|
|
7432
7541
|
|
|
7433
7542
|
// src/commands/deploy/backend.ts
|
|
7434
|
-
import
|
|
7543
|
+
import path16 from "node:path";
|
|
7435
7544
|
|
|
7436
7545
|
// src/commands/deploy/internal/backend-deploy/backend-deploy-workflow.ts
|
|
7437
|
-
import
|
|
7546
|
+
import path15 from "node:path";
|
|
7438
7547
|
|
|
7439
7548
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/client.ts
|
|
7440
7549
|
import Docker from "dockerode";
|
|
7441
7550
|
|
|
7442
7551
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
7443
|
-
import { existsSync as
|
|
7444
|
-
import
|
|
7552
|
+
import { existsSync as existsSync22, readFileSync as readFileSync18 } from "node:fs";
|
|
7553
|
+
import path12 from "node:path";
|
|
7445
7554
|
function asOptionalTlsBuffer(value) {
|
|
7446
7555
|
if (typeof value !== "string") {
|
|
7447
7556
|
console.log("tls filepath not exist");
|
|
7448
7557
|
return void 0;
|
|
7449
7558
|
}
|
|
7450
|
-
console.log("tls filepath",
|
|
7559
|
+
console.log("tls filepath", path12.join(process.cwd(), value));
|
|
7451
7560
|
const normalized = value.trim();
|
|
7452
7561
|
if (normalized === "") {
|
|
7453
7562
|
return void 0;
|
|
7454
7563
|
}
|
|
7455
|
-
if (
|
|
7456
|
-
return
|
|
7564
|
+
if (existsSync22(normalized)) {
|
|
7565
|
+
return readFileSync18(normalized);
|
|
7457
7566
|
}
|
|
7458
7567
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
7459
7568
|
if (looksLikePath) {
|
|
@@ -7578,17 +7687,17 @@ var DockerodeClient = class {
|
|
|
7578
7687
|
await this.client.getImage(image).remove({ force: true });
|
|
7579
7688
|
}
|
|
7580
7689
|
async pullImage(image, auth) {
|
|
7581
|
-
const stream = await new Promise((
|
|
7690
|
+
const stream = await new Promise((resolve6, reject) => {
|
|
7582
7691
|
const pullOptions = auth ? { authconfig: auth } : void 0;
|
|
7583
7692
|
this.client.pull(image, pullOptions, (err, output) => {
|
|
7584
7693
|
if (err || !output) {
|
|
7585
7694
|
reject(err ?? new Error("docker pull \u8FD4\u56DE\u7A7A\u8F93\u51FA"));
|
|
7586
7695
|
return;
|
|
7587
7696
|
}
|
|
7588
|
-
|
|
7697
|
+
resolve6(output);
|
|
7589
7698
|
});
|
|
7590
7699
|
});
|
|
7591
|
-
await new Promise((
|
|
7700
|
+
await new Promise((resolve6, reject) => {
|
|
7592
7701
|
this.client.modem.followProgress(
|
|
7593
7702
|
stream,
|
|
7594
7703
|
(err) => {
|
|
@@ -7596,7 +7705,7 @@ var DockerodeClient = class {
|
|
|
7596
7705
|
reject(err);
|
|
7597
7706
|
return;
|
|
7598
7707
|
}
|
|
7599
|
-
|
|
7708
|
+
resolve6();
|
|
7600
7709
|
},
|
|
7601
7710
|
() => void 0
|
|
7602
7711
|
);
|
|
@@ -7663,8 +7772,8 @@ var DockerodeClient = class {
|
|
|
7663
7772
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
7664
7773
|
|
|
7665
7774
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
7666
|
-
import { existsSync as
|
|
7667
|
-
import
|
|
7775
|
+
import { existsSync as existsSync23, readFileSync as readFileSync19, statSync as statSync10 } from "node:fs";
|
|
7776
|
+
import path13 from "node:path";
|
|
7668
7777
|
function stripSurroundingQuotes(value) {
|
|
7669
7778
|
const t = value.trim();
|
|
7670
7779
|
if (t.length >= 2) {
|
|
@@ -7679,11 +7788,11 @@ function loadEnvFromFile(envFilePath) {
|
|
|
7679
7788
|
if (!envFilePath) {
|
|
7680
7789
|
return {};
|
|
7681
7790
|
}
|
|
7682
|
-
const targetPath =
|
|
7683
|
-
if (!
|
|
7791
|
+
const targetPath = path13.resolve(envFilePath);
|
|
7792
|
+
if (!existsSync23(targetPath) || !statSync10(targetPath).isFile()) {
|
|
7684
7793
|
return {};
|
|
7685
7794
|
}
|
|
7686
|
-
const raw =
|
|
7795
|
+
const raw = readFileSync19(targetPath, "utf-8");
|
|
7687
7796
|
const result = {};
|
|
7688
7797
|
for (const line of raw.split(/\r?\n/)) {
|
|
7689
7798
|
const normalized = line.trim();
|
|
@@ -7854,12 +7963,12 @@ function dockerPushImage(params, cwd) {
|
|
|
7854
7963
|
}
|
|
7855
7964
|
|
|
7856
7965
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
7857
|
-
import { existsSync as
|
|
7858
|
-
import
|
|
7966
|
+
import { existsSync as existsSync24 } from "node:fs";
|
|
7967
|
+
import path14 from "node:path";
|
|
7859
7968
|
function resolveDockerBuildPaths(cwd) {
|
|
7860
|
-
const dockerfilePath =
|
|
7969
|
+
const dockerfilePath = path14.join(cwd, "Dockerfile");
|
|
7861
7970
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
7862
|
-
if (!
|
|
7971
|
+
if (!existsSync24(dockerfilePath)) {
|
|
7863
7972
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
7864
7973
|
}
|
|
7865
7974
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|
|
@@ -7914,7 +8023,7 @@ var BackendDeployWorkflow = class {
|
|
|
7914
8023
|
serveraddress
|
|
7915
8024
|
});
|
|
7916
8025
|
Logger.success("\u8FDC\u7A0B\u62C9\u53D6\u955C\u50CF\u5B8C\u6210");
|
|
7917
|
-
const envFilePath =
|
|
8026
|
+
const envFilePath = path15.resolve(cwd, this.params.envFilePath || ".env");
|
|
7918
8027
|
const envObj = loadEnvFromFile(envFilePath);
|
|
7919
8028
|
if (this.params.dockerNetwork?.trim()) {
|
|
7920
8029
|
Logger.info(`\u8FDC\u7A0B\u5BB9\u5668\u5C06\u52A0\u5165 Docker \u7F51\u7EDC\uFF1A${this.params.dockerNetwork.trim()}`);
|
|
@@ -7954,7 +8063,7 @@ function registerDeployBackendCommands(program) {
|
|
|
7954
8063
|
assertDeployImageTag(tag);
|
|
7955
8064
|
const cfg = loadApmConfig({ configPath: opts.config });
|
|
7956
8065
|
const fromApm = resolveBackendDeployFromApmConfig(cfg);
|
|
7957
|
-
const dirAbs =
|
|
8066
|
+
const dirAbs = path16.resolve(process.cwd(), opts.dir || "servers/api");
|
|
7958
8067
|
const params = {
|
|
7959
8068
|
image: fromApm.name,
|
|
7960
8069
|
tag,
|
|
@@ -7984,34 +8093,15 @@ function registerDeployBackendCommands(program) {
|
|
|
7984
8093
|
}
|
|
7985
8094
|
|
|
7986
8095
|
// src/commands/deploy/frontend.ts
|
|
7987
|
-
import { copyFile, readdir as readdir3, stat
|
|
7988
|
-
import
|
|
7989
|
-
function resolveArtifactNamePrefix(cfg) {
|
|
7990
|
-
const nameRaw = (cfg.name ?? "").trim();
|
|
7991
|
-
if (!nameRaw) {
|
|
7992
|
-
console.error(
|
|
7993
|
-
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A MinIO \u5BF9\u8C61\u952E\u524D\u7F00\uFF09"
|
|
7994
|
-
);
|
|
7995
|
-
process.exit(1);
|
|
7996
|
-
}
|
|
7997
|
-
if (nameRaw.includes(":")) {
|
|
7998
|
-
console.error("apm.config.json \u7684 name \u4E0D\u80FD\u5305\u542B ':'");
|
|
7999
|
-
process.exit(1);
|
|
8000
|
-
}
|
|
8001
|
-
try {
|
|
8002
|
-
return sanitizeRelativePath(nameRaw.replace(/\\/g, "/"));
|
|
8003
|
-
} catch {
|
|
8004
|
-
console.error("apm.config.json \u7684 name \u975E\u6CD5\uFF08\u8DEF\u5F84\u7247\u6BB5\u4E0D\u80FD\u4E3A . \u6216 ..\uFF09");
|
|
8005
|
-
process.exit(1);
|
|
8006
|
-
}
|
|
8007
|
-
}
|
|
8096
|
+
import { copyFile, readdir as readdir3, stat } from "node:fs/promises";
|
|
8097
|
+
import path17 from "node:path";
|
|
8008
8098
|
function artifactObjectKey(namePrefix, branchSegment, relativePath) {
|
|
8009
8099
|
const base = sanitizeRelativePath(namePrefix);
|
|
8010
8100
|
const rel = sanitizeRelativePath(relativePath);
|
|
8011
8101
|
return `${base}/${branchSegment}/dist/${rel}`;
|
|
8012
8102
|
}
|
|
8013
8103
|
async function ensureArtifactRootIndexHtml(root) {
|
|
8014
|
-
const indexHtmlPath =
|
|
8104
|
+
const indexHtmlPath = path17.join(root, "index.html");
|
|
8015
8105
|
try {
|
|
8016
8106
|
const st = await stat(indexHtmlPath);
|
|
8017
8107
|
if (st.isFile()) {
|
|
@@ -8023,12 +8113,11 @@ async function ensureArtifactRootIndexHtml(root) {
|
|
|
8023
8113
|
try {
|
|
8024
8114
|
entries = await readdir3(root, { withFileTypes: true });
|
|
8025
8115
|
} catch (e) {
|
|
8026
|
-
|
|
8027
|
-
process.exit(1);
|
|
8116
|
+
throw new DeployExecutionError(`\u65E0\u6CD5\u8BFB\u53D6\u4EA7\u7269\u76EE\u5F55\uFF1A${root}`, 1, String(e));
|
|
8028
8117
|
}
|
|
8029
8118
|
const dirNames = entries.filter((e) => e.isDirectory()).map((e) => String(e.name)).sort();
|
|
8030
8119
|
for (const name of dirNames) {
|
|
8031
|
-
const candidate =
|
|
8120
|
+
const candidate = path17.join(root, name, "index.html");
|
|
8032
8121
|
try {
|
|
8033
8122
|
const st = await stat(candidate);
|
|
8034
8123
|
if (!st.isFile()) {
|
|
@@ -8039,52 +8128,39 @@ async function ensureArtifactRootIndexHtml(root) {
|
|
|
8039
8128
|
}
|
|
8040
8129
|
await copyFile(candidate, indexHtmlPath);
|
|
8041
8130
|
console.error(
|
|
8042
|
-
`\u4EA7\u7269\u534F\u8BAE\uFF1A\u5DF2\u5C06 ${
|
|
8131
|
+
`\u4EA7\u7269\u534F\u8BAE\uFF1A\u5DF2\u5C06 ${path17.join(name, "index.html")} \u590D\u5236\u4E3A\u6839\u76EE\u5F55 index.html`
|
|
8043
8132
|
);
|
|
8044
8133
|
return;
|
|
8045
8134
|
}
|
|
8046
|
-
|
|
8047
|
-
`\u4EA7\u7269\u534F\u8BAE\uFF1A\u9700\u5728\u4EA7\u7269\u6839\u76EE\u5F55\u5B58\u5728 index.html\uFF0C\u6216\u5728\u5176\u4E00\u7EA7\u5B50\u76EE\u5F55\u4E2D\u5B58\u5728\u53EF\u590D\u5236\u7684 index.html\uFF08\u672A\u5728 ${root} \u4E0B\u627E\u5230\uFF09
|
|
8135
|
+
throw new DeployExecutionError(
|
|
8136
|
+
`\u4EA7\u7269\u534F\u8BAE\uFF1A\u9700\u5728\u4EA7\u7269\u6839\u76EE\u5F55\u5B58\u5728 index.html\uFF0C\u6216\u5728\u5176\u4E00\u7EA7\u5B50\u76EE\u5F55\u4E2D\u5B58\u5728\u53EF\u590D\u5236\u7684 index.html\uFF08\u672A\u5728 ${root} \u4E0B\u627E\u5230\uFF09`,
|
|
8137
|
+
1
|
|
8048
8138
|
);
|
|
8049
|
-
process.exit(1);
|
|
8050
8139
|
}
|
|
8051
8140
|
async function runFrontendPackOnlyDeploy(root, namePrefix) {
|
|
8052
|
-
const zipPath =
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
8058
|
-
|
|
8059
|
-
|
|
8060
|
-
|
|
8061
|
-
|
|
8062
|
-
|
|
8063
|
-
|
|
8064
|
-
|
|
8065
|
-
|
|
8066
|
-
|
|
8067
|
-
|
|
8068
|
-
|
|
8069
|
-
|
|
8070
|
-
|
|
8071
|
-
|
|
8072
|
-
|
|
8073
|
-
|
|
8074
|
-
|
|
8075
|
-
artifactUploaded
|
|
8076
|
-
},
|
|
8077
|
-
null,
|
|
8078
|
-
2
|
|
8079
|
-
)
|
|
8080
|
-
);
|
|
8081
|
-
} finally {
|
|
8082
|
-
try {
|
|
8083
|
-
await unlink2(zipPath);
|
|
8084
|
-
console.error(`\u5DF2\u6E05\u7406\u672C\u5730\u4E34\u65F6\u6587\u4EF6: ${zipPath}`);
|
|
8085
|
-
} catch {
|
|
8086
|
-
}
|
|
8087
|
-
}
|
|
8141
|
+
const zipPath = path17.resolve(root, "..", ".deploy-frontend-dist.zip");
|
|
8142
|
+
const { zipSizeBytes, artifactUploaded } = await packDirectoryWithMinioArchive({
|
|
8143
|
+
localDir: root,
|
|
8144
|
+
zipPath,
|
|
8145
|
+
projectName: namePrefix,
|
|
8146
|
+
kind: "frontend",
|
|
8147
|
+
uploadWithoutRunId: true,
|
|
8148
|
+
skipMessage: "[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7\u524D\u7AEF\u8BBF\u95EE\u6876\u4E0A\u4F20",
|
|
8149
|
+
successMessage: "\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u81F3\u524D\u7AEF\u8BBF\u95EE\u6876\uFF09"
|
|
8150
|
+
});
|
|
8151
|
+
console.log(
|
|
8152
|
+
JSON.stringify(
|
|
8153
|
+
{
|
|
8154
|
+
ok: true,
|
|
8155
|
+
packOnly: true,
|
|
8156
|
+
namePrefix,
|
|
8157
|
+
zipSizeBytes,
|
|
8158
|
+
artifactUploaded
|
|
8159
|
+
},
|
|
8160
|
+
null,
|
|
8161
|
+
2
|
|
8162
|
+
)
|
|
8163
|
+
);
|
|
8088
8164
|
}
|
|
8089
8165
|
function registerDeployFrontendCommands(program) {
|
|
8090
8166
|
program.command("deploy-frontend").description(
|
|
@@ -8105,91 +8181,97 @@ function registerDeployFrontendCommands(program) {
|
|
|
8105
8181
|
"\u4EC5\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u81F3\u524D\u7AEF\u8BBF\u95EE\u6876\uFF08\u9ED8\u8BA4\u5173\u95ED\uFF09"
|
|
8106
8182
|
).action(
|
|
8107
8183
|
async (name, opts) => {
|
|
8108
|
-
|
|
8109
|
-
|
|
8110
|
-
|
|
8111
|
-
|
|
8112
|
-
|
|
8113
|
-
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
|
|
8117
|
-
|
|
8118
|
-
|
|
8119
|
-
|
|
8120
|
-
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
8128
|
-
|
|
8129
|
-
|
|
8130
|
-
|
|
8131
|
-
|
|
8132
|
-
|
|
8133
|
-
|
|
8134
|
-
|
|
8135
|
-
|
|
8136
|
-
|
|
8137
|
-
|
|
8138
|
-
|
|
8139
|
-
|
|
8140
|
-
|
|
8141
|
-
|
|
8142
|
-
|
|
8143
|
-
|
|
8144
|
-
|
|
8145
|
-
|
|
8146
|
-
|
|
8147
|
-
|
|
8148
|
-
|
|
8149
|
-
|
|
8184
|
+
try {
|
|
8185
|
+
const cfg = loadApmConfig({ configPath: opts.config });
|
|
8186
|
+
const namePrefix = resolveArtifactNamePrefix(cfg);
|
|
8187
|
+
const root = path17.resolve(process.cwd(), opts.dir || "apps/web/dist");
|
|
8188
|
+
if (!await isDirectoryPath(root)) {
|
|
8189
|
+
throw new DeployExecutionError(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`, 1);
|
|
8190
|
+
}
|
|
8191
|
+
await ensureArtifactRootIndexHtml(root);
|
|
8192
|
+
if (opts.packOnly) {
|
|
8193
|
+
await runFrontendPackOnlyDeploy(root, namePrefix);
|
|
8194
|
+
return;
|
|
8195
|
+
}
|
|
8196
|
+
const settings = resolveFrontendDeployFromApmConfig(cfg);
|
|
8197
|
+
const minio = new MinioClient({
|
|
8198
|
+
endPoint: settings.endpoint,
|
|
8199
|
+
port: settings.port,
|
|
8200
|
+
useSSL: settings.useSsl,
|
|
8201
|
+
accessKey: settings.accessKey,
|
|
8202
|
+
secretKey: settings.secretKey
|
|
8203
|
+
});
|
|
8204
|
+
const bucket = settings.bucket;
|
|
8205
|
+
const maxBytes = Math.max(
|
|
8206
|
+
1,
|
|
8207
|
+
Number.isFinite(opts.maxFileSizeMb) ? Math.floor(
|
|
8208
|
+
(opts.maxFileSizeMb ?? DEFAULT_MAX_FILE_SIZE_MB) * 1024 * 1024
|
|
8209
|
+
) : DEFAULT_MAX_FILE_SIZE_MB * 1024 * 1024
|
|
8210
|
+
);
|
|
8211
|
+
const files = await collectFiles(root);
|
|
8212
|
+
if (files.length === 0) {
|
|
8213
|
+
throw new DeployExecutionError(`\u76EE\u5F55\u4E3A\u7A7A\uFF1A${root}`, 1);
|
|
8214
|
+
}
|
|
8215
|
+
let uploaded = 0;
|
|
8216
|
+
let totalBytes = 0;
|
|
8217
|
+
console.error(`\u5F00\u59CB\u76F4\u8FDE MinIO \u4E0A\u4F20\uFF0C\u5171 ${files.length} \u4E2A\u6587\u4EF6\u2026`);
|
|
8218
|
+
await minio.ensureBucket(bucket);
|
|
8219
|
+
await minio.deleteObjectsByPrefix(
|
|
8220
|
+
bucket,
|
|
8221
|
+
`${namePrefix}/${name}/dist/`
|
|
8222
|
+
);
|
|
8223
|
+
for (const f of files) {
|
|
8224
|
+
if (f.size > maxBytes) {
|
|
8225
|
+
throw new DeployExecutionError(
|
|
8226
|
+
`\u6587\u4EF6\u8FC7\u5927\uFF0C\u5DF2\u62D2\u7EDD\uFF1A${f.relativePath}\uFF08${toMB(
|
|
8227
|
+
f.size
|
|
8228
|
+
)}MB > ${toMB(maxBytes)}MB\uFF09`,
|
|
8229
|
+
1
|
|
8230
|
+
);
|
|
8231
|
+
}
|
|
8232
|
+
const buf = await readArtifactFile(f.absPath);
|
|
8233
|
+
const cleanRel = sanitizeRelativePath(f.relativePath);
|
|
8234
|
+
const objectKey = artifactObjectKey(namePrefix, name, cleanRel);
|
|
8235
|
+
const mimeType = detectMimeType(f.relativePath).trim().toLowerCase() || "application/octet-stream";
|
|
8236
|
+
await minio.putObject(bucket, objectKey, buf, {
|
|
8237
|
+
"Content-Type": mimeType
|
|
8238
|
+
});
|
|
8239
|
+
uploaded += 1;
|
|
8240
|
+
totalBytes += buf.length;
|
|
8150
8241
|
console.error(
|
|
8151
|
-
|
|
8152
|
-
maxBytes
|
|
8153
|
-
)}MB\uFF09`
|
|
8242
|
+
`[${uploaded}/${files.length}] ${f.relativePath} -> ${objectKey}`
|
|
8154
8243
|
);
|
|
8155
|
-
process.exit(1);
|
|
8156
8244
|
}
|
|
8157
|
-
|
|
8158
|
-
|
|
8159
|
-
|
|
8160
|
-
|
|
8161
|
-
|
|
8162
|
-
|
|
8163
|
-
|
|
8164
|
-
|
|
8165
|
-
|
|
8166
|
-
|
|
8167
|
-
|
|
8245
|
+
console.error("\u6B63\u5728\u8BBE\u7F6E\u6876\u7B56\u7565\uFF08\u533F\u540D\u53EF\u8BFB\u5BF9\u8C61\uFF0C\u4FBF\u4E8E HTTP \u76F4\u94FE\uFF09\u2026");
|
|
8246
|
+
await minio.setBucketPublicRead(bucket);
|
|
8247
|
+
console.log(
|
|
8248
|
+
JSON.stringify(
|
|
8249
|
+
{
|
|
8250
|
+
ok: true,
|
|
8251
|
+
namePrefix,
|
|
8252
|
+
envName: name,
|
|
8253
|
+
bucket,
|
|
8254
|
+
fileCount: uploaded,
|
|
8255
|
+
totalBytes,
|
|
8256
|
+
bucketPublicRead: true
|
|
8257
|
+
},
|
|
8258
|
+
null,
|
|
8259
|
+
2
|
|
8260
|
+
)
|
|
8168
8261
|
);
|
|
8262
|
+
} catch (error) {
|
|
8263
|
+
if (error instanceof DeployExecutionError) {
|
|
8264
|
+
printDeployExecutionError(error);
|
|
8265
|
+
process.exit(error.exitCode);
|
|
8266
|
+
}
|
|
8267
|
+
throw error;
|
|
8169
8268
|
}
|
|
8170
|
-
console.error("\u6B63\u5728\u8BBE\u7F6E\u6876\u7B56\u7565\uFF08\u533F\u540D\u53EF\u8BFB\u5BF9\u8C61\uFF0C\u4FBF\u4E8E HTTP \u76F4\u94FE\uFF09\u2026");
|
|
8171
|
-
await minio.setBucketPublicRead(bucket);
|
|
8172
|
-
console.log(
|
|
8173
|
-
JSON.stringify(
|
|
8174
|
-
{
|
|
8175
|
-
ok: true,
|
|
8176
|
-
namePrefix,
|
|
8177
|
-
envName: name,
|
|
8178
|
-
bucket,
|
|
8179
|
-
fileCount: uploaded,
|
|
8180
|
-
totalBytes,
|
|
8181
|
-
bucketPublicRead: true
|
|
8182
|
-
},
|
|
8183
|
-
null,
|
|
8184
|
-
2
|
|
8185
|
-
)
|
|
8186
|
-
);
|
|
8187
8269
|
}
|
|
8188
8270
|
);
|
|
8189
8271
|
}
|
|
8190
8272
|
|
|
8191
8273
|
// src/commands/deploy/sftp.ts
|
|
8192
|
-
import
|
|
8274
|
+
import path18 from "node:path";
|
|
8193
8275
|
function registerDeploySftpCommands(program) {
|
|
8194
8276
|
program.command("deploy-sftp").description(
|
|
8195
8277
|
"\u5C06\u6307\u5B9A\u76EE\u5F55\u538B\u7F29\u4E3A zip \u540E\u901A\u8FC7 SFTP \u4E0A\u4F20\u5230\u8FDC\u7A0B\u670D\u52A1\u5668\uFF08\u8FDE\u63A5\u4FE1\u606F\u89C1 apm.config.json wisdomDeploy\uFF09"
|
|
@@ -8205,25 +8287,22 @@ function registerDeploySftpCommands(program) {
|
|
|
8205
8287
|
"\u4EC5\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF08\u4E0E --extract \u4E92\u65A5\uFF09"
|
|
8206
8288
|
).action(
|
|
8207
8289
|
async (opts) => {
|
|
8208
|
-
const cfg = loadApmConfig({ configPath: opts.config });
|
|
8209
|
-
const settings = resolveWisdomDeployFromApmConfig(cfg);
|
|
8210
|
-
const projectName = (cfg.name ?? "").trim();
|
|
8211
|
-
if (!projectName) {
|
|
8212
|
-
console.error(
|
|
8213
|
-
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09"
|
|
8214
|
-
);
|
|
8215
|
-
process.exit(1);
|
|
8216
|
-
}
|
|
8217
|
-
const root = path12.resolve(process.cwd(), opts.dir || "apps/web/dist");
|
|
8218
|
-
if (!await isDirectoryPath(root)) {
|
|
8219
|
-
console.error(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`);
|
|
8220
|
-
process.exit(1);
|
|
8221
|
-
}
|
|
8222
8290
|
try {
|
|
8291
|
+
const cfg = loadApmConfig({ configPath: opts.config });
|
|
8292
|
+
const settings = resolveWisdomDeployFromApmConfig(cfg);
|
|
8293
|
+
const projectName = resolveProjectNameForDeploy(cfg, process.cwd(), {
|
|
8294
|
+
requireName: true
|
|
8295
|
+
});
|
|
8296
|
+
const root = path18.resolve(process.cwd(), opts.dir || "apps/web/dist");
|
|
8297
|
+
if (!await isDirectoryPath(root)) {
|
|
8298
|
+
throw new DeployExecutionError(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`, 1);
|
|
8299
|
+
}
|
|
8223
8300
|
const packOnly = Boolean(opts.packOnly);
|
|
8224
8301
|
if (packOnly && opts.extract) {
|
|
8225
|
-
|
|
8226
|
-
|
|
8302
|
+
throw new DeployExecutionError(
|
|
8303
|
+
"--pack-only \u4E0E --extract \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528",
|
|
8304
|
+
1
|
|
8305
|
+
);
|
|
8227
8306
|
}
|
|
8228
8307
|
const result = await runWisdomSftpDeploy({
|
|
8229
8308
|
localDir: root,
|
|
@@ -8233,8 +8312,12 @@ function registerDeploySftpCommands(program) {
|
|
|
8233
8312
|
packOnly
|
|
8234
8313
|
});
|
|
8235
8314
|
console.log(JSON.stringify(result, null, 2));
|
|
8236
|
-
} catch (
|
|
8237
|
-
|
|
8315
|
+
} catch (error) {
|
|
8316
|
+
if (error instanceof DeployExecutionError) {
|
|
8317
|
+
printDeployExecutionError(error);
|
|
8318
|
+
process.exit(error.exitCode);
|
|
8319
|
+
}
|
|
8320
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
8238
8321
|
const action = opts.packOnly ? "\u6253\u5305" : opts.extract ? "\u90E8\u7F72" : "\u4E0A\u4F20";
|
|
8239
8322
|
console.error(`${action}\u5931\u8D25:`, message);
|
|
8240
8323
|
process.exit(1);
|
|
@@ -8251,11 +8334,19 @@ function registerDeployWisdomBackendCommands(program) {
|
|
|
8251
8334
|
"--config <path>",
|
|
8252
8335
|
"apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
|
|
8253
8336
|
).action(async (opts) => {
|
|
8254
|
-
|
|
8255
|
-
|
|
8256
|
-
|
|
8257
|
-
|
|
8258
|
-
|
|
8337
|
+
try {
|
|
8338
|
+
const cfg = loadApmConfig({ configPath: opts.config });
|
|
8339
|
+
const settings = resolveWisdomBackendDeployFromApmConfig(cfg);
|
|
8340
|
+
await runWisdomBackendDeploy({
|
|
8341
|
+
config: settings
|
|
8342
|
+
});
|
|
8343
|
+
} catch (error) {
|
|
8344
|
+
if (error instanceof DeployExecutionError) {
|
|
8345
|
+
printDeployExecutionError(error);
|
|
8346
|
+
process.exit(error.exitCode);
|
|
8347
|
+
}
|
|
8348
|
+
throw error;
|
|
8349
|
+
}
|
|
8259
8350
|
});
|
|
8260
8351
|
}
|
|
8261
8352
|
|