ai-project-manage-cli 6.0.103 → 6.0.105
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 +734 -469
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2035,6 +2035,9 @@ import { basename as basename3 } from "path";
|
|
|
2035
2035
|
// src/assumptions/local-validate.ts
|
|
2036
2036
|
var NO_ASSUMPTIONS_RE = /无[,,]?\s*口径均有依据/;
|
|
2037
2037
|
var BLOCK_HEADER_RE = /^####\s+(A\d+)\s*$/im;
|
|
2038
|
+
function formatAssumptionQuestionId(source, code) {
|
|
2039
|
+
return `${source}:${code}`;
|
|
2040
|
+
}
|
|
2038
2041
|
var DEV_PATTERNS = [
|
|
2039
2042
|
{ pattern: /status\s*=/i, message: "\u5305\u542B status= \u7B49\u6280\u672F\u679A\u4E3E" },
|
|
2040
2043
|
{ pattern: /\.(java|vue|ts|tsx|jsx|sql)\b/i, message: "\u5305\u542B\u6587\u4EF6\u8DEF\u5F84" },
|
|
@@ -2064,7 +2067,7 @@ function parseField(block, label) {
|
|
|
2064
2067
|
const value = match?.[1]?.trim();
|
|
2065
2068
|
return value || void 0;
|
|
2066
2069
|
}
|
|
2067
|
-
function parseStructuredBlock(code, block) {
|
|
2070
|
+
function parseStructuredBlock(code, block, source) {
|
|
2068
2071
|
const pmQuestion = parseField(block, "\u95EE") ?? parseField(block, "prompt");
|
|
2069
2072
|
if (!pmQuestion) return null;
|
|
2070
2073
|
const optionsSection = block.match(
|
|
@@ -2073,7 +2076,7 @@ function parseStructuredBlock(code, block) {
|
|
|
2073
2076
|
const options = optionsSection ? parseOptionsBlock(optionsSection[1]) : [];
|
|
2074
2077
|
return {
|
|
2075
2078
|
code,
|
|
2076
|
-
questionId: code,
|
|
2079
|
+
questionId: formatAssumptionQuestionId(source, code),
|
|
2077
2080
|
pmQuestion,
|
|
2078
2081
|
context: parseField(block, "\u573A\u666F"),
|
|
2079
2082
|
options,
|
|
@@ -2104,7 +2107,7 @@ function parseAssumptionsDocument(markdown, _source) {
|
|
|
2104
2107
|
for (const block of blocks) {
|
|
2105
2108
|
const headerMatch = block.match(BLOCK_HEADER_RE);
|
|
2106
2109
|
if (!headerMatch) continue;
|
|
2107
|
-
const parsed = parseStructuredBlock(headerMatch[1], block);
|
|
2110
|
+
const parsed = parseStructuredBlock(headerMatch[1], block, _source);
|
|
2108
2111
|
if (parsed) results.push(parsed);
|
|
2109
2112
|
}
|
|
2110
2113
|
return results;
|
|
@@ -2878,33 +2881,17 @@ function posixBasename(p) {
|
|
|
2878
2881
|
}
|
|
2879
2882
|
|
|
2880
2883
|
// src/commands/deploy/internal/deploy-hints.ts
|
|
2881
|
-
function
|
|
2882
|
-
const configuredEnvs = Object.keys(deployCommands).filter(
|
|
2883
|
-
(key) => deployCommands[key]?.trim()
|
|
2884
|
-
);
|
|
2885
|
-
if (configuredEnvs.length > 0) {
|
|
2886
|
-
return [
|
|
2887
|
-
`[apm] \u65E0\u6CD5\u6267\u884C\u90E8\u7F72\uFF1Aapm.config.json \u4E2D\u672A\u914D\u7F6E deploy.${env}`,
|
|
2888
|
-
`[apm] \u5F53\u524D\u5DF2\u914D\u7F6E\u7684\u73AF\u5883: ${configuredEnvs.join(", ")}`
|
|
2889
|
-
];
|
|
2890
|
-
}
|
|
2884
|
+
function formatMissingWisdomDeployLines() {
|
|
2891
2885
|
return [
|
|
2892
|
-
"[apm] \u65E0\u6CD5\u6267\u884C\
|
|
2893
|
-
"[apm] \u90E8\u5206\u9879\u76EE\u4E0D\u652F\u6301\u6216\u672A\u542F\u7528\u81EA\u52A8\u5316\u90E8\u7F72\uFF0C\u5C5E\u6B63\u5E38\u60C5\u51B5\uFF0C\u53EF\u8DF3\u8FC7\u90E8\u7F72"
|
|
2886
|
+
"[apm] \u65E0\u6CD5\u6267\u884C apm deploy\uFF1A\u8BF7\u5728 apm.config.json \u4E2D\u914D\u7F6E wisdomDeploy\uFF08host\u3001remotePath\uFF09"
|
|
2894
2887
|
];
|
|
2895
2888
|
}
|
|
2896
2889
|
function formatWisdomFrontendBuildNotConfiguredLines(env, packageJsonPath) {
|
|
2897
2890
|
return [
|
|
2898
|
-
`[apm] \u65E0\u6CD5\u6267\u884C\
|
|
2891
|
+
`[apm] \u65E0\u6CD5\u6267\u884C\u524D\u7AEF\u90E8\u7F72\uFF1A${packageJsonPath} \u4E2D\u672A\u627E\u5230 build:${env} \u811A\u672C`,
|
|
2899
2892
|
"[apm] \u8BF7\u914D\u7F6E npm run build:test / build:online \u540E\u518D\u8BD5"
|
|
2900
2893
|
];
|
|
2901
2894
|
}
|
|
2902
|
-
function formatWisdomFrontendDeployNotConfiguredLines(env, packageJsonPath) {
|
|
2903
|
-
return [
|
|
2904
|
-
`[apm] \u65E0\u6CD5\u6267\u884C\u90E8\u7F72\uFF1A${packageJsonPath} \u4E2D\u672A\u627E\u5230 deploy:${env} \u811A\u672C`,
|
|
2905
|
-
"[apm] \u82E5\u672C\u9879\u76EE\u4E0D\u652F\u6301\u81EA\u52A8\u5316\u90E8\u7F72\uFF0C\u5C5E\u6B63\u5E38\u60C5\u51B5\uFF0C\u53EF\u8DF3\u8FC7\u90E8\u7F72"
|
|
2906
|
-
];
|
|
2907
|
-
}
|
|
2908
2895
|
|
|
2909
2896
|
// src/commands/deploy/deploy-errors.ts
|
|
2910
2897
|
var DeployExecutionError = class extends Error {
|
|
@@ -2918,8 +2905,260 @@ var DeployExecutionError = class extends Error {
|
|
|
2918
2905
|
}
|
|
2919
2906
|
};
|
|
2920
2907
|
|
|
2921
|
-
// src/commands/deploy/deploy-
|
|
2908
|
+
// src/commands/deploy/deploy-debug-log.ts
|
|
2922
2909
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
2910
|
+
import { existsSync as existsSync14 } from "node:fs";
|
|
2911
|
+
import { dirname as dirname5, join as join16 } from "node:path";
|
|
2912
|
+
|
|
2913
|
+
// src/commands/deploy/internal/deploy-artifact-minio.ts
|
|
2914
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
2915
|
+
|
|
2916
|
+
// src/commands/deploy/internal/minio.ts
|
|
2917
|
+
import { statSync as statSync5 } from "node:fs";
|
|
2918
|
+
import { readdir, readFile } from "node:fs/promises";
|
|
2919
|
+
import path from "node:path";
|
|
2920
|
+
import * as Minio from "minio";
|
|
2921
|
+
var DEFAULT_MAX_FILE_SIZE_MB = 50;
|
|
2922
|
+
async function isDirectoryPath(dir) {
|
|
2923
|
+
try {
|
|
2924
|
+
const st = statSync5(dir);
|
|
2925
|
+
return st.isDirectory();
|
|
2926
|
+
} catch {
|
|
2927
|
+
return false;
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2930
|
+
function sanitizeRelativePath(rel) {
|
|
2931
|
+
const norm = rel.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
2932
|
+
const segments = norm.split("/").filter(Boolean);
|
|
2933
|
+
for (const s of segments) {
|
|
2934
|
+
if (s === "." || s === "..") {
|
|
2935
|
+
throw new Error(`\u975E\u6CD5\u76F8\u5BF9\u8DEF\u5F84\u7247\u6BB5\uFF1A${s}`);
|
|
2936
|
+
}
|
|
2937
|
+
}
|
|
2938
|
+
return segments.join("/");
|
|
2939
|
+
}
|
|
2940
|
+
async function collectFiles(root) {
|
|
2941
|
+
const out = [];
|
|
2942
|
+
async function walk(dir, prefix) {
|
|
2943
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
2944
|
+
for (const e of entries) {
|
|
2945
|
+
const name = e.name;
|
|
2946
|
+
if (name === "." || name === "..") {
|
|
2947
|
+
continue;
|
|
2948
|
+
}
|
|
2949
|
+
const abs = path.join(dir, name);
|
|
2950
|
+
const rel = prefix ? `${prefix}/${name}` : name;
|
|
2951
|
+
if (e.isDirectory()) {
|
|
2952
|
+
await walk(abs, rel);
|
|
2953
|
+
} else if (e.isFile()) {
|
|
2954
|
+
const st = statSync5(abs);
|
|
2955
|
+
out.push({
|
|
2956
|
+
absPath: abs,
|
|
2957
|
+
relativePath: rel.replace(/\\/g, "/"),
|
|
2958
|
+
size: st.size
|
|
2959
|
+
});
|
|
2960
|
+
}
|
|
2961
|
+
}
|
|
2962
|
+
}
|
|
2963
|
+
await walk(root, "");
|
|
2964
|
+
out.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
2965
|
+
return out;
|
|
2966
|
+
}
|
|
2967
|
+
async function readArtifactFile(absPath) {
|
|
2968
|
+
return readFile(absPath);
|
|
2969
|
+
}
|
|
2970
|
+
function toMB(bytes) {
|
|
2971
|
+
return Math.round(bytes / (1024 * 1024) * 1e3) / 1e3;
|
|
2972
|
+
}
|
|
2973
|
+
var MIME = {
|
|
2974
|
+
".html": "text/html; charset=utf-8",
|
|
2975
|
+
".css": "text/css; charset=utf-8",
|
|
2976
|
+
".js": "application/javascript; charset=utf-8",
|
|
2977
|
+
".json": "application/json; charset=utf-8",
|
|
2978
|
+
".svg": "image/svg+xml",
|
|
2979
|
+
".png": "image/png",
|
|
2980
|
+
".jpg": "image/jpeg",
|
|
2981
|
+
".jpeg": "image/jpeg",
|
|
2982
|
+
".gif": "image/gif",
|
|
2983
|
+
".webp": "image/webp",
|
|
2984
|
+
".woff": "font/woff",
|
|
2985
|
+
".woff2": "font/woff2",
|
|
2986
|
+
".ttf": "font/ttf",
|
|
2987
|
+
".ico": "image/x-icon",
|
|
2988
|
+
".txt": "text/plain; charset=utf-8",
|
|
2989
|
+
".map": "application/json"
|
|
2990
|
+
};
|
|
2991
|
+
function detectMimeType(filePath) {
|
|
2992
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
2993
|
+
return MIME[ext] ?? "";
|
|
2994
|
+
}
|
|
2995
|
+
var MinioClient = class {
|
|
2996
|
+
inner;
|
|
2997
|
+
constructor(opts) {
|
|
2998
|
+
const endPoint = opts.endPoint.replace(/^https?:\/\//i, "").split("/")[0] ?? opts.endPoint;
|
|
2999
|
+
this.inner = new Minio.Client({
|
|
3000
|
+
endPoint,
|
|
3001
|
+
port: opts.port,
|
|
3002
|
+
useSSL: opts.useSSL,
|
|
3003
|
+
accessKey: opts.accessKey,
|
|
3004
|
+
secretKey: opts.secretKey
|
|
3005
|
+
});
|
|
3006
|
+
}
|
|
3007
|
+
async ensureBucket(bucket) {
|
|
3008
|
+
const exists = await this.inner.bucketExists(bucket);
|
|
3009
|
+
if (!exists) {
|
|
3010
|
+
await this.inner.makeBucket(bucket);
|
|
3011
|
+
}
|
|
3012
|
+
}
|
|
3013
|
+
async deleteObjectsByPrefix(bucket, prefix) {
|
|
3014
|
+
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
3015
|
+
const keys = [];
|
|
3016
|
+
await new Promise((resolve5, reject) => {
|
|
3017
|
+
objectsStream.on("data", (obj) => {
|
|
3018
|
+
if (obj.name) {
|
|
3019
|
+
keys.push(obj.name);
|
|
3020
|
+
}
|
|
3021
|
+
});
|
|
3022
|
+
objectsStream.on("error", reject);
|
|
3023
|
+
objectsStream.on("end", resolve5);
|
|
3024
|
+
});
|
|
3025
|
+
const chunkSize = 500;
|
|
3026
|
+
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
3027
|
+
const chunk = keys.slice(i, i + chunkSize);
|
|
3028
|
+
await this.inner.removeObjects(
|
|
3029
|
+
bucket,
|
|
3030
|
+
chunk.map((name) => name)
|
|
3031
|
+
);
|
|
3032
|
+
}
|
|
3033
|
+
}
|
|
3034
|
+
async putObject(bucket, objectKey, body, meta) {
|
|
3035
|
+
await this.inner.putObject(bucket, objectKey, body, body.length, meta);
|
|
3036
|
+
}
|
|
3037
|
+
/** 匿名可读当前桶全部对象(便于静态站点直链) */
|
|
3038
|
+
async setBucketPublicRead(bucket) {
|
|
3039
|
+
const policy = {
|
|
3040
|
+
Version: "2012-10-17",
|
|
3041
|
+
Statement: [
|
|
3042
|
+
{
|
|
3043
|
+
Effect: "Allow",
|
|
3044
|
+
Principal: { AWS: ["*"] },
|
|
3045
|
+
Action: ["s3:GetObject"],
|
|
3046
|
+
Resource: [`arn:aws:s3:::${bucket}/*`]
|
|
3047
|
+
}
|
|
3048
|
+
]
|
|
3049
|
+
};
|
|
3050
|
+
await this.inner.setBucketPolicy(bucket, JSON.stringify(policy));
|
|
3051
|
+
}
|
|
3052
|
+
};
|
|
3053
|
+
|
|
3054
|
+
// src/commands/deploy/internal/deploy-artifact-minio.ts
|
|
3055
|
+
var APM_DEPLOYMENT_RUN_ID_ENV = "APM_DEPLOYMENT_RUN_ID";
|
|
3056
|
+
function formatDeployArtifactTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
3057
|
+
const pad = (n) => String(n).padStart(2, "0");
|
|
3058
|
+
return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`;
|
|
3059
|
+
}
|
|
3060
|
+
function sanitizeDeployProjectName(name) {
|
|
3061
|
+
const trimmed = name.trim().replace(/\\/g, "/");
|
|
3062
|
+
const base = trimmed.split("/").filter(Boolean).pop() ?? trimmed;
|
|
3063
|
+
try {
|
|
3064
|
+
return sanitizeRelativePath(base.replace(/[/\\:*?"<>|]/g, "_"));
|
|
3065
|
+
} catch {
|
|
3066
|
+
return "project";
|
|
3067
|
+
}
|
|
3068
|
+
}
|
|
3069
|
+
function buildDeployArtifactFileName(kind, projectName, timestamp = formatDeployArtifactTimestamp()) {
|
|
3070
|
+
const safeName = sanitizeDeployProjectName(projectName);
|
|
3071
|
+
const suffix = kind === "frontend" ? "dist.zip" : "jar.zip";
|
|
3072
|
+
return `${timestamp}-${safeName}.${suffix}`;
|
|
3073
|
+
}
|
|
3074
|
+
function buildDeployArtifactObjectKey(projectName, fileName) {
|
|
3075
|
+
const safeProject = sanitizeDeployProjectName(projectName);
|
|
3076
|
+
return `deploy/${safeProject}/${fileName}`;
|
|
3077
|
+
}
|
|
3078
|
+
function resolveDeploymentRunIdFromEnv() {
|
|
3079
|
+
const raw = process.env[APM_DEPLOYMENT_RUN_ID_ENV]?.trim();
|
|
3080
|
+
return raw || null;
|
|
3081
|
+
}
|
|
3082
|
+
async function fetchDeployArtifactStorage(api) {
|
|
3083
|
+
return api.cli.getDeployArtifactStorage(void 0);
|
|
3084
|
+
}
|
|
3085
|
+
async function uploadDeployArtifactZip(options) {
|
|
3086
|
+
const deploymentRunId = options.deploymentRunId ?? resolveDeploymentRunIdFromEnv();
|
|
3087
|
+
if (!deploymentRunId && !options.uploadWithoutRunId) {
|
|
3088
|
+
return null;
|
|
3089
|
+
}
|
|
3090
|
+
const cfg = await tryReadApmConfig();
|
|
3091
|
+
if (!cfg || !resolveApiKey(cfg)) {
|
|
3092
|
+
console.warn("[apm] \u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7 MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863");
|
|
3093
|
+
return null;
|
|
3094
|
+
}
|
|
3095
|
+
const api = options.api ?? createApmApiClient(cfg);
|
|
3096
|
+
let storage;
|
|
3097
|
+
try {
|
|
3098
|
+
storage = await fetchDeployArtifactStorage(api);
|
|
3099
|
+
} catch (error) {
|
|
3100
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3101
|
+
console.warn(`[apm] \u83B7\u53D6 MinIO \u914D\u7F6E\u5931\u8D25\uFF0C\u8DF3\u8FC7\u90E8\u7F72\u4EA7\u7269\u5F52\u6863: ${detail}`);
|
|
3102
|
+
return null;
|
|
3103
|
+
}
|
|
3104
|
+
const fileName = buildDeployArtifactFileName(
|
|
3105
|
+
options.kind,
|
|
3106
|
+
options.projectName,
|
|
3107
|
+
options.timestamp
|
|
3108
|
+
);
|
|
3109
|
+
const objectKey = buildDeployArtifactObjectKey(options.projectName, fileName);
|
|
3110
|
+
let body;
|
|
3111
|
+
try {
|
|
3112
|
+
body = await readFile2(options.zipPath);
|
|
3113
|
+
} catch (error) {
|
|
3114
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3115
|
+
console.warn(`[apm] \u8BFB\u53D6\u90E8\u7F72\u4EA7\u7269 zip \u5931\u8D25\uFF0C\u8DF3\u8FC7 MinIO \u5F52\u6863: ${detail}`);
|
|
3116
|
+
return null;
|
|
3117
|
+
}
|
|
3118
|
+
try {
|
|
3119
|
+
const client = new MinioClient({
|
|
3120
|
+
endPoint: storage.endpoint,
|
|
3121
|
+
port: storage.port,
|
|
3122
|
+
useSSL: storage.useSsl,
|
|
3123
|
+
accessKey: storage.accessKey,
|
|
3124
|
+
secretKey: storage.secretKey
|
|
3125
|
+
});
|
|
3126
|
+
await client.ensureBucket(storage.bucket);
|
|
3127
|
+
await client.putObject(storage.bucket, objectKey, body, {
|
|
3128
|
+
"Content-Type": "application/zip"
|
|
3129
|
+
});
|
|
3130
|
+
console.error(
|
|
3131
|
+
`[apm] \u672C\u5730\u76F4\u4F20 MinIO\uFF08\u4E0D\u7ECF\u5E73\u53F0\u670D\u52A1\u5668\uFF09: ${storage.endpoint}:${storage.port}/${storage.bucket}/${objectKey} (${(body.length / 1024 / 1024).toFixed(
|
|
3132
|
+
2
|
|
3133
|
+
)} MB)`
|
|
3134
|
+
);
|
|
3135
|
+
} catch (error) {
|
|
3136
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3137
|
+
console.warn(`[apm] MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863\u5931\u8D25: ${detail}`);
|
|
3138
|
+
return null;
|
|
3139
|
+
}
|
|
3140
|
+
if (deploymentRunId) {
|
|
3141
|
+
try {
|
|
3142
|
+
await api.cli.attachTaskDeploymentArtifact({
|
|
3143
|
+
id: deploymentRunId,
|
|
3144
|
+
artifactObjectKey: objectKey,
|
|
3145
|
+
artifactFileName: fileName
|
|
3146
|
+
});
|
|
3147
|
+
console.error(
|
|
3148
|
+
`[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
|
|
3149
|
+
);
|
|
3150
|
+
} catch (error) {
|
|
3151
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3152
|
+
console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
|
|
3153
|
+
return null;
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
return {
|
|
3157
|
+
objectKey,
|
|
3158
|
+
fileName,
|
|
3159
|
+
bucket: storage.bucket
|
|
3160
|
+
};
|
|
3161
|
+
}
|
|
2923
3162
|
|
|
2924
3163
|
// src/commands/deploy/internal/deploy-shell-env.ts
|
|
2925
3164
|
import { spawnSync as spawnSync3 } from "node:child_process";
|
|
@@ -3741,316 +3980,252 @@ function buildDeployShellEnv(extra) {
|
|
|
3741
3980
|
return env;
|
|
3742
3981
|
}
|
|
3743
3982
|
|
|
3744
|
-
// src/commands/deploy/deploy-
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
const
|
|
3757
|
-
if (
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
}
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
)
|
|
3767
|
-
|
|
3768
|
-
if (result.status !== 0) {
|
|
3769
|
-
throw new DeployExecutionError(
|
|
3770
|
-
`\u90E8\u7F72\u547D\u4EE4\u9000\u51FA\u7801 ${result.status ?? "unknown"}: ${command}`,
|
|
3771
|
-
result.status ?? 1,
|
|
3772
|
-
output
|
|
3773
|
-
);
|
|
3774
|
-
}
|
|
3775
|
-
return output;
|
|
3776
|
-
}
|
|
3777
|
-
|
|
3778
|
-
// src/commands/deploy/internal/wisdom-auto-deploy.ts
|
|
3779
|
-
import { existsSync as existsSync15, readFileSync as readFileSync13, statSync as statSync7 } from "node:fs";
|
|
3780
|
-
import path4 from "node:path";
|
|
3781
|
-
|
|
3782
|
-
// src/commands/deploy/internal/wisdom-backend-deploy.ts
|
|
3783
|
-
import {
|
|
3784
|
-
existsSync as existsSync14,
|
|
3785
|
-
mkdirSync as mkdirSync7,
|
|
3786
|
-
readdirSync as readdirSync5,
|
|
3787
|
-
readFileSync as readFileSync12,
|
|
3788
|
-
statSync as statSync6,
|
|
3789
|
-
writeFileSync as writeFileSync12
|
|
3790
|
-
} from "node:fs";
|
|
3791
|
-
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
3792
|
-
import path3 from "node:path";
|
|
3793
|
-
import { Client as Client2 } from "ssh2";
|
|
3794
|
-
import JSZip2 from "jszip";
|
|
3795
|
-
import SftpClient2 from "ssh2-sftp-client";
|
|
3796
|
-
|
|
3797
|
-
// src/commands/deploy/internal/wisdom-sftp.ts
|
|
3798
|
-
import { readdir as readdir2, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
|
|
3799
|
-
import path2 from "node:path";
|
|
3800
|
-
import JSZip from "jszip";
|
|
3801
|
-
import SftpClient from "ssh2-sftp-client";
|
|
3802
|
-
|
|
3803
|
-
// src/commands/deploy/internal/deploy-artifact-minio.ts
|
|
3804
|
-
import { readFile as readFile2 } from "node:fs/promises";
|
|
3805
|
-
|
|
3806
|
-
// src/commands/deploy/internal/minio.ts
|
|
3807
|
-
import { statSync as statSync5 } from "node:fs";
|
|
3808
|
-
import { readdir, readFile } from "node:fs/promises";
|
|
3809
|
-
import path from "node:path";
|
|
3810
|
-
import * as Minio from "minio";
|
|
3811
|
-
var DEFAULT_MAX_FILE_SIZE_MB = 50;
|
|
3812
|
-
async function isDirectoryPath(dir) {
|
|
3813
|
-
try {
|
|
3814
|
-
const st = statSync5(dir);
|
|
3815
|
-
return st.isDirectory();
|
|
3816
|
-
} catch {
|
|
3817
|
-
return false;
|
|
3818
|
-
}
|
|
3819
|
-
}
|
|
3820
|
-
function sanitizeRelativePath(rel) {
|
|
3821
|
-
const norm = rel.replace(/\\/g, "/").replace(/^\/+/, "");
|
|
3822
|
-
const segments = norm.split("/").filter(Boolean);
|
|
3823
|
-
for (const s of segments) {
|
|
3824
|
-
if (s === "." || s === "..") {
|
|
3825
|
-
throw new Error(`\u975E\u6CD5\u76F8\u5BF9\u8DEF\u5F84\u7247\u6BB5\uFF1A${s}`);
|
|
3826
|
-
}
|
|
3827
|
-
}
|
|
3828
|
-
return segments.join("/");
|
|
3829
|
-
}
|
|
3830
|
-
async function collectFiles(root) {
|
|
3831
|
-
const out = [];
|
|
3832
|
-
async function walk(dir, prefix) {
|
|
3833
|
-
const entries = await readdir(dir, { withFileTypes: true });
|
|
3834
|
-
for (const e of entries) {
|
|
3835
|
-
const name = e.name;
|
|
3836
|
-
if (name === "." || name === "..") {
|
|
3837
|
-
continue;
|
|
3838
|
-
}
|
|
3839
|
-
const abs = path.join(dir, name);
|
|
3840
|
-
const rel = prefix ? `${prefix}/${name}` : name;
|
|
3841
|
-
if (e.isDirectory()) {
|
|
3842
|
-
await walk(abs, rel);
|
|
3843
|
-
} else if (e.isFile()) {
|
|
3844
|
-
const st = statSync5(abs);
|
|
3845
|
-
out.push({
|
|
3846
|
-
absPath: abs,
|
|
3847
|
-
relativePath: rel.replace(/\\/g, "/"),
|
|
3848
|
-
size: st.size
|
|
3849
|
-
});
|
|
3850
|
-
}
|
|
3983
|
+
// src/commands/deploy/deploy-debug-log.ts
|
|
3984
|
+
var LOG_PREFIX = "[apm:deploy-debug]";
|
|
3985
|
+
var SENSITIVE_ENV_KEY = /(password|secret|token|api[_-]?key|authorization|credential|private|passwd)/i;
|
|
3986
|
+
var PATH_SEP2 = process.platform === "win32" ? ";" : ":";
|
|
3987
|
+
function logLine(message) {
|
|
3988
|
+
console.error(`${LOG_PREFIX} ${message}`);
|
|
3989
|
+
}
|
|
3990
|
+
function pathEntries(value) {
|
|
3991
|
+
if (!value?.trim()) return [];
|
|
3992
|
+
return value.split(PATH_SEP2).filter(Boolean);
|
|
3993
|
+
}
|
|
3994
|
+
function summarizePath(value, maxEntries = 12) {
|
|
3995
|
+
const entries = pathEntries(value);
|
|
3996
|
+
if (entries.length === 0) return "(empty)";
|
|
3997
|
+
const head = entries.slice(0, maxEntries).join(PATH_SEP2);
|
|
3998
|
+
if (entries.length <= maxEntries) return head;
|
|
3999
|
+
return `${head}${PATH_SEP2}\u2026 (+${entries.length - maxEntries} more)`;
|
|
4000
|
+
}
|
|
4001
|
+
function pickEnvKeys(env, keys) {
|
|
4002
|
+
const out = {};
|
|
4003
|
+
for (const key of keys) {
|
|
4004
|
+
const value = env[key];
|
|
4005
|
+
if (value !== void 0 && value !== "") {
|
|
4006
|
+
out[key] = value;
|
|
3851
4007
|
}
|
|
3852
4008
|
}
|
|
3853
|
-
await walk(root, "");
|
|
3854
|
-
out.sort((a, b) => a.relativePath.localeCompare(b.relativePath));
|
|
3855
4009
|
return out;
|
|
3856
4010
|
}
|
|
3857
|
-
|
|
3858
|
-
|
|
3859
|
-
|
|
3860
|
-
|
|
3861
|
-
|
|
3862
|
-
|
|
3863
|
-
|
|
3864
|
-
|
|
3865
|
-
|
|
3866
|
-
|
|
3867
|
-
|
|
3868
|
-
|
|
3869
|
-
|
|
3870
|
-
|
|
3871
|
-
|
|
3872
|
-
|
|
3873
|
-
|
|
3874
|
-
|
|
3875
|
-
|
|
3876
|
-
".ttf": "font/ttf",
|
|
3877
|
-
".ico": "image/x-icon",
|
|
3878
|
-
".txt": "text/plain; charset=utf-8",
|
|
3879
|
-
".map": "application/json"
|
|
3880
|
-
};
|
|
3881
|
-
function detectMimeType(filePath) {
|
|
3882
|
-
const ext = path.extname(filePath).toLowerCase();
|
|
3883
|
-
return MIME[ext] ?? "";
|
|
3884
|
-
}
|
|
3885
|
-
var MinioClient = class {
|
|
3886
|
-
inner;
|
|
3887
|
-
constructor(opts) {
|
|
3888
|
-
const endPoint = opts.endPoint.replace(/^https?:\/\//i, "").split("/")[0] ?? opts.endPoint;
|
|
3889
|
-
this.inner = new Minio.Client({
|
|
3890
|
-
endPoint,
|
|
3891
|
-
port: opts.port,
|
|
3892
|
-
useSSL: opts.useSSL,
|
|
3893
|
-
accessKey: opts.accessKey,
|
|
3894
|
-
secretKey: opts.secretKey
|
|
3895
|
-
});
|
|
3896
|
-
}
|
|
3897
|
-
async ensureBucket(bucket) {
|
|
3898
|
-
const exists = await this.inner.bucketExists(bucket);
|
|
3899
|
-
if (!exists) {
|
|
3900
|
-
await this.inner.makeBucket(bucket);
|
|
4011
|
+
function collectInterestingEnv(env) {
|
|
4012
|
+
const keys = /* @__PURE__ */ new Set([
|
|
4013
|
+
"PATH",
|
|
4014
|
+
"HOME",
|
|
4015
|
+
"USER",
|
|
4016
|
+
"LOGNAME",
|
|
4017
|
+
"SHELL",
|
|
4018
|
+
"LANG",
|
|
4019
|
+
"LC_ALL",
|
|
4020
|
+
"NODE_ENV",
|
|
4021
|
+
"npm_config_registry",
|
|
4022
|
+
"NPM_CONFIG_REGISTRY",
|
|
4023
|
+
"npm_config_prefix",
|
|
4024
|
+
"NPM_CONFIG_PREFIX",
|
|
4025
|
+
APM_DEPLOYMENT_RUN_ID_ENV
|
|
4026
|
+
]);
|
|
4027
|
+
for (const key of Object.keys(env)) {
|
|
4028
|
+
if (/^npm_config_/i.test(key) || /^NPM_CONFIG_/i.test(key)) {
|
|
4029
|
+
keys.add(key);
|
|
3901
4030
|
}
|
|
3902
|
-
|
|
3903
|
-
|
|
3904
|
-
const objectsStream = this.inner.listObjectsV2(bucket, prefix, true);
|
|
3905
|
-
const keys = [];
|
|
3906
|
-
await new Promise((resolve5, reject) => {
|
|
3907
|
-
objectsStream.on("data", (obj) => {
|
|
3908
|
-
if (obj.name) {
|
|
3909
|
-
keys.push(obj.name);
|
|
3910
|
-
}
|
|
3911
|
-
});
|
|
3912
|
-
objectsStream.on("error", reject);
|
|
3913
|
-
objectsStream.on("end", resolve5);
|
|
3914
|
-
});
|
|
3915
|
-
const chunkSize = 500;
|
|
3916
|
-
for (let i = 0; i < keys.length; i += chunkSize) {
|
|
3917
|
-
const chunk = keys.slice(i, i + chunkSize);
|
|
3918
|
-
await this.inner.removeObjects(
|
|
3919
|
-
bucket,
|
|
3920
|
-
chunk.map((name) => name)
|
|
3921
|
-
);
|
|
4031
|
+
if (/^APM_/i.test(key) && !SENSITIVE_ENV_KEY.test(key)) {
|
|
4032
|
+
keys.add(key);
|
|
3922
4033
|
}
|
|
3923
4034
|
}
|
|
3924
|
-
|
|
3925
|
-
|
|
3926
|
-
|
|
3927
|
-
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
Statement: [
|
|
3932
|
-
{
|
|
3933
|
-
Effect: "Allow",
|
|
3934
|
-
Principal: { AWS: ["*"] },
|
|
3935
|
-
Action: ["s3:GetObject"],
|
|
3936
|
-
Resource: [`arn:aws:s3:::${bucket}/*`]
|
|
3937
|
-
}
|
|
3938
|
-
]
|
|
3939
|
-
};
|
|
3940
|
-
await this.inner.setBucketPolicy(bucket, JSON.stringify(policy));
|
|
3941
|
-
}
|
|
3942
|
-
};
|
|
3943
|
-
|
|
3944
|
-
// src/commands/deploy/internal/deploy-artifact-minio.ts
|
|
3945
|
-
var APM_DEPLOYMENT_RUN_ID_ENV = "APM_DEPLOYMENT_RUN_ID";
|
|
3946
|
-
function formatDeployArtifactTimestamp(date = /* @__PURE__ */ new Date()) {
|
|
3947
|
-
const pad = (n) => String(n).padStart(2, "0");
|
|
3948
|
-
return `${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`;
|
|
3949
|
-
}
|
|
3950
|
-
function sanitizeDeployProjectName(name) {
|
|
3951
|
-
const trimmed = name.trim().replace(/\\/g, "/");
|
|
3952
|
-
const base = trimmed.split("/").filter(Boolean).pop() ?? trimmed;
|
|
3953
|
-
try {
|
|
3954
|
-
return sanitizeRelativePath(base.replace(/[/\\:*?"<>|]/g, "_"));
|
|
3955
|
-
} catch {
|
|
3956
|
-
return "project";
|
|
3957
|
-
}
|
|
4035
|
+
const picked = {};
|
|
4036
|
+
for (const key of [...keys].sort()) {
|
|
4037
|
+
const value = env[key];
|
|
4038
|
+
if (value === void 0 || value === "") continue;
|
|
4039
|
+
picked[key] = SENSITIVE_ENV_KEY.test(key) ? "***" : value;
|
|
4040
|
+
}
|
|
4041
|
+
return picked;
|
|
3958
4042
|
}
|
|
3959
|
-
function
|
|
3960
|
-
const
|
|
3961
|
-
const
|
|
3962
|
-
return
|
|
4043
|
+
function describePathDelta(before, after) {
|
|
4044
|
+
const beforeSet = new Set(pathEntries(before));
|
|
4045
|
+
const added = pathEntries(after).filter((entry) => !beforeSet.has(entry));
|
|
4046
|
+
if (added.length === 0) return "buildDeployShellEnv \u672A prepend \u65B0 PATH \u6BB5";
|
|
4047
|
+
return `prepend: ${added.join(PATH_SEP2)}`;
|
|
3963
4048
|
}
|
|
3964
|
-
function
|
|
3965
|
-
const
|
|
3966
|
-
|
|
4049
|
+
function probeCommand(label, command, cwd, env) {
|
|
4050
|
+
const result = spawnSync4(command, {
|
|
4051
|
+
cwd,
|
|
4052
|
+
shell: true,
|
|
4053
|
+
env,
|
|
4054
|
+
encoding: "utf8",
|
|
4055
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
4056
|
+
});
|
|
4057
|
+
const stdout = String(result.stdout ?? "").trim();
|
|
4058
|
+
const stderr = String(result.stderr ?? "").trim();
|
|
4059
|
+
const detail = stdout || stderr || "(no output)";
|
|
4060
|
+
logLine(
|
|
4061
|
+
`probe ${label}: exit=${result.status ?? "null"} output=${detail.slice(
|
|
4062
|
+
0,
|
|
4063
|
+
500
|
|
4064
|
+
)}`
|
|
4065
|
+
);
|
|
3967
4066
|
}
|
|
3968
|
-
function
|
|
3969
|
-
|
|
3970
|
-
|
|
4067
|
+
function probeShellTooling(cwd, env) {
|
|
4068
|
+
logLine("--- shell \u5DE5\u5177\u63A2\u6D4B\uFF08\u4E0E runDeployShellCommand \u76F8\u540C env/cwd\uFF09---");
|
|
4069
|
+
probeCommand("node -v", "node -v", cwd, env);
|
|
4070
|
+
probeCommand("npm -v", "npm -v", cwd, env);
|
|
4071
|
+
if (process.platform === "win32") {
|
|
4072
|
+
probeCommand("where node", "where node", cwd, env);
|
|
4073
|
+
probeCommand("where npm", "where npm", cwd, env);
|
|
4074
|
+
} else {
|
|
4075
|
+
probeCommand("which node", "which node", cwd, env);
|
|
4076
|
+
probeCommand("which npm", "which npm", cwd, env);
|
|
4077
|
+
}
|
|
4078
|
+
}
|
|
4079
|
+
function logExecuteDeployContext(input) {
|
|
4080
|
+
const trigger = input.trigger ?? "cli";
|
|
4081
|
+
const deploymentRunId = process.env[APM_DEPLOYMENT_RUN_ID_ENV]?.trim() || null;
|
|
4082
|
+
const shellEnv = buildDeployShellEnv();
|
|
4083
|
+
const npmGlobalBin = resolveNpmGlobalBin2();
|
|
4084
|
+
const packageJsonPath = join16(input.cwd, "package.json");
|
|
4085
|
+
logLine("========== executeDeploy \u4E0A\u4E0B\u6587 ==========");
|
|
4086
|
+
logLine(`trigger=${trigger} deployEnv=${input.env}`);
|
|
4087
|
+
logLine(`cwd(input)=${input.cwdInput}`);
|
|
4088
|
+
logLine(`cwd(resolved)=${input.cwd}`);
|
|
4089
|
+
logLine(`process.cwd()=${input.processCwd}`);
|
|
4090
|
+
logLine(
|
|
4091
|
+
`cwdMatchProcess=${input.cwd === input.processCwd ? "yes" : "no"} (connect \u901A\u5E38\u4E3A no)`
|
|
4092
|
+
);
|
|
4093
|
+
logLine(
|
|
4094
|
+
`apm.config=${input.apmConfigPath} exists=${existsSync14(
|
|
4095
|
+
input.apmConfigPath
|
|
4096
|
+
)}`
|
|
4097
|
+
);
|
|
4098
|
+
logLine(
|
|
4099
|
+
`package.json=${packageJsonPath} exists=${existsSync14(packageJsonPath)}`
|
|
4100
|
+
);
|
|
4101
|
+
logLine(
|
|
4102
|
+
`flags captureOutput=${input.captureOutput} packOnly=${Boolean(
|
|
4103
|
+
input.packOnly
|
|
4104
|
+
)} archiveDeployArtifact=${Boolean(input.archiveDeployArtifact)}`
|
|
4105
|
+
);
|
|
4106
|
+
logLine(`configPathOption=${input.configPathOption ?? "(default)"}`);
|
|
4107
|
+
logLine(`${APM_DEPLOYMENT_RUN_ID_ENV}=${deploymentRunId ?? "(unset)"}`);
|
|
4108
|
+
logLine(
|
|
4109
|
+
`process execPath=${process.execPath} pid=${process.pid} platform=${process.platform} arch=${process.arch}`
|
|
4110
|
+
);
|
|
4111
|
+
logLine(`process argv=${process.argv.join(" ")}`);
|
|
4112
|
+
logLine(`npmGlobalBin=${npmGlobalBin ?? "(resolve failed)"}`);
|
|
4113
|
+
logLine(`nodeDir=${dirname5(process.execPath)}`);
|
|
4114
|
+
logLine("--- process.env\uFF08\u8282\u9009\uFF09---");
|
|
4115
|
+
for (const [key, value] of Object.entries(
|
|
4116
|
+
collectInterestingEnv(process.env)
|
|
4117
|
+
)) {
|
|
4118
|
+
logLine(` ${key}=${value}`);
|
|
4119
|
+
}
|
|
4120
|
+
logLine(`process.env.PATH=${summarizePath(process.env.PATH)}`);
|
|
4121
|
+
logLine("--- buildDeployShellEnv()\uFF08\u5B50\u8FDB\u7A0B\u5B9E\u9645 env\uFF09---");
|
|
4122
|
+
logLine(describePathDelta(process.env.PATH, shellEnv.PATH));
|
|
4123
|
+
logLine(`shellEnv.PATH=${summarizePath(shellEnv.PATH)}`);
|
|
4124
|
+
for (const [key, value] of Object.entries(
|
|
4125
|
+
pickEnvKeys(shellEnv, [APM_DEPLOYMENT_RUN_ID_ENV, "NODE_ENV"])
|
|
4126
|
+
)) {
|
|
4127
|
+
logLine(` shellEnv.${key}=${value}`);
|
|
4128
|
+
}
|
|
4129
|
+
probeShellTooling(input.cwd, shellEnv);
|
|
4130
|
+
logLine("==========================================");
|
|
4131
|
+
}
|
|
4132
|
+
function logRunDeployShellContext(input) {
|
|
4133
|
+
const shellEnv = buildDeployShellEnv();
|
|
4134
|
+
logLine("---------- runDeployShellCommand ----------");
|
|
4135
|
+
logLine(`command=${input.command}`);
|
|
4136
|
+
logLine(`cwd=${input.cwd}`);
|
|
4137
|
+
logLine(`captureOutput=${input.captureOutput}`);
|
|
4138
|
+
logLine(
|
|
4139
|
+
`stdio=${input.captureOutput ? "stdin=inherit stdout=pipe stderr=pipe" : "inherit"}`
|
|
4140
|
+
);
|
|
4141
|
+
logLine(`shell=true maxBuffer=${50 * 1024 * 1024}`);
|
|
4142
|
+
logLine(`shellEnv.PATH(head)=${summarizePath(shellEnv.PATH, 8)}`);
|
|
4143
|
+
logLine("--------------------------------------------");
|
|
3971
4144
|
}
|
|
3972
|
-
|
|
3973
|
-
|
|
4145
|
+
function logRunDeployShellResult(input) {
|
|
4146
|
+
logLine(
|
|
4147
|
+
`runDeployShellCommand done command=${input.command} exit=${input.exitCode ?? "null"} signal=${input.signal ?? "null"} capturedBytes=${input.outputBytes}${input.errorMessage ? ` error=${input.errorMessage}` : ""}`
|
|
4148
|
+
);
|
|
3974
4149
|
}
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
3978
|
-
|
|
3979
|
-
}
|
|
3980
|
-
const cfg = await tryReadApmConfig();
|
|
3981
|
-
if (!cfg || !resolveApiKey(cfg)) {
|
|
3982
|
-
console.warn("[apm] \u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7 MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863");
|
|
3983
|
-
return null;
|
|
3984
|
-
}
|
|
3985
|
-
const api = options.api ?? createApmApiClient(cfg);
|
|
3986
|
-
let storage;
|
|
3987
|
-
try {
|
|
3988
|
-
storage = await fetchDeployArtifactStorage(api);
|
|
3989
|
-
} catch (error) {
|
|
3990
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
3991
|
-
console.warn(`[apm] \u83B7\u53D6 MinIO \u914D\u7F6E\u5931\u8D25\uFF0C\u8DF3\u8FC7\u90E8\u7F72\u4EA7\u7269\u5F52\u6863: ${detail}`);
|
|
3992
|
-
return null;
|
|
3993
|
-
}
|
|
3994
|
-
const fileName = buildDeployArtifactFileName(
|
|
3995
|
-
options.kind,
|
|
3996
|
-
options.projectName,
|
|
3997
|
-
options.timestamp
|
|
4150
|
+
function logWisdomFrontendDeployContext(input) {
|
|
4151
|
+
logLine("--- wisdom Vue \u524D\u7AEF ---");
|
|
4152
|
+
logLine(
|
|
4153
|
+
`buildKey=build:${input.env} buildCmd=${input.buildCmd ?? "(missing)"}`
|
|
3998
4154
|
);
|
|
3999
|
-
|
|
4000
|
-
|
|
4001
|
-
|
|
4002
|
-
|
|
4003
|
-
|
|
4004
|
-
|
|
4005
|
-
|
|
4006
|
-
|
|
4155
|
+
logLine(`distDir=${input.distDir} exists=${existsSync14(input.distDir)}`);
|
|
4156
|
+
logLine(
|
|
4157
|
+
`packOnly=${input.packOnly} archiveDeployArtifact=${input.archiveDeployArtifact}`
|
|
4158
|
+
);
|
|
4159
|
+
}
|
|
4160
|
+
|
|
4161
|
+
// src/commands/deploy/internal/wisdom-deploy.ts
|
|
4162
|
+
import { existsSync as existsSync16, readFileSync as readFileSync13, statSync as statSync7 } from "node:fs";
|
|
4163
|
+
import path4 from "node:path";
|
|
4164
|
+
|
|
4165
|
+
// src/commands/deploy/deploy-shell-run.ts
|
|
4166
|
+
import { spawnSync as spawnSync5 } from "node:child_process";
|
|
4167
|
+
function runDeployShellCommand(command, cwd, captureOutput) {
|
|
4168
|
+
logRunDeployShellContext({ command, cwd, captureOutput });
|
|
4169
|
+
const shellEnv = buildDeployShellEnv();
|
|
4170
|
+
const result = spawnSync5(command, {
|
|
4171
|
+
cwd,
|
|
4172
|
+
shell: true,
|
|
4173
|
+
env: shellEnv,
|
|
4174
|
+
encoding: "utf8",
|
|
4175
|
+
maxBuffer: DEPLOY_SPAWN_MAX_BUFFER_BYTES,
|
|
4176
|
+
stdio: captureOutput ? ["inherit", "pipe", "pipe"] : "inherit"
|
|
4177
|
+
});
|
|
4178
|
+
const stdout = captureOutput ? String(result.stdout ?? "") : "";
|
|
4179
|
+
const stderr = captureOutput ? String(result.stderr ?? "") : "";
|
|
4180
|
+
const output = [stdout, stderr].filter(Boolean).join("\n");
|
|
4181
|
+
logRunDeployShellResult({
|
|
4182
|
+
command,
|
|
4183
|
+
exitCode: result.status,
|
|
4184
|
+
signal: result.signal,
|
|
4185
|
+
errorMessage: result.error?.message,
|
|
4186
|
+
outputBytes: Buffer.byteLength(output, "utf8")
|
|
4187
|
+
});
|
|
4188
|
+
if (captureOutput) {
|
|
4189
|
+
if (stdout) process.stdout.write(stdout);
|
|
4190
|
+
if (stderr) process.stderr.write(stderr);
|
|
4007
4191
|
}
|
|
4008
|
-
|
|
4009
|
-
|
|
4010
|
-
|
|
4011
|
-
|
|
4012
|
-
|
|
4013
|
-
accessKey: storage.accessKey,
|
|
4014
|
-
secretKey: storage.secretKey
|
|
4015
|
-
});
|
|
4016
|
-
await client.ensureBucket(storage.bucket);
|
|
4017
|
-
await client.putObject(storage.bucket, objectKey, body, {
|
|
4018
|
-
"Content-Type": "application/zip"
|
|
4019
|
-
});
|
|
4020
|
-
console.error(
|
|
4021
|
-
`[apm] \u672C\u5730\u76F4\u4F20 MinIO\uFF08\u4E0D\u7ECF\u5E73\u53F0\u670D\u52A1\u5668\uFF09: ${storage.endpoint}:${storage.port}/${storage.bucket}/${objectKey} (${(body.length / 1024 / 1024).toFixed(
|
|
4022
|
-
2
|
|
4023
|
-
)} MB)`
|
|
4192
|
+
if (result.error) {
|
|
4193
|
+
throw new DeployExecutionError(
|
|
4194
|
+
`\u90E8\u7F72\u547D\u4EE4\u6267\u884C\u5931\u8D25: ${result.error.message}`,
|
|
4195
|
+
1,
|
|
4196
|
+
output
|
|
4024
4197
|
);
|
|
4025
|
-
} catch (error) {
|
|
4026
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
4027
|
-
console.warn(`[apm] MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863\u5931\u8D25: ${detail}`);
|
|
4028
|
-
return null;
|
|
4029
4198
|
}
|
|
4030
|
-
if (
|
|
4031
|
-
|
|
4032
|
-
|
|
4033
|
-
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
});
|
|
4037
|
-
console.error(
|
|
4038
|
-
`[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
|
|
4039
|
-
);
|
|
4040
|
-
} catch (error) {
|
|
4041
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
4042
|
-
console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
|
|
4043
|
-
return null;
|
|
4044
|
-
}
|
|
4199
|
+
if (result.status !== 0) {
|
|
4200
|
+
throw new DeployExecutionError(
|
|
4201
|
+
`\u90E8\u7F72\u547D\u4EE4\u9000\u51FA\u7801 ${result.status ?? "unknown"}: ${command}`,
|
|
4202
|
+
result.status ?? 1,
|
|
4203
|
+
output
|
|
4204
|
+
);
|
|
4045
4205
|
}
|
|
4046
|
-
return
|
|
4047
|
-
objectKey,
|
|
4048
|
-
fileName,
|
|
4049
|
-
bucket: storage.bucket
|
|
4050
|
-
};
|
|
4206
|
+
return output;
|
|
4051
4207
|
}
|
|
4052
4208
|
|
|
4209
|
+
// src/commands/deploy/internal/wisdom-backend-deploy.ts
|
|
4210
|
+
import {
|
|
4211
|
+
existsSync as existsSync15,
|
|
4212
|
+
mkdirSync as mkdirSync7,
|
|
4213
|
+
readdirSync as readdirSync5,
|
|
4214
|
+
readFileSync as readFileSync12,
|
|
4215
|
+
statSync as statSync6,
|
|
4216
|
+
writeFileSync as writeFileSync12
|
|
4217
|
+
} from "node:fs";
|
|
4218
|
+
import { spawnSync as spawnSync6 } from "node:child_process";
|
|
4219
|
+
import path3 from "node:path";
|
|
4220
|
+
import { Client as Client2 } from "ssh2";
|
|
4221
|
+
import JSZip2 from "jszip";
|
|
4222
|
+
import SftpClient2 from "ssh2-sftp-client";
|
|
4223
|
+
|
|
4053
4224
|
// src/commands/deploy/internal/wisdom-sftp.ts
|
|
4225
|
+
import { readdir as readdir2, readFile as readFile3, unlink, writeFile } from "node:fs/promises";
|
|
4226
|
+
import path2 from "node:path";
|
|
4227
|
+
import JSZip from "jszip";
|
|
4228
|
+
import SftpClient from "ssh2-sftp-client";
|
|
4054
4229
|
async function addDirToZip(dir, zipFolder) {
|
|
4055
4230
|
const entries = await readdir2(dir, { withFileTypes: true });
|
|
4056
4231
|
for (const entry of entries) {
|
|
@@ -4208,10 +4383,27 @@ async function uploadAndMaybeExtract(settings, localZip, extract) {
|
|
|
4208
4383
|
await sftp.end();
|
|
4209
4384
|
}
|
|
4210
4385
|
}
|
|
4386
|
+
function resolveDeployArtifactUpload(input) {
|
|
4387
|
+
const { packOnly, archiveDeployArtifact, deploymentRunId } = input;
|
|
4388
|
+
if (deploymentRunId) {
|
|
4389
|
+
return { upload: true, uploadWithoutRunId: false };
|
|
4390
|
+
}
|
|
4391
|
+
if (archiveDeployArtifact || packOnly) {
|
|
4392
|
+
return { upload: true, uploadWithoutRunId: true };
|
|
4393
|
+
}
|
|
4394
|
+
return { upload: false, uploadWithoutRunId: false };
|
|
4395
|
+
}
|
|
4211
4396
|
async function runWisdomSftpDeploy(params) {
|
|
4212
4397
|
const zipPath = path2.join(params.localDir, "..", ".deploy-sftp-dist.zip");
|
|
4213
4398
|
const resolvedZipPath = path2.resolve(zipPath);
|
|
4214
4399
|
const packOnly = Boolean(params.packOnly);
|
|
4400
|
+
const archiveDeployArtifact = Boolean(params.archiveDeployArtifact);
|
|
4401
|
+
const deploymentRunId = resolveDeploymentRunIdFromEnv();
|
|
4402
|
+
const artifactUpload = resolveDeployArtifactUpload({
|
|
4403
|
+
packOnly,
|
|
4404
|
+
archiveDeployArtifact,
|
|
4405
|
+
deploymentRunId
|
|
4406
|
+
});
|
|
4215
4407
|
let zipSizeBytes = 0;
|
|
4216
4408
|
let artifactUploaded = false;
|
|
4217
4409
|
try {
|
|
@@ -4225,15 +4417,21 @@ async function runWisdomSftpDeploy(params) {
|
|
|
4225
4417
|
} else {
|
|
4226
4418
|
console.error("[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7 SFTP \u8FDC\u7A0B\u4E0A\u4F20");
|
|
4227
4419
|
}
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4420
|
+
if (artifactUpload.upload) {
|
|
4421
|
+
const artifact = await uploadDeployArtifactZip({
|
|
4422
|
+
zipPath: resolvedZipPath,
|
|
4423
|
+
projectName: params.projectName,
|
|
4424
|
+
kind: "frontend",
|
|
4425
|
+
uploadWithoutRunId: artifactUpload.uploadWithoutRunId
|
|
4426
|
+
});
|
|
4427
|
+
artifactUploaded = artifact !== null;
|
|
4428
|
+
}
|
|
4429
|
+
if (artifactUploaded) {
|
|
4430
|
+
if (packOnly) {
|
|
4431
|
+
console.error("\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09");
|
|
4432
|
+
} else {
|
|
4433
|
+
console.error("[apm] SFTP \u90E8\u7F72\u5B8C\u6210\uFF0C\u90E8\u7F72\u4EA7\u7269\u5DF2\u5F52\u6863 MinIO");
|
|
4434
|
+
}
|
|
4237
4435
|
}
|
|
4238
4436
|
} finally {
|
|
4239
4437
|
try {
|
|
@@ -4303,7 +4501,7 @@ function fileSignature(filePath) {
|
|
|
4303
4501
|
}
|
|
4304
4502
|
function loadManifest3() {
|
|
4305
4503
|
const manifestPath2 = manifestFilePath();
|
|
4306
|
-
if (!
|
|
4504
|
+
if (!existsSync15(manifestPath2)) {
|
|
4307
4505
|
return {};
|
|
4308
4506
|
}
|
|
4309
4507
|
return JSON.parse(readFileSync12(manifestPath2, "utf8"));
|
|
@@ -4388,7 +4586,7 @@ function getMvnExecutable() {
|
|
|
4388
4586
|
const isWin = process.platform === "win32";
|
|
4389
4587
|
const candidates = isWin ? ["mvn.cmd", "mvn.bat", "mvn"] : ["mvn"];
|
|
4390
4588
|
for (const name of candidates) {
|
|
4391
|
-
const result =
|
|
4589
|
+
const result = spawnSync6(isWin ? `where ${name}` : `which ${name}`, {
|
|
4392
4590
|
encoding: "utf8",
|
|
4393
4591
|
shell: true
|
|
4394
4592
|
});
|
|
@@ -4418,7 +4616,7 @@ function runMavenBuild(projectRoot, mavenLocalRepo, repoSource) {
|
|
|
4418
4616
|
log(`Maven \u672C\u5730\u4ED3\u5E93: ${mavenRepo}`);
|
|
4419
4617
|
}
|
|
4420
4618
|
log(`\u6784\u5EFA\u76EE\u5F55: ${projectRoot}`);
|
|
4421
|
-
const result =
|
|
4619
|
+
const result = spawnSync6(command, {
|
|
4422
4620
|
cwd: projectRoot,
|
|
4423
4621
|
stdio: "inherit",
|
|
4424
4622
|
shell: true,
|
|
@@ -4430,11 +4628,11 @@ function runMavenBuild(projectRoot, mavenLocalRepo, repoSource) {
|
|
|
4430
4628
|
}
|
|
4431
4629
|
function locateLibDir(projectRoot) {
|
|
4432
4630
|
const targetDir = getTargetDir(projectRoot);
|
|
4433
|
-
if (!
|
|
4631
|
+
if (!existsSync15(targetDir)) {
|
|
4434
4632
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
4435
4633
|
}
|
|
4436
4634
|
const libDir = path3.join(targetDir, "lib");
|
|
4437
|
-
if (!
|
|
4635
|
+
if (!existsSync15(libDir) || !statSync6(libDir).isDirectory()) {
|
|
4438
4636
|
fail(`lib \u76EE\u5F55\u4E0D\u5B58\u5728: ${libDir}`);
|
|
4439
4637
|
}
|
|
4440
4638
|
const libJars = readdirSync5(libDir).filter((name) => name.endsWith(".jar"));
|
|
@@ -4446,7 +4644,7 @@ function locateLibDir(projectRoot) {
|
|
|
4446
4644
|
}
|
|
4447
4645
|
function locateMainJar(projectRoot) {
|
|
4448
4646
|
const targetDir = getTargetDir(projectRoot);
|
|
4449
|
-
if (!
|
|
4647
|
+
if (!existsSync15(targetDir)) {
|
|
4450
4648
|
fail(`\u6784\u5EFA\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728: ${targetDir}`);
|
|
4451
4649
|
}
|
|
4452
4650
|
const jarFiles = readdirSync5(targetDir).filter((name) => name.endsWith(".jar") && !name.endsWith(".jar.original")).map((name) => path3.join(targetDir, name)).sort((a, b) => statSync6(b).mtimeMs - statSync6(a).mtimeMs);
|
|
@@ -4919,22 +5117,17 @@ async function runWisdomBackendDeploy(options) {
|
|
|
4919
5117
|
log("\u90E8\u7F72\u5B8C\u6210");
|
|
4920
5118
|
}
|
|
4921
5119
|
|
|
4922
|
-
// src/commands/deploy/internal/wisdom-
|
|
4923
|
-
function
|
|
5120
|
+
// src/commands/deploy/internal/wisdom-deploy.ts
|
|
5121
|
+
function isWisdomDeployConfigured(cfg) {
|
|
4924
5122
|
const w = cfg.wisdomDeploy;
|
|
4925
|
-
|
|
4926
|
-
return false;
|
|
4927
|
-
}
|
|
4928
|
-
const hasNewFrontend = Boolean(cfg.frontendDeploy?.endpoint?.trim());
|
|
4929
|
-
const hasNewBackend = Boolean(cfg.backendDeploy?.registryHost?.trim());
|
|
4930
|
-
return !hasNewFrontend && !hasNewBackend;
|
|
5123
|
+
return Boolean(w?.host?.trim() && w?.remotePath?.trim());
|
|
4931
5124
|
}
|
|
4932
5125
|
function detectWisdomProjectType(cwd) {
|
|
4933
|
-
return
|
|
5126
|
+
return existsSync16(path4.join(cwd, "package.json")) ? "frontend" : "backend";
|
|
4934
5127
|
}
|
|
4935
5128
|
function readPackageScripts(cwd) {
|
|
4936
5129
|
const pkgPath = path4.join(cwd, "package.json");
|
|
4937
|
-
if (!
|
|
5130
|
+
if (!existsSync16(pkgPath)) {
|
|
4938
5131
|
return {};
|
|
4939
5132
|
}
|
|
4940
5133
|
try {
|
|
@@ -4945,14 +5138,6 @@ function readPackageScripts(cwd) {
|
|
|
4945
5138
|
return {};
|
|
4946
5139
|
}
|
|
4947
5140
|
}
|
|
4948
|
-
function resolveFrontendDeployCommand(env, cwd) {
|
|
4949
|
-
const scripts = readPackageScripts(cwd);
|
|
4950
|
-
const deployKey = `deploy:${env}`;
|
|
4951
|
-
if (scripts[deployKey]?.trim()) {
|
|
4952
|
-
return `npm run deploy:${env}`;
|
|
4953
|
-
}
|
|
4954
|
-
return null;
|
|
4955
|
-
}
|
|
4956
5141
|
function resolveFrontendBuildCommand(env, cwd) {
|
|
4957
5142
|
const scripts = readPackageScripts(cwd);
|
|
4958
5143
|
const buildKey = `build:${env}`;
|
|
@@ -4966,7 +5151,7 @@ function resolveFrontendDistDir(cwd) {
|
|
|
4966
5151
|
for (const rel of candidates) {
|
|
4967
5152
|
const full = path4.join(cwd, rel);
|
|
4968
5153
|
try {
|
|
4969
|
-
if (
|
|
5154
|
+
if (existsSync16(full) && statSync7(full).isDirectory()) {
|
|
4970
5155
|
return full;
|
|
4971
5156
|
}
|
|
4972
5157
|
} catch {
|
|
@@ -4974,62 +5159,57 @@ function resolveFrontendDistDir(cwd) {
|
|
|
4974
5159
|
}
|
|
4975
5160
|
return path4.join(cwd, "dist");
|
|
4976
5161
|
}
|
|
4977
|
-
async function
|
|
4978
|
-
const cwd =
|
|
4979
|
-
const
|
|
4980
|
-
const
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
5162
|
+
async function executeWisdomFrontendDeploy(options) {
|
|
5163
|
+
const { cwd, cfg, captureOutput, packOnly, archiveDeployArtifact } = options;
|
|
5164
|
+
const buildCmd = resolveFrontendBuildCommand(options.env, cwd);
|
|
5165
|
+
const distDir = resolveFrontendDistDir(cwd);
|
|
5166
|
+
logWisdomFrontendDeployContext({
|
|
5167
|
+
env: options.env,
|
|
5168
|
+
cwd,
|
|
5169
|
+
buildCmd,
|
|
5170
|
+
distDir,
|
|
5171
|
+
packOnly,
|
|
5172
|
+
archiveDeployArtifact
|
|
5173
|
+
});
|
|
5174
|
+
if (!buildCmd) {
|
|
5175
|
+
const lines = formatWisdomFrontendBuildNotConfiguredLines(
|
|
5176
|
+
options.env,
|
|
5177
|
+
path4.join(cwd, "package.json")
|
|
5178
|
+
);
|
|
5179
|
+
throw new DeployExecutionError(lines.join("\n"), 1, lines.join("\n"));
|
|
5180
|
+
}
|
|
4984
5181
|
console.error(
|
|
4985
|
-
`[apm] \
|
|
5182
|
+
`[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" : ""))
|
|
4986
5183
|
);
|
|
4987
|
-
|
|
4988
|
-
|
|
4989
|
-
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
|
|
4996
|
-
|
|
4997
|
-
console.error(`[apm] \u524D\u7AEF\u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u6267\u884C ${buildCmd}`);
|
|
4998
|
-
runDeployShellCommand(buildCmd, cwd, captureOutput);
|
|
4999
|
-
const projectName = (cfg.name ?? "").trim();
|
|
5000
|
-
if (!projectName) {
|
|
5001
|
-
throw new DeployExecutionError(
|
|
5002
|
-
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09",
|
|
5003
|
-
1
|
|
5004
|
-
);
|
|
5005
|
-
}
|
|
5006
|
-
const settings2 = resolveWisdomDeployFromApmConfig(cfg);
|
|
5007
|
-
await runWisdomSftpDeploy({
|
|
5008
|
-
localDir: resolveFrontendDistDir(cwd),
|
|
5009
|
-
settings: settings2,
|
|
5010
|
-
extract: false,
|
|
5011
|
-
projectName,
|
|
5012
|
-
packOnly: true
|
|
5013
|
-
});
|
|
5014
|
-
return { projectType };
|
|
5015
|
-
}
|
|
5016
|
-
const deployCmd = resolveFrontendDeployCommand(options.env, cwd);
|
|
5017
|
-
if (!deployCmd) {
|
|
5018
|
-
const lines = formatWisdomFrontendDeployNotConfiguredLines(
|
|
5019
|
-
options.env,
|
|
5020
|
-
path4.join(cwd, "package.json")
|
|
5021
|
-
);
|
|
5022
|
-
throw new DeployExecutionError(lines.join("\n"), 1, lines.join("\n"));
|
|
5023
|
-
}
|
|
5024
|
-
runDeployShellCommand(deployCmd, cwd, captureOutput);
|
|
5025
|
-
return { projectType };
|
|
5184
|
+
runDeployShellCommand(buildCmd, cwd, captureOutput);
|
|
5185
|
+
let projectName = (cfg.name ?? "").trim();
|
|
5186
|
+
if ((packOnly || archiveDeployArtifact) && !projectName) {
|
|
5187
|
+
throw new DeployExecutionError(
|
|
5188
|
+
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09",
|
|
5189
|
+
1
|
|
5190
|
+
);
|
|
5191
|
+
}
|
|
5192
|
+
if (!projectName) {
|
|
5193
|
+
projectName = path4.basename(cwd);
|
|
5026
5194
|
}
|
|
5195
|
+
const settings = resolveWisdomDeployFromApmConfig(cfg);
|
|
5196
|
+
await runWisdomSftpDeploy({
|
|
5197
|
+
localDir: distDir,
|
|
5198
|
+
settings,
|
|
5199
|
+
extract: !packOnly,
|
|
5200
|
+
projectName,
|
|
5201
|
+
packOnly,
|
|
5202
|
+
archiveDeployArtifact
|
|
5203
|
+
});
|
|
5204
|
+
}
|
|
5205
|
+
async function executeWisdomBackendDeployFlow(options) {
|
|
5206
|
+
const { cwd, cfg, packOnly } = options;
|
|
5027
5207
|
const settings = resolveWisdomBackendDeployFromApmConfig(cfg);
|
|
5028
5208
|
if (packOnly) {
|
|
5029
|
-
console.error(`[apm] \
|
|
5209
|
+
console.error(`[apm] Java\uFF1AMaven \u6784\u5EFA\uFF08\u4EC5\u6253\u5305\uFF0C\u5FFD\u7565\u73AF\u5883 ${options.env}\uFF09`);
|
|
5030
5210
|
} else {
|
|
5031
5211
|
console.error(
|
|
5032
|
-
`[apm] \
|
|
5212
|
+
`[apm] Java\uFF1AMaven \u6784\u5EFA\u5E76\u90E8\u7F72\uFF08\u4E0D\u533A\u5206 test/online\uFF0C\u5FFD\u7565\u73AF\u5883 ${options.env}\uFF09`
|
|
5033
5213
|
);
|
|
5034
5214
|
}
|
|
5035
5215
|
await runWisdomBackendDeploy({
|
|
@@ -5037,11 +5217,40 @@ async function runWisdomAutoDeploy(options) {
|
|
|
5037
5217
|
projectRoot: cwd,
|
|
5038
5218
|
packOnly
|
|
5039
5219
|
});
|
|
5220
|
+
}
|
|
5221
|
+
async function executeWisdomDeploy(options) {
|
|
5222
|
+
const cwd = path4.resolve(options.cwd);
|
|
5223
|
+
const captureOutput = options.captureOutput ?? false;
|
|
5224
|
+
const packOnly = Boolean(options.packOnly);
|
|
5225
|
+
const archiveDeployArtifact = Boolean(options.archiveDeployArtifact);
|
|
5226
|
+
const projectType = detectWisdomProjectType(cwd);
|
|
5227
|
+
const configPath = options.configPath ?? path4.join(workspaceApmDir(cwd), "apm.config.json");
|
|
5228
|
+
const cfg = loadApmConfig({ configPath });
|
|
5229
|
+
console.error(
|
|
5230
|
+
`[apm] ${projectType === "frontend" ? "Vue \u524D\u7AEF" : "Java \u540E\u7AEF"}${packOnly ? "\uFF08\u4EC5\u6253\u5305\uFF09" : ""}`
|
|
5231
|
+
);
|
|
5232
|
+
if (projectType === "frontend") {
|
|
5233
|
+
await executeWisdomFrontendDeploy({
|
|
5234
|
+
...options,
|
|
5235
|
+
cwd,
|
|
5236
|
+
cfg,
|
|
5237
|
+
captureOutput,
|
|
5238
|
+
packOnly,
|
|
5239
|
+
archiveDeployArtifact
|
|
5240
|
+
});
|
|
5241
|
+
return { projectType };
|
|
5242
|
+
}
|
|
5243
|
+
await executeWisdomBackendDeployFlow({
|
|
5244
|
+
...options,
|
|
5245
|
+
cwd,
|
|
5246
|
+
cfg,
|
|
5247
|
+
packOnly
|
|
5248
|
+
});
|
|
5040
5249
|
return { projectType };
|
|
5041
5250
|
}
|
|
5042
5251
|
|
|
5043
5252
|
// src/commands/deploy/internal/deploy-baseline-sync.ts
|
|
5044
|
-
var
|
|
5253
|
+
var LOG_PREFIX2 = "[apm] \u90E8\u7F72\u524D\u57FA\u7EBF\u540C\u6B65:";
|
|
5045
5254
|
function formatGitError(error) {
|
|
5046
5255
|
return error instanceof Error ? error.message : String(error);
|
|
5047
5256
|
}
|
|
@@ -5077,20 +5286,20 @@ async function restoreWorkingTree(cwd) {
|
|
|
5077
5286
|
}
|
|
5078
5287
|
async function mergeBaselineBranch(cwd, baselineBranch, currentBranch, note) {
|
|
5079
5288
|
const mergeTarget = `origin/${baselineBranch}`;
|
|
5080
|
-
note(`${
|
|
5289
|
+
note(`${LOG_PREFIX2} \u5F00\u59CB\u5408\u5E76 ${mergeTarget} \u5230\u5F53\u524D\u5206\u652F ${currentBranch}`);
|
|
5081
5290
|
try {
|
|
5082
5291
|
if (currentBranch === baselineBranch) {
|
|
5083
5292
|
await execGit(cwd, ["merge", "--ff-only", mergeTarget]);
|
|
5084
5293
|
} else {
|
|
5085
5294
|
await execGit(cwd, ["merge", mergeTarget, "--no-edit"]);
|
|
5086
5295
|
}
|
|
5087
|
-
note(`${
|
|
5296
|
+
note(`${LOG_PREFIX2} \u5DF2\u5408\u5E76 ${mergeTarget} \u6700\u65B0\u4EE3\u7801`);
|
|
5088
5297
|
return { merged: true, conflictRollback: false };
|
|
5089
5298
|
} catch (error) {
|
|
5090
5299
|
await abortMergeIfNeeded(cwd);
|
|
5091
|
-
note(`${
|
|
5092
|
-
note(`${
|
|
5093
|
-
note(`${
|
|
5300
|
+
note(`${LOG_PREFIX2} \u5408\u5E76 ${mergeTarget} \u5931\u8D25: ${formatGitError(error)}`);
|
|
5301
|
+
note(`${LOG_PREFIX2} \u5DF2\u6267\u884C git merge --abort \u56DE\u9000\u5230\u5408\u5E76\u524D\u72B6\u6001`);
|
|
5302
|
+
note(`${LOG_PREFIX2} \u5C06\u4F7F\u7528\u56DE\u9000\u540E\u7684\u4EE3\u7801\u7EE7\u7EED\u90E8\u7F72`);
|
|
5094
5303
|
return { merged: false, conflictRollback: true };
|
|
5095
5304
|
}
|
|
5096
5305
|
}
|
|
@@ -5098,17 +5307,17 @@ async function restoreStashIfNeeded(cwd, stashed, note) {
|
|
|
5098
5307
|
if (!stashed) {
|
|
5099
5308
|
return false;
|
|
5100
5309
|
}
|
|
5101
|
-
note(`${
|
|
5310
|
+
note(`${LOG_PREFIX2} \u6B63\u5728\u6062\u590D stash \u4E2D\u7684\u672A\u63D0\u4EA4\u6539\u52A8`);
|
|
5102
5311
|
try {
|
|
5103
5312
|
await execGit(cwd, ["stash", "pop"], true);
|
|
5104
|
-
note(`${
|
|
5313
|
+
note(`${LOG_PREFIX2} \u5DF2\u6062\u590D stash \u4E2D\u7684\u672A\u63D0\u4EA4\u6539\u52A8`);
|
|
5105
5314
|
return false;
|
|
5106
5315
|
} catch (error) {
|
|
5107
5316
|
await abortMergeIfNeeded(cwd);
|
|
5108
5317
|
await restoreWorkingTree(cwd);
|
|
5109
|
-
note(`${
|
|
5110
|
-
note(`${
|
|
5111
|
-
note(`${
|
|
5318
|
+
note(`${LOG_PREFIX2} \u6062\u590D stash \u5931\u8D25: ${formatGitError(error)}`);
|
|
5319
|
+
note(`${LOG_PREFIX2} \u5DF2\u56DE\u9000\u5DE5\u4F5C\u533A\uFF08git reset --hard HEAD\uFF09\uFF0Cstash \u4ECD\u4FDD\u7559`);
|
|
5320
|
+
note(`${LOG_PREFIX2} \u5C06\u4F7F\u7528\u56DE\u9000\u540E\u7684\u4EE3\u7801\u7EE7\u7EED\u90E8\u7F72`);
|
|
5112
5321
|
return true;
|
|
5113
5322
|
}
|
|
5114
5323
|
}
|
|
@@ -5127,30 +5336,30 @@ async function syncDeployBaselineBeforeDeploy(cwd) {
|
|
|
5127
5336
|
...partial
|
|
5128
5337
|
});
|
|
5129
5338
|
if (!await isGitRepo(cwd)) {
|
|
5130
|
-
note(`${
|
|
5339
|
+
note(`${LOG_PREFIX2} \u5F53\u524D\u76EE\u5F55\u4E0D\u662F git \u4ED3\u5E93\uFF0C\u8DF3\u8FC7`);
|
|
5131
5340
|
return emptyResult();
|
|
5132
5341
|
}
|
|
5133
5342
|
const cfg = await tryReadApmConfig();
|
|
5134
5343
|
if (!cfg || !resolveApiKey(cfg)) {
|
|
5135
|
-
note(`${
|
|
5344
|
+
note(`${LOG_PREFIX2} \u672A\u767B\u5F55\uFF0C\u8DF3\u8FC7`);
|
|
5136
5345
|
return emptyResult();
|
|
5137
5346
|
}
|
|
5138
5347
|
await ensureGitRepo(cwd);
|
|
5139
5348
|
const api = createApmApiClient(cfg);
|
|
5140
5349
|
const baselineBranch = await resolveBaselineBranch2(cwd, api);
|
|
5141
|
-
note(`${
|
|
5142
|
-
note(`${
|
|
5350
|
+
note(`${LOG_PREFIX2} \u57FA\u7EBF\u5206\u652F ${baselineBranch}`);
|
|
5351
|
+
note(`${LOG_PREFIX2} \u6B63\u5728 fetch origin ${baselineBranch}`);
|
|
5143
5352
|
await execGit(cwd, ["fetch", "origin", baselineBranch], true);
|
|
5144
5353
|
if (!await remoteBranchExists(cwd, baselineBranch)) {
|
|
5145
5354
|
throw new Error(
|
|
5146
5355
|
`\u8FDC\u7A0B\u4E0D\u5B58\u5728\u57FA\u7EBF\u5206\u652F origin/${baselineBranch}\uFF0C\u8BF7\u786E\u8BA4\u4ED3\u5E93\u9ED8\u8BA4\u5206\u652F\u5DF2\u63A8\u9001\u5230 origin`
|
|
5147
5356
|
);
|
|
5148
5357
|
}
|
|
5149
|
-
note(`${
|
|
5358
|
+
note(`${LOG_PREFIX2} fetch \u5B8C\u6210`);
|
|
5150
5359
|
const currentBranch = await getCurrentBranch(cwd);
|
|
5151
5360
|
let stashed = false;
|
|
5152
5361
|
if (await isWorkingTreeDirty(cwd)) {
|
|
5153
|
-
note(`${
|
|
5362
|
+
note(`${LOG_PREFIX2} \u68C0\u6D4B\u5230\u672A\u63D0\u4EA4\u6539\u52A8\uFF0C\u5148 stash`);
|
|
5154
5363
|
await execGit(cwd, [
|
|
5155
5364
|
"stash",
|
|
5156
5365
|
"push",
|
|
@@ -5159,7 +5368,7 @@ async function syncDeployBaselineBeforeDeploy(cwd) {
|
|
|
5159
5368
|
"apm: deploy baseline sync"
|
|
5160
5369
|
]);
|
|
5161
5370
|
stashed = true;
|
|
5162
|
-
note(`${
|
|
5371
|
+
note(`${LOG_PREFIX2} \u5DF2 stash \u672A\u63D0\u4EA4\u6539\u52A8`);
|
|
5163
5372
|
}
|
|
5164
5373
|
const { merged, conflictRollback } = await mergeBaselineBranch(
|
|
5165
5374
|
cwd,
|
|
@@ -5169,10 +5378,10 @@ async function syncDeployBaselineBeforeDeploy(cwd) {
|
|
|
5169
5378
|
);
|
|
5170
5379
|
const stashConflict = await restoreStashIfNeeded(cwd, stashed, note);
|
|
5171
5380
|
if (conflictRollback || stashConflict) {
|
|
5172
|
-
note(`${
|
|
5381
|
+
note(`${LOG_PREFIX2} \u57FA\u7EBF\u540C\u6B65\u672A\u5B8C\u6210\uFF08\u5B58\u5728\u51B2\u7A81\u5E76\u5DF2\u56DE\u9000\uFF09\uFF0C\u7EE7\u7EED\u6267\u884C\u90E8\u7F72`);
|
|
5173
5382
|
} else if (merged) {
|
|
5174
5383
|
note(
|
|
5175
|
-
`${
|
|
5384
|
+
`${LOG_PREFIX2} \u5B8C\u6210\uFF08\u5F53\u524D\u5206\u652F ${currentBranch} \u5DF2\u5305\u542B ${baselineBranch} \u6700\u65B0\u4EE3\u7801\uFF09`
|
|
5176
5385
|
);
|
|
5177
5386
|
}
|
|
5178
5387
|
return {
|
|
@@ -5186,10 +5395,26 @@ async function syncDeployBaselineBeforeDeploy(cwd) {
|
|
|
5186
5395
|
|
|
5187
5396
|
// src/commands/deploy/deploy-execute.ts
|
|
5188
5397
|
async function executeDeploy(options) {
|
|
5189
|
-
const
|
|
5398
|
+
const cwdInput = options.cwd.trim();
|
|
5399
|
+
if (!cwdInput) {
|
|
5400
|
+
throw new DeployExecutionError("[apm] executeDeploy \u7F3A\u5C11\u5DE5\u4F5C\u76EE\u5F55 cwd", 1);
|
|
5401
|
+
}
|
|
5402
|
+
const cwd = resolveWorkdirPath(cwdInput);
|
|
5190
5403
|
const apmConfigPath = options.configPath ?? path5.join(workspaceApmDir(cwd), "apm.config.json");
|
|
5191
5404
|
const captureOutput = options.captureOutput ?? false;
|
|
5192
5405
|
const outputParts = [];
|
|
5406
|
+
logExecuteDeployContext({
|
|
5407
|
+
trigger: options.deployTrigger,
|
|
5408
|
+
env: options.env,
|
|
5409
|
+
cwd,
|
|
5410
|
+
cwdInput,
|
|
5411
|
+
processCwd: process.cwd(),
|
|
5412
|
+
apmConfigPath,
|
|
5413
|
+
captureOutput,
|
|
5414
|
+
packOnly: options.packOnly,
|
|
5415
|
+
archiveDeployArtifact: options.archiveDeployArtifact,
|
|
5416
|
+
configPathOption: options.configPath
|
|
5417
|
+
});
|
|
5193
5418
|
try {
|
|
5194
5419
|
const configSyncResult = await syncRemoteDeploymentConfig(
|
|
5195
5420
|
cwd,
|
|
@@ -5212,36 +5437,29 @@ async function executeDeploy(options) {
|
|
|
5212
5437
|
detail
|
|
5213
5438
|
);
|
|
5214
5439
|
}
|
|
5440
|
+
const preDeployLog = outputParts.join("\n");
|
|
5215
5441
|
const cfg = loadApmConfig({ configPath: apmConfigPath });
|
|
5216
|
-
if (
|
|
5217
|
-
|
|
5218
|
-
await runWisdomAutoDeploy({
|
|
5219
|
-
env: options.env,
|
|
5220
|
-
cwd,
|
|
5221
|
-
configPath: apmConfigPath,
|
|
5222
|
-
captureOutput,
|
|
5223
|
-
packOnly: options.packOnly
|
|
5224
|
-
});
|
|
5225
|
-
return outputParts.join("\n");
|
|
5226
|
-
} catch (error) {
|
|
5227
|
-
if (error instanceof DeployExecutionError) {
|
|
5228
|
-
throw error;
|
|
5229
|
-
}
|
|
5230
|
-
const detail = error instanceof Error ? error.message : String(error);
|
|
5231
|
-
throw new DeployExecutionError(detail, 1);
|
|
5232
|
-
}
|
|
5233
|
-
}
|
|
5234
|
-
const deployCommands = cfg.deploy ?? {};
|
|
5235
|
-
const command = deployCommands[options.env]?.trim();
|
|
5236
|
-
if (!command) {
|
|
5237
|
-
const lines = formatDeployNotConfiguredLines(options.env, deployCommands);
|
|
5442
|
+
if (!isWisdomDeployConfigured(cfg)) {
|
|
5443
|
+
const lines = formatMissingWisdomDeployLines();
|
|
5238
5444
|
throw new DeployExecutionError(lines.join("\n"), 1, lines.join("\n"));
|
|
5239
5445
|
}
|
|
5240
|
-
|
|
5241
|
-
|
|
5242
|
-
|
|
5446
|
+
try {
|
|
5447
|
+
await executeWisdomDeploy({
|
|
5448
|
+
env: options.env,
|
|
5449
|
+
cwd,
|
|
5450
|
+
configPath: apmConfigPath,
|
|
5451
|
+
captureOutput,
|
|
5452
|
+
packOnly: options.packOnly,
|
|
5453
|
+
archiveDeployArtifact: options.archiveDeployArtifact
|
|
5454
|
+
});
|
|
5455
|
+
return preDeployLog;
|
|
5456
|
+
} catch (error) {
|
|
5457
|
+
if (error instanceof DeployExecutionError) {
|
|
5458
|
+
throw error;
|
|
5459
|
+
}
|
|
5460
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
5461
|
+
throw new DeployExecutionError(detail, 1);
|
|
5243
5462
|
}
|
|
5244
|
-
return outputParts.join("\n");
|
|
5245
5463
|
}
|
|
5246
5464
|
function printDeployExecutionError(error) {
|
|
5247
5465
|
if (error.output.trim()) {
|
|
@@ -5390,7 +5608,9 @@ async function handleInboundDeploy(cfg, msg, signal) {
|
|
|
5390
5608
|
env: msg.environment,
|
|
5391
5609
|
cwd: workdir,
|
|
5392
5610
|
packOnly: msg.packOnly,
|
|
5393
|
-
captureOutput: true
|
|
5611
|
+
captureOutput: true,
|
|
5612
|
+
archiveDeployArtifact: true,
|
|
5613
|
+
deployTrigger: "connect"
|
|
5394
5614
|
};
|
|
5395
5615
|
try {
|
|
5396
5616
|
if (signal.aborted) return;
|
|
@@ -5706,13 +5926,13 @@ ${JSON.stringify(event, null, 2)}
|
|
|
5706
5926
|
}
|
|
5707
5927
|
|
|
5708
5928
|
// src/commands/connect/agent-session-registry.ts
|
|
5709
|
-
import { existsSync as
|
|
5710
|
-
import { dirname as
|
|
5929
|
+
import { existsSync as existsSync17, mkdirSync as mkdirSync8, readFileSync as readFileSync14, writeFileSync as writeFileSync13 } from "node:fs";
|
|
5930
|
+
import { dirname as dirname6, resolve as resolve4 } from "node:path";
|
|
5711
5931
|
function registryPath(workdir, sessionId) {
|
|
5712
5932
|
return resolve4(workdir, ".apm", "sessions", sessionId, "cursor-agents.json");
|
|
5713
5933
|
}
|
|
5714
5934
|
function readRegistry(path13) {
|
|
5715
|
-
if (!
|
|
5935
|
+
if (!existsSync17(path13)) {
|
|
5716
5936
|
return {};
|
|
5717
5937
|
}
|
|
5718
5938
|
try {
|
|
@@ -5733,7 +5953,7 @@ function readRegistry(path13) {
|
|
|
5733
5953
|
return {};
|
|
5734
5954
|
}
|
|
5735
5955
|
function writeRegistry(path13, registry) {
|
|
5736
|
-
mkdirSync8(
|
|
5956
|
+
mkdirSync8(dirname6(path13), { recursive: true });
|
|
5737
5957
|
writeFileSync13(path13, `${JSON.stringify(registry, null, 2)}
|
|
5738
5958
|
`, "utf8");
|
|
5739
5959
|
}
|
|
@@ -6184,15 +6404,15 @@ async function ensureMessageHasReply(cfg, sessionId, messageId, fallback) {
|
|
|
6184
6404
|
}
|
|
6185
6405
|
|
|
6186
6406
|
// src/commands/connect/cli-version-sync.ts
|
|
6187
|
-
import { existsSync as
|
|
6188
|
-
import { join as
|
|
6407
|
+
import { existsSync as existsSync18, readFileSync as readFileSync15, writeFileSync as writeFileSync14 } from "fs";
|
|
6408
|
+
import { join as join17 } from "path";
|
|
6189
6409
|
var CLI_VERSION_FILE = ".cli-version.json";
|
|
6190
6410
|
function manifestPath(apmDir) {
|
|
6191
|
-
return
|
|
6411
|
+
return join17(apmDir, CLI_VERSION_FILE);
|
|
6192
6412
|
}
|
|
6193
6413
|
function loadManifest4(apmDir) {
|
|
6194
6414
|
const path13 = toFsPath(manifestPath(apmDir));
|
|
6195
|
-
if (!
|
|
6415
|
+
if (!existsSync18(path13)) {
|
|
6196
6416
|
return null;
|
|
6197
6417
|
}
|
|
6198
6418
|
try {
|
|
@@ -6260,23 +6480,53 @@ function markPullDone(sessionId, workdir) {
|
|
|
6260
6480
|
|
|
6261
6481
|
// src/commands/connect/run-slot-pool.ts
|
|
6262
6482
|
var DEFAULT_MAX_CONCURRENT = 5;
|
|
6263
|
-
function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT) {
|
|
6483
|
+
function createRunSlotPool(maxConcurrent = DEFAULT_MAX_CONCURRENT, options = {}) {
|
|
6484
|
+
const label = options.label ?? "task";
|
|
6485
|
+
const isDeployPool = label === "deploy";
|
|
6264
6486
|
let active = 0;
|
|
6265
6487
|
const waiters = [];
|
|
6266
|
-
const
|
|
6488
|
+
const logDeploy = (message) => {
|
|
6489
|
+
if (isDeployPool) {
|
|
6490
|
+
console.error(`[apm] deploy \u4E32\u884C\u9650\u6D41\uFF1A${message}`);
|
|
6491
|
+
}
|
|
6492
|
+
};
|
|
6493
|
+
const acquire = (meta) => {
|
|
6267
6494
|
if (active < maxConcurrent) {
|
|
6268
6495
|
active += 1;
|
|
6496
|
+
if (isDeployPool) {
|
|
6497
|
+
logDeploy(
|
|
6498
|
+
`\u5F00\u59CB\u6267\u884C${meta ? `\uFF08${meta}\uFF09` : ""}\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`
|
|
6499
|
+
);
|
|
6500
|
+
}
|
|
6269
6501
|
return Promise.resolve();
|
|
6270
6502
|
}
|
|
6503
|
+
const queueIndex = waiters.length + 1;
|
|
6504
|
+
if (isDeployPool) {
|
|
6505
|
+
logDeploy(
|
|
6506
|
+
`\u5E76\u53D1\u5DF2\u6EE1\uFF08${maxConcurrent}/${maxConcurrent}\uFF09\uFF0C${meta ? `${meta} ` : ""}\u8FDB\u5165\u6392\u961F\uFF0C\u524D\u65B9 ${queueIndex} \u4E2A`
|
|
6507
|
+
);
|
|
6508
|
+
}
|
|
6509
|
+
const queuedAt = Date.now();
|
|
6271
6510
|
return new Promise((resolve5) => {
|
|
6272
6511
|
waiters.push(() => {
|
|
6273
6512
|
active += 1;
|
|
6513
|
+
const waitedMs = Date.now() - queuedAt;
|
|
6514
|
+
if (isDeployPool) {
|
|
6515
|
+
logDeploy(
|
|
6516
|
+
`\u6392\u961F\u7ED3\u675F\uFF0C\u5F00\u59CB\u6267\u884C${meta ? `\uFF08${meta}\uFF09` : ""}\uFF0C\u7B49\u5F85 ${Math.ceil(
|
|
6517
|
+
waitedMs / 1e3
|
|
6518
|
+
)}s\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`
|
|
6519
|
+
);
|
|
6520
|
+
}
|
|
6274
6521
|
resolve5();
|
|
6275
6522
|
});
|
|
6276
6523
|
});
|
|
6277
6524
|
};
|
|
6278
6525
|
const release = () => {
|
|
6279
6526
|
active = Math.max(0, active - 1);
|
|
6527
|
+
if (isDeployPool) {
|
|
6528
|
+
logDeploy(`\u6267\u884C\u69FD\u91CA\u653E\uFF0C\u5F53\u524D\u5360\u7528 ${active}/${maxConcurrent}`);
|
|
6529
|
+
}
|
|
6280
6530
|
const next = waiters.shift();
|
|
6281
6531
|
if (next) {
|
|
6282
6532
|
next();
|
|
@@ -6473,6 +6723,7 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
6473
6723
|
clientMachineId,
|
|
6474
6724
|
shutdownAbort,
|
|
6475
6725
|
runSlots,
|
|
6726
|
+
deployRunSlots,
|
|
6476
6727
|
activeTasks,
|
|
6477
6728
|
activeRuns,
|
|
6478
6729
|
pendingCancels,
|
|
@@ -6511,12 +6762,13 @@ function attachWsHandlers(ws, ctx, onOpen) {
|
|
|
6511
6762
|
shutdownAbort.signal,
|
|
6512
6763
|
perDeployController.signal
|
|
6513
6764
|
]);
|
|
6765
|
+
const deploySlotMeta = `deploymentRunId=${msg2.deploymentRunId} env=${msg2.environment} workdir=${msg2.workdir}`;
|
|
6514
6766
|
const task2 = (async () => {
|
|
6515
|
-
await
|
|
6767
|
+
await deployRunSlots.acquire(deploySlotMeta);
|
|
6516
6768
|
try {
|
|
6517
6769
|
await handleInboundDeploy(cfg, msg2, signal2);
|
|
6518
6770
|
} finally {
|
|
6519
|
-
|
|
6771
|
+
deployRunSlots.release();
|
|
6520
6772
|
}
|
|
6521
6773
|
})();
|
|
6522
6774
|
activeTasks.add(task2);
|
|
@@ -6674,6 +6926,7 @@ async function runConnect(options) {
|
|
|
6674
6926
|
const lifecycleAbort = new AbortController();
|
|
6675
6927
|
const shutdownAbort = new AbortController();
|
|
6676
6928
|
const runSlots = createRunSlotPool();
|
|
6929
|
+
const deployRunSlots = createRunSlotPool(1, { label: "deploy" });
|
|
6677
6930
|
const activeTasks = /* @__PURE__ */ new Set();
|
|
6678
6931
|
const activeRuns = /* @__PURE__ */ new Map();
|
|
6679
6932
|
const pendingCancels = /* @__PURE__ */ new Set();
|
|
@@ -6683,6 +6936,7 @@ async function runConnect(options) {
|
|
|
6683
6936
|
clientMachineId,
|
|
6684
6937
|
shutdownAbort,
|
|
6685
6938
|
runSlots,
|
|
6939
|
+
deployRunSlots,
|
|
6686
6940
|
activeTasks,
|
|
6687
6941
|
activeRuns,
|
|
6688
6942
|
pendingCancels,
|
|
@@ -6921,7 +7175,7 @@ async function runDeployWithBackendTracking(options) {
|
|
|
6921
7175
|
const run = await api.cli.createTaskDeployment({
|
|
6922
7176
|
sessionId: options.sessionId,
|
|
6923
7177
|
environment,
|
|
6924
|
-
workdirPath: options.cwd
|
|
7178
|
+
workdirPath: options.cwd
|
|
6925
7179
|
});
|
|
6926
7180
|
deploymentRunId = run.id;
|
|
6927
7181
|
console.log(
|
|
@@ -6957,7 +7211,11 @@ async function runDeployWithBackendTracking(options) {
|
|
|
6957
7211
|
originalError.apply(console, args);
|
|
6958
7212
|
};
|
|
6959
7213
|
try {
|
|
6960
|
-
const output = await executeDeploy({
|
|
7214
|
+
const output = await executeDeploy({
|
|
7215
|
+
...options,
|
|
7216
|
+
captureOutput: true,
|
|
7217
|
+
archiveDeployArtifact: true
|
|
7218
|
+
});
|
|
6961
7219
|
if (output.trim()) {
|
|
6962
7220
|
appendLog(output);
|
|
6963
7221
|
}
|
|
@@ -7000,8 +7258,8 @@ async function runDeployWithBackendTracking(options) {
|
|
|
7000
7258
|
// src/commands/deploy/deploy.ts
|
|
7001
7259
|
function registerDeployMainCommand(program) {
|
|
7002
7260
|
program.command("deploy").description(
|
|
7003
|
-
"\
|
|
7004
|
-
).argument("<env>", "\u90E8\u7F72\u73AF\u5883\u540D\uFF08\u5982 test\u3001online\uFF09").option(
|
|
7261
|
+
"\u533B\u52A1\u90E8\u7F72\uFF1AVue build + SFTP / Java Maven + SSH\uFF08\u9700 apm.config.json wisdomDeploy\uFF09"
|
|
7262
|
+
).argument("<env>", "\u90E8\u7F72\u73AF\u5883\u540D\uFF08\u5982 test\u3001online\uFF1BVue \u5BF9\u5E94 build:<env>\uFF09").option(
|
|
7005
7263
|
"--config <path>",
|
|
7006
7264
|
"apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
|
|
7007
7265
|
).option(
|
|
@@ -7009,7 +7267,7 @@ function registerDeployMainCommand(program) {
|
|
|
7009
7267
|
"\u6C9F\u901A\u7FA4 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7"
|
|
7010
7268
|
).option(
|
|
7011
7269
|
"--pack-only",
|
|
7012
|
-
"\u4EC5\u6784\u5EFA/\u6253\u5305\
|
|
7270
|
+
"\u4EC5\u6784\u5EFA/\u6253\u5305\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B SFTP/SSH\uFF1B\u53EF\u5F52\u6863\u5E73\u53F0\u90E8\u7F72\u4EA7\u7269"
|
|
7013
7271
|
).action(
|
|
7014
7272
|
async (env, opts) => {
|
|
7015
7273
|
const cwd = process.cwd();
|
|
@@ -7022,11 +7280,18 @@ function registerDeployMainCommand(program) {
|
|
|
7022
7280
|
cwd,
|
|
7023
7281
|
configPath: opts.config,
|
|
7024
7282
|
sessionId,
|
|
7025
|
-
packOnly
|
|
7283
|
+
packOnly,
|
|
7284
|
+
deployTrigger: "session"
|
|
7026
7285
|
});
|
|
7027
7286
|
return;
|
|
7028
7287
|
}
|
|
7029
|
-
await executeDeploy({
|
|
7288
|
+
await executeDeploy({
|
|
7289
|
+
env,
|
|
7290
|
+
cwd,
|
|
7291
|
+
configPath: opts.config,
|
|
7292
|
+
packOnly,
|
|
7293
|
+
deployTrigger: "cli"
|
|
7294
|
+
});
|
|
7030
7295
|
} catch (error) {
|
|
7031
7296
|
if (error instanceof DeployExecutionError) {
|
|
7032
7297
|
printDeployExecutionError(error);
|
|
@@ -7048,7 +7313,7 @@ import path9 from "node:path";
|
|
|
7048
7313
|
import Docker from "dockerode";
|
|
7049
7314
|
|
|
7050
7315
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/connection-options.ts
|
|
7051
|
-
import { existsSync as
|
|
7316
|
+
import { existsSync as existsSync19, readFileSync as readFileSync16 } from "node:fs";
|
|
7052
7317
|
import path6 from "node:path";
|
|
7053
7318
|
function asOptionalTlsBuffer(value) {
|
|
7054
7319
|
if (typeof value !== "string") {
|
|
@@ -7060,7 +7325,7 @@ function asOptionalTlsBuffer(value) {
|
|
|
7060
7325
|
if (normalized === "") {
|
|
7061
7326
|
return void 0;
|
|
7062
7327
|
}
|
|
7063
|
-
if (
|
|
7328
|
+
if (existsSync19(normalized)) {
|
|
7064
7329
|
return readFileSync16(normalized);
|
|
7065
7330
|
}
|
|
7066
7331
|
const looksLikePath = /[\\/]/.test(normalized) || normalized.endsWith(".pem");
|
|
@@ -7271,7 +7536,7 @@ var DockerodeClient = class {
|
|
|
7271
7536
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
7272
7537
|
|
|
7273
7538
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
7274
|
-
import { existsSync as
|
|
7539
|
+
import { existsSync as existsSync20, readFileSync as readFileSync17, statSync as statSync8 } from "node:fs";
|
|
7275
7540
|
import path7 from "node:path";
|
|
7276
7541
|
function stripSurroundingQuotes(value) {
|
|
7277
7542
|
const t = value.trim();
|
|
@@ -7288,7 +7553,7 @@ function loadEnvFromFile(envFilePath) {
|
|
|
7288
7553
|
return {};
|
|
7289
7554
|
}
|
|
7290
7555
|
const targetPath = path7.resolve(envFilePath);
|
|
7291
|
-
if (!
|
|
7556
|
+
if (!existsSync20(targetPath) || !statSync8(targetPath).isFile()) {
|
|
7292
7557
|
return {};
|
|
7293
7558
|
}
|
|
7294
7559
|
const raw = readFileSync17(targetPath, "utf-8");
|
|
@@ -7462,12 +7727,12 @@ function dockerPushImage(params, cwd) {
|
|
|
7462
7727
|
}
|
|
7463
7728
|
|
|
7464
7729
|
// src/commands/deploy/internal/backend-deploy/resolve-dockerfile.ts
|
|
7465
|
-
import { existsSync as
|
|
7730
|
+
import { existsSync as existsSync21 } from "node:fs";
|
|
7466
7731
|
import path8 from "node:path";
|
|
7467
7732
|
function resolveDockerBuildPaths(cwd) {
|
|
7468
7733
|
const dockerfilePath = path8.join(cwd, "Dockerfile");
|
|
7469
7734
|
Logger.info(`\u67E5\u627EDockerfile\u6587\u4EF6\uFF0C\u8DEF\u5F84: ${dockerfilePath}`);
|
|
7470
|
-
if (!
|
|
7735
|
+
if (!existsSync21(dockerfilePath)) {
|
|
7471
7736
|
throw new Error(`Dockerfile \u4E0D\u5B58\u5728\uFF1A${dockerfilePath}`);
|
|
7472
7737
|
}
|
|
7473
7738
|
Logger.info("\u2713 Dockerfile \u5B58\u5728");
|