ai-project-manage-cli 8.0.12 → 8.0.14
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/webide-message-worker.js +108 -56
- package/package.json +1 -1
- package/template/rules/webide_package.md +14 -12
|
@@ -205,8 +205,8 @@ function toFsPath(inputPath) {
|
|
|
205
205
|
}
|
|
206
206
|
return `\\\\?\\${normalized}`;
|
|
207
207
|
}
|
|
208
|
-
function normalizeWorkdirPath(
|
|
209
|
-
let normalized =
|
|
208
|
+
function normalizeWorkdirPath(path2) {
|
|
209
|
+
let normalized = path2.trim().replace(/\\/g, "/").normalize("NFC");
|
|
210
210
|
if (normalized.startsWith("//?/")) {
|
|
211
211
|
normalized = normalized.slice(4);
|
|
212
212
|
}
|
|
@@ -328,9 +328,9 @@ function listWebIdeRuleFileNames(rulesDir) {
|
|
|
328
328
|
function assertWebIdeTemplateCopiedToApm(apmDir, workdir) {
|
|
329
329
|
const required = ["AGENTS.md", "rules"];
|
|
330
330
|
for (const item of required) {
|
|
331
|
-
const
|
|
332
|
-
if (!existsSync(toFsPath(
|
|
333
|
-
throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${
|
|
331
|
+
const path2 = join2(apmDir, item);
|
|
332
|
+
if (!existsSync(toFsPath(path2))) {
|
|
333
|
+
throw new Error(`[apm] WebIDE \u521D\u59CB\u5316\u4E0D\u5B8C\u6574\uFF0C\u7F3A\u5C11: ${path2}`);
|
|
334
334
|
}
|
|
335
335
|
}
|
|
336
336
|
const rulesDir = join2(apmDir, "rules");
|
|
@@ -614,13 +614,13 @@ function normalizeRepoEntry(raw) {
|
|
|
614
614
|
return entry;
|
|
615
615
|
}
|
|
616
616
|
function readManifest(workdir) {
|
|
617
|
-
const
|
|
618
|
-
if (!existsSync2(
|
|
617
|
+
const path2 = toFsPath(manifestPath(workdir));
|
|
618
|
+
if (!existsSync2(path2)) {
|
|
619
619
|
return null;
|
|
620
620
|
}
|
|
621
621
|
try {
|
|
622
622
|
const raw = JSON.parse(
|
|
623
|
-
readFileSync2(
|
|
623
|
+
readFileSync2(path2, "utf8")
|
|
624
624
|
);
|
|
625
625
|
if (raw?.version !== WORKSPACE_REPOS_VERSION) {
|
|
626
626
|
return null;
|
|
@@ -652,8 +652,8 @@ function readManifest(workdir) {
|
|
|
652
652
|
function writeManifest(workdir, manifest) {
|
|
653
653
|
const apmDir = toFsPath(workspaceApmDir(workdir));
|
|
654
654
|
mkdirSync3(apmDir, { recursive: true });
|
|
655
|
-
const
|
|
656
|
-
writeFileSync2(
|
|
655
|
+
const path2 = toFsPath(manifestPath(workdir));
|
|
656
|
+
writeFileSync2(path2, `${JSON.stringify(manifest, null, 2)}
|
|
657
657
|
`, "utf8");
|
|
658
658
|
}
|
|
659
659
|
function manifestStillValid(workdir, manifest) {
|
|
@@ -2226,12 +2226,12 @@ import { dirname as dirname3, resolve as resolve5 } from "node:path";
|
|
|
2226
2226
|
function registryPath(workdir, taskId) {
|
|
2227
2227
|
return resolve5(workdir, ".apm", "webide", taskId, "cursor-agent.json");
|
|
2228
2228
|
}
|
|
2229
|
-
function readRegistry(
|
|
2230
|
-
if (!existsSync4(
|
|
2229
|
+
function readRegistry(path2) {
|
|
2230
|
+
if (!existsSync4(path2)) {
|
|
2231
2231
|
return {};
|
|
2232
2232
|
}
|
|
2233
2233
|
try {
|
|
2234
|
-
const parsed = JSON.parse(readFileSync4(
|
|
2234
|
+
const parsed = JSON.parse(readFileSync4(path2, "utf8"));
|
|
2235
2235
|
if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
2236
2236
|
const raw = parsed;
|
|
2237
2237
|
const state = {};
|
|
@@ -2259,16 +2259,16 @@ function readRegistry(path) {
|
|
|
2259
2259
|
}
|
|
2260
2260
|
return {};
|
|
2261
2261
|
}
|
|
2262
|
-
function writeRegistry(
|
|
2263
|
-
mkdirSync4(dirname3(
|
|
2264
|
-
writeFileSync3(
|
|
2262
|
+
function writeRegistry(path2, registry) {
|
|
2263
|
+
mkdirSync4(dirname3(path2), { recursive: true });
|
|
2264
|
+
writeFileSync3(path2, `${JSON.stringify(registry, null, 2)}
|
|
2265
2265
|
`, "utf8");
|
|
2266
2266
|
}
|
|
2267
2267
|
function syncWebIdeTaskState(workdir, taskId, patch) {
|
|
2268
2268
|
const trimmedTaskId = taskId.trim();
|
|
2269
2269
|
if (!trimmedTaskId) return;
|
|
2270
|
-
const
|
|
2271
|
-
const current = readRegistry(
|
|
2270
|
+
const path2 = registryPath(workdir, trimmedTaskId);
|
|
2271
|
+
const current = readRegistry(path2);
|
|
2272
2272
|
const next = {
|
|
2273
2273
|
...current,
|
|
2274
2274
|
taskId: trimmedTaskId,
|
|
@@ -2292,7 +2292,7 @@ function syncWebIdeTaskState(workdir, taskId, patch) {
|
|
|
2292
2292
|
if (patch.status !== void 0) {
|
|
2293
2293
|
next.status = patch.status;
|
|
2294
2294
|
}
|
|
2295
|
-
writeRegistry(
|
|
2295
|
+
writeRegistry(path2, next);
|
|
2296
2296
|
}
|
|
2297
2297
|
function loadWebIdeAgentId(workdir, taskId) {
|
|
2298
2298
|
return readRegistry(registryPath(workdir, taskId)).agentId;
|
|
@@ -2301,8 +2301,8 @@ function saveWebIdeAgentId(workdir, taskId, agentId) {
|
|
|
2301
2301
|
syncWebIdeTaskState(workdir, taskId, { agentId });
|
|
2302
2302
|
}
|
|
2303
2303
|
function clearWebIdeAgentId(workdir, taskId) {
|
|
2304
|
-
const
|
|
2305
|
-
if (!existsSync4(
|
|
2304
|
+
const path2 = registryPath(workdir, taskId);
|
|
2305
|
+
if (!existsSync4(path2)) return;
|
|
2306
2306
|
syncWebIdeTaskState(workdir, taskId, { agentId: "" });
|
|
2307
2307
|
}
|
|
2308
2308
|
|
|
@@ -2502,6 +2502,10 @@ var MinioClient = class {
|
|
|
2502
2502
|
async putObject(bucket, objectKey, body, meta) {
|
|
2503
2503
|
await this.inner.putObject(bucket, objectKey, body, body.length, meta);
|
|
2504
2504
|
}
|
|
2505
|
+
/** 大文件:从本地路径流式上传,避免整包读入内存 */
|
|
2506
|
+
async fPutObject(bucket, objectKey, filePath, meta) {
|
|
2507
|
+
await this.inner.fPutObject(bucket, objectKey, filePath, meta);
|
|
2508
|
+
}
|
|
2505
2509
|
};
|
|
2506
2510
|
|
|
2507
2511
|
// src/commands/connect/apm-log-minio.ts
|
|
@@ -2519,7 +2523,8 @@ async function createApmLogMinioClient(cfg) {
|
|
|
2519
2523
|
accessKey: storage.accessKey,
|
|
2520
2524
|
secretKey: storage.secretKey
|
|
2521
2525
|
}),
|
|
2522
|
-
bucket: storage.bucket
|
|
2526
|
+
bucket: storage.bucket,
|
|
2527
|
+
...storage.publicEndpoint ? { publicEndpoint: storage.publicEndpoint } : {}
|
|
2523
2528
|
};
|
|
2524
2529
|
}
|
|
2525
2530
|
|
|
@@ -2949,13 +2954,13 @@ async function downloadAttachment(cfg, attachmentId) {
|
|
|
2949
2954
|
return Buffer.from(await res.arrayBuffer());
|
|
2950
2955
|
}
|
|
2951
2956
|
function loadManifest(dir) {
|
|
2952
|
-
const
|
|
2953
|
-
if (!existsSync6(
|
|
2957
|
+
const path2 = join5(dir, MANIFEST_FILE);
|
|
2958
|
+
if (!existsSync6(path2)) {
|
|
2954
2959
|
return { version: 1, attachments: {} };
|
|
2955
2960
|
}
|
|
2956
2961
|
try {
|
|
2957
2962
|
const parsed = JSON.parse(
|
|
2958
|
-
readFileSync6(
|
|
2963
|
+
readFileSync6(path2, "utf8")
|
|
2959
2964
|
);
|
|
2960
2965
|
if (parsed?.version === 1 && parsed.attachments && typeof parsed.attachments === "object") {
|
|
2961
2966
|
return parsed;
|
|
@@ -3050,14 +3055,14 @@ function projectDocumentLocalPath(apmRoot, projectId, documentPath) {
|
|
|
3050
3055
|
...normalized.split("/")
|
|
3051
3056
|
);
|
|
3052
3057
|
}
|
|
3053
|
-
function normalizeLocalDocumentPath(
|
|
3054
|
-
const trimmed =
|
|
3058
|
+
function normalizeLocalDocumentPath(path2) {
|
|
3059
|
+
const trimmed = path2.trim().replace(/\\/g, "/");
|
|
3055
3060
|
if (!trimmed || trimmed.startsWith("/") || /^[a-zA-Z]:/.test(trimmed)) {
|
|
3056
|
-
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${
|
|
3061
|
+
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path2}`);
|
|
3057
3062
|
}
|
|
3058
3063
|
const segments = trimmed.split("/").filter(Boolean);
|
|
3059
3064
|
if (segments.some((segment) => segment === ".." || segment === ".")) {
|
|
3060
|
-
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${
|
|
3065
|
+
throw new Error(`\u975E\u6CD5\u6587\u6863\u8DEF\u5F84: ${path2}`);
|
|
3061
3066
|
}
|
|
3062
3067
|
return segments.join("/");
|
|
3063
3068
|
}
|
|
@@ -3111,15 +3116,15 @@ function diffManifestPaths(remote, local) {
|
|
|
3111
3116
|
(local?.documents ?? []).map((doc) => [doc.path, doc.contentHash])
|
|
3112
3117
|
);
|
|
3113
3118
|
const download = [];
|
|
3114
|
-
for (const [
|
|
3115
|
-
if (localMap.get(
|
|
3116
|
-
download.push(
|
|
3119
|
+
for (const [path2, hash] of remoteMap) {
|
|
3120
|
+
if (localMap.get(path2) !== hash) {
|
|
3121
|
+
download.push(path2);
|
|
3117
3122
|
}
|
|
3118
3123
|
}
|
|
3119
3124
|
const deleteLocal = [];
|
|
3120
|
-
for (const
|
|
3121
|
-
if (!remoteMap.has(
|
|
3122
|
-
deleteLocal.push(
|
|
3125
|
+
for (const path2 of localMap.keys()) {
|
|
3126
|
+
if (!remoteMap.has(path2)) {
|
|
3127
|
+
deleteLocal.push(path2);
|
|
3123
3128
|
}
|
|
3124
3129
|
}
|
|
3125
3130
|
return { download, deleteLocal };
|
|
@@ -3213,9 +3218,9 @@ ${diagnostic ?? ""}`);
|
|
|
3213
3218
|
}
|
|
3214
3219
|
}
|
|
3215
3220
|
let deleted = 0;
|
|
3216
|
-
for (const
|
|
3221
|
+
for (const path2 of deleteLocal) {
|
|
3217
3222
|
const absPath = toFsPath(
|
|
3218
|
-
projectDocumentLocalPath(targetApmDir, projectId,
|
|
3223
|
+
projectDocumentLocalPath(targetApmDir, projectId, path2)
|
|
3219
3224
|
);
|
|
3220
3225
|
if (existsSync7(absPath)) {
|
|
3221
3226
|
rmSync2(absPath, { force: true });
|
|
@@ -3262,23 +3267,23 @@ async function syncProjectDocumentsPush(cfg, workdirPath, apmRoot, options) {
|
|
|
3262
3267
|
(remoteManifest?.documents ?? []).map((doc) => [doc.path, doc.description])
|
|
3263
3268
|
);
|
|
3264
3269
|
let synced = 0;
|
|
3265
|
-
for (const
|
|
3270
|
+
for (const path2 of localPaths) {
|
|
3266
3271
|
const absPath = toFsPath(
|
|
3267
|
-
projectDocumentLocalPath(targetApmDir, projectId,
|
|
3272
|
+
projectDocumentLocalPath(targetApmDir, projectId, path2)
|
|
3268
3273
|
);
|
|
3269
3274
|
const content = readFileSync7(absPath, "utf8");
|
|
3270
3275
|
const contentHash = hashLocalFileContent(content);
|
|
3271
|
-
if (remoteHashByPath.get(
|
|
3276
|
+
if (remoteHashByPath.get(path2) === contentHash) {
|
|
3272
3277
|
continue;
|
|
3273
3278
|
}
|
|
3274
3279
|
await api.cli.upsertProjectDocument({
|
|
3275
3280
|
projectId,
|
|
3276
|
-
path,
|
|
3281
|
+
path: path2,
|
|
3277
3282
|
content,
|
|
3278
|
-
description: remoteDescriptionByPath.get(
|
|
3283
|
+
description: remoteDescriptionByPath.get(path2) ?? void 0
|
|
3279
3284
|
});
|
|
3280
3285
|
synced += 1;
|
|
3281
|
-
console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${
|
|
3286
|
+
console.log(`[apm] \u5DF2\u540C\u6B65\u9879\u76EE\u6587\u6863: ${path2}`);
|
|
3282
3287
|
}
|
|
3283
3288
|
if (synced === 0) {
|
|
3284
3289
|
console.log("[apm] \u9879\u76EE\u6587\u6863\u65E0\u53D8\u5316\uFF0C\u8DF3\u8FC7\u63A8\u9001");
|
|
@@ -3294,13 +3299,13 @@ function manifestPath2(apmDir) {
|
|
|
3294
3299
|
return join7(apmDir, CLI_VERSION_FILE);
|
|
3295
3300
|
}
|
|
3296
3301
|
function loadManifest2(apmDir) {
|
|
3297
|
-
const
|
|
3298
|
-
if (!existsSync8(
|
|
3302
|
+
const path2 = toFsPath(manifestPath2(apmDir));
|
|
3303
|
+
if (!existsSync8(path2)) {
|
|
3299
3304
|
return null;
|
|
3300
3305
|
}
|
|
3301
3306
|
try {
|
|
3302
3307
|
const parsed = JSON.parse(
|
|
3303
|
-
readFileSync8(
|
|
3308
|
+
readFileSync8(path2, "utf8")
|
|
3304
3309
|
);
|
|
3305
3310
|
if (parsed?.version === 1 && typeof parsed.cliVersion === "string" && parsed.cliVersion.trim()) {
|
|
3306
3311
|
return parsed;
|
|
@@ -3982,6 +3987,53 @@ async function handleStartProject(cfg, msg, signal) {
|
|
|
3982
3987
|
}
|
|
3983
3988
|
}
|
|
3984
3989
|
|
|
3990
|
+
// src/commands/connect/upload-package-artifact.ts
|
|
3991
|
+
import fs from "node:fs";
|
|
3992
|
+
import path from "node:path";
|
|
3993
|
+
function packageTmpDir(packageId) {
|
|
3994
|
+
return `/data/package-tmp/${packageId}`;
|
|
3995
|
+
}
|
|
3996
|
+
function expectedLocalArtifactPath(target, packageId) {
|
|
3997
|
+
const fileName = target === "frontend" ? "dist.zip" : "jars.zip";
|
|
3998
|
+
return path.join(packageTmpDir(packageId), fileName);
|
|
3999
|
+
}
|
|
4000
|
+
function packageArtifactObjectKey(target, projectId, timestampMs = Date.now()) {
|
|
4001
|
+
const folder = target === "frontend" ? "vue" : "java";
|
|
4002
|
+
const suffix = target === "frontend" ? "dist.zip" : "jar.zip";
|
|
4003
|
+
return `packages/${projectId}/${folder}/${timestampMs}.${suffix}`;
|
|
4004
|
+
}
|
|
4005
|
+
function removePackageTmpDir(packageId) {
|
|
4006
|
+
const dir = packageTmpDir(packageId);
|
|
4007
|
+
try {
|
|
4008
|
+
fs.rmSync(dir, { recursive: true, force: true });
|
|
4009
|
+
} catch (err) {
|
|
4010
|
+
console.warn(
|
|
4011
|
+
`[apm] \u6E05\u7406\u6253\u5305\u4E34\u65F6\u76EE\u5F55\u5931\u8D25 ${dir}:`,
|
|
4012
|
+
err instanceof Error ? err.message : err
|
|
4013
|
+
);
|
|
4014
|
+
}
|
|
4015
|
+
}
|
|
4016
|
+
async function uploadPackageArtifact(cfg, target, packageId, projectId) {
|
|
4017
|
+
const localPath = expectedLocalArtifactPath(target, packageId);
|
|
4018
|
+
if (!fs.existsSync(localPath)) {
|
|
4019
|
+
throw new Error(`\u6253\u5305\u4EA7\u7269\u4E0D\u5B58\u5728: ${localPath}`);
|
|
4020
|
+
}
|
|
4021
|
+
const stat = fs.statSync(localPath);
|
|
4022
|
+
if (!stat.isFile() || stat.size <= 0) {
|
|
4023
|
+
throw new Error(`\u6253\u5305\u4EA7\u7269\u65E0\u6548\u6216\u4E3A\u7A7A: ${localPath}`);
|
|
4024
|
+
}
|
|
4025
|
+
const objectKey = packageArtifactObjectKey(target, projectId);
|
|
4026
|
+
const { client, bucket, publicEndpoint } = await createApmLogMinioClient(cfg);
|
|
4027
|
+
await client.ensureBucket(bucket);
|
|
4028
|
+
await client.fPutObject(bucket, objectKey, localPath, {
|
|
4029
|
+
"Content-Type": "application/zip"
|
|
4030
|
+
});
|
|
4031
|
+
removePackageTmpDir(packageId);
|
|
4032
|
+
const base = publicEndpoint?.replace(/\/$/, "") ?? "";
|
|
4033
|
+
const artifactUrl = base ? `${base}/${bucket}/${objectKey}` : null;
|
|
4034
|
+
return { artifactPath: objectKey, artifactUrl };
|
|
4035
|
+
}
|
|
4036
|
+
|
|
3985
4037
|
// src/commands/connect/handle-package.ts
|
|
3986
4038
|
async function updatePackageStatus(cfg, packageId, status, extra) {
|
|
3987
4039
|
const api = createApmApiClient(cfg);
|
|
@@ -3990,15 +4042,10 @@ async function updatePackageStatus(cfg, packageId, status, extra) {
|
|
|
3990
4042
|
status,
|
|
3991
4043
|
...extra?.error != null ? { error: extra.error } : {},
|
|
3992
4044
|
...extra?.content != null ? { content: extra.content } : {},
|
|
3993
|
-
...extra?.artifactPath != null ? { artifactPath: extra.artifactPath } : {}
|
|
4045
|
+
...extra?.artifactPath != null ? { artifactPath: extra.artifactPath } : {},
|
|
4046
|
+
...extra?.artifactUrl != null ? { artifactUrl: extra.artifactUrl } : {}
|
|
3994
4047
|
});
|
|
3995
4048
|
}
|
|
3996
|
-
function expectedArtifactPath(target, packageId) {
|
|
3997
|
-
if (target === "frontend") {
|
|
3998
|
-
return `/data/artifacts/vue/${packageId}/dist.zip`;
|
|
3999
|
-
}
|
|
4000
|
-
return `/data/artifacts/springboot/${packageId}/jars.zip`;
|
|
4001
|
-
}
|
|
4002
4049
|
async function handleWebIdePackage(cfg, msg, signal) {
|
|
4003
4050
|
const workdir = requireRemoteWorkdir(msg.workdir);
|
|
4004
4051
|
const messageId = msg.messageId;
|
|
@@ -4119,7 +4166,6 @@ async function handleWebIdePackage(cfg, msg, signal) {
|
|
|
4119
4166
|
);
|
|
4120
4167
|
eventSession.addCliStep("\u542F\u52A8\u6253\u5305 Agent", "\u51C6\u5907 create\u2026", "running");
|
|
4121
4168
|
await syncPrepLog();
|
|
4122
|
-
const artifactHint = expectedArtifactPath(msg.target, packageId);
|
|
4123
4169
|
let failedByTool = false;
|
|
4124
4170
|
const outcome = await runCursorAgent(
|
|
4125
4171
|
cfg,
|
|
@@ -4226,11 +4272,17 @@ async function handleWebIdePackage(cfg, msg, signal) {
|
|
|
4226
4272
|
);
|
|
4227
4273
|
return;
|
|
4228
4274
|
}
|
|
4275
|
+
const uploaded = await runPrepStep(
|
|
4276
|
+
"\u4E0A\u4F20\u6253\u5305\u4EA7\u7269\u5230 MinIO",
|
|
4277
|
+
() => uploadPackageArtifact(cfg, msg.target, packageId, projectId),
|
|
4278
|
+
(result) => `objectKey=${result.artifactPath}${result.artifactUrl ? ` url=${result.artifactUrl}` : ""}`
|
|
4279
|
+
);
|
|
4229
4280
|
await updatePackageStatus(cfg, packageId, "SUCCESS", {
|
|
4230
|
-
artifactPath:
|
|
4281
|
+
artifactPath: uploaded.artifactPath,
|
|
4282
|
+
...uploaded.artifactUrl ? { artifactUrl: uploaded.artifactUrl } : {}
|
|
4231
4283
|
});
|
|
4232
4284
|
console.log(
|
|
4233
|
-
`[apm] webide-package \u5B8C\u6210 target=${msg.target} packageId=${packageId} agentId=${outcome.agentId}`
|
|
4285
|
+
`[apm] webide-package \u5B8C\u6210 target=${msg.target} packageId=${packageId} agentId=${outcome.agentId} artifact=${uploaded.artifactPath}`
|
|
4234
4286
|
);
|
|
4235
4287
|
} catch (err) {
|
|
4236
4288
|
const detail = err instanceof Error ? err.message : String(err);
|
package/package.json
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
适用:独立打包 Agent(不 resume 任务对话)。只打 payload 指定的 **一个** target(`frontend` / `backend`)。
|
|
4
4
|
|
|
5
|
+
产物最终由 CLI 上传 MinIO;本地**只**使用临时目录,不要写 `/data/artifacts/` 持久路径。
|
|
6
|
+
|
|
5
7
|
### 开始前
|
|
6
8
|
|
|
7
9
|
1. Read 本规则全文。
|
|
@@ -12,8 +14,8 @@
|
|
|
12
14
|
|
|
13
15
|
- **禁止**修改业务代码、提交 Git、创建 PR。
|
|
14
16
|
- **禁止**为修依赖或修编译错误而改代码 / 装依赖 / 改 lockfile;构建失败 → 以错误结束。
|
|
15
|
-
- **禁止**在仓库工作区内留下交付用 zip
|
|
16
|
-
-
|
|
17
|
+
- **禁止**在仓库工作区内留下交付用 zip。
|
|
18
|
+
- 临时目录统一用:`/data/package-tmp/<packageId>/`(不要用 `/tmp`,不要用 `/data/artifacts/`)。
|
|
17
19
|
- 后端交付 jar 的路径与文件名**只**来自 deploy 文档;禁止在本规则中写死具体项目的 jar 清单。
|
|
18
20
|
|
|
19
21
|
### target=frontend(Vue)
|
|
@@ -22,14 +24,14 @@
|
|
|
22
24
|
2. **不要**执行 `npm i` / `pnpm i` 等;分支切换后依赖已就绪。
|
|
23
25
|
3. 执行文档中的打包命令(通常 `npm run build`)。
|
|
24
26
|
4. 确认产出 `dist/`(或文档写明的目录)。
|
|
25
|
-
5.
|
|
27
|
+
5. 在临时目录压缩(勿在工作区生成 `dist.zip`),落到:
|
|
26
28
|
|
|
27
|
-
`/data/
|
|
29
|
+
`/data/package-tmp/<packageId>/dist.zip`
|
|
28
30
|
|
|
29
31
|
**压缩结构(必须)**:zip 内顶层就是名为 `dist` 的目录,解压后得到 `dist/…`,**禁止**出现 `dist/dist/…`。
|
|
30
32
|
|
|
31
33
|
- 正确:在**含有 `dist` 的父目录**执行,例如
|
|
32
|
-
`zip -r /data/
|
|
34
|
+
`mkdir -p /data/package-tmp/<packageId> && zip -r /data/package-tmp/<packageId>/dist.zip dist`
|
|
33
35
|
(把目录名 `dist` 打进包,不要先 `cd dist` 再压当前目录)。
|
|
34
36
|
- 错误:`cd dist && zip -r … .`(解压后没有顶层 `dist`);或把整个前端仓/多套一层 `dist` 再压(解压成 `dist/dist`)。
|
|
35
37
|
|
|
@@ -40,25 +42,25 @@
|
|
|
40
42
|
1. 按 deploy 文档进入后端目录,执行文档写明的构建命令(通常 `mvn clean package`)。
|
|
41
43
|
2. **只**收集 deploy 文档标明的交付 jar(路径/文件名/glob 以文档为准)。**禁止**全量收集 `target/lib`、**禁止**打包 SQL、**禁止**在规则或命令里写死具体 jar 名。
|
|
42
44
|
3. 确认文档列出的每个 jar 均已生成;缺任一文件 → SetPackageFailed。
|
|
43
|
-
4.
|
|
45
|
+
4. 在临时目录将上述 jar **打成一个 zip**(勿在工作区生成交付 zip),落到:
|
|
44
46
|
|
|
45
|
-
`/data/
|
|
47
|
+
`/data/package-tmp/<packageId>/jars.zip`
|
|
46
48
|
|
|
47
49
|
**压缩结构(必须)**:zip 内顶层直接是各个 `.jar` 文件(解压后同级列出 jar),**禁止**多套一层无意义目录,也禁止把整个 `lib` 目录原样打进包。
|
|
48
50
|
|
|
49
51
|
示例(路径与文件列表须来自 deploy,勿照抄本例文件名):
|
|
50
52
|
|
|
51
53
|
```bash
|
|
52
|
-
mkdir -p /data/
|
|
54
|
+
mkdir -p /data/package-tmp/<packageId>/jars
|
|
53
55
|
# 按 deploy 文档把待交付 jar 拷到临时目录后:
|
|
54
|
-
cd /data/
|
|
55
|
-
zip /data/
|
|
56
|
+
cd /data/package-tmp/<packageId>/jars
|
|
57
|
+
zip /data/package-tmp/<packageId>/jars.zip ./*.jar
|
|
56
58
|
```
|
|
57
59
|
|
|
58
|
-
5.
|
|
60
|
+
5. 可选:同临时目录写 `commitId.txt`(后端仓 `git rev-parse HEAD` 一行),非必须。
|
|
59
61
|
6. 构建或落盘失败 → 调用 **SetPackageFailed**(传入失败原因)后结束。
|
|
60
62
|
|
|
61
63
|
### 结束
|
|
62
64
|
|
|
63
|
-
-
|
|
65
|
+
- 成功:确认 zip 已落到 `/data/package-tmp/<packageId>/` 约定文件名后正常结束(不要调用 SetPackageFailed)。CLI 会上传 MinIO 并清理该临时目录。
|
|
64
66
|
- 失败:先调用 SetPackageFailed 写入原因,再结束。
|