ai-project-manage-cli 6.0.85 → 6.0.87
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/README.md +1 -0
- package/dist/index.js +216 -48
- package/package.json +1 -1
- package/template/skills/apm-deploy/SKILL.md +7 -0
package/README.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -2483,7 +2483,7 @@ async function fetchDeployArtifactStorage(api) {
|
|
|
2483
2483
|
}
|
|
2484
2484
|
async function uploadDeployArtifactZip(options) {
|
|
2485
2485
|
const deploymentRunId = options.deploymentRunId ?? resolveDeploymentRunIdFromEnv();
|
|
2486
|
-
if (!deploymentRunId) {
|
|
2486
|
+
if (!deploymentRunId && !options.uploadWithoutRunId) {
|
|
2487
2487
|
return null;
|
|
2488
2488
|
}
|
|
2489
2489
|
const cfg = await tryReadApmConfig();
|
|
@@ -2527,26 +2527,30 @@ async function uploadDeployArtifactZip(options) {
|
|
|
2527
2527
|
"Content-Type": "application/zip"
|
|
2528
2528
|
});
|
|
2529
2529
|
console.error(
|
|
2530
|
-
`[apm] \
|
|
2530
|
+
`[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(
|
|
2531
|
+
2
|
|
2532
|
+
)} MB)`
|
|
2531
2533
|
);
|
|
2532
2534
|
} catch (error) {
|
|
2533
2535
|
const detail = error instanceof Error ? error.message : String(error);
|
|
2534
2536
|
console.warn(`[apm] MinIO \u90E8\u7F72\u4EA7\u7269\u5F52\u6863\u5931\u8D25: ${detail}`);
|
|
2535
2537
|
return null;
|
|
2536
2538
|
}
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
|
|
2542
|
-
|
|
2543
|
-
|
|
2544
|
-
|
|
2545
|
-
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2539
|
+
if (deploymentRunId) {
|
|
2540
|
+
try {
|
|
2541
|
+
await api.cli.attachTaskDeploymentArtifact({
|
|
2542
|
+
id: deploymentRunId,
|
|
2543
|
+
artifactObjectKey: objectKey,
|
|
2544
|
+
artifactFileName: fileName
|
|
2545
|
+
});
|
|
2546
|
+
console.error(
|
|
2547
|
+
`[apm] \u5DF2\u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55 id=${deploymentRunId} file=${fileName}`
|
|
2548
|
+
);
|
|
2549
|
+
} catch (error) {
|
|
2550
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
2551
|
+
console.warn(`[apm] \u7ED1\u5B9A\u90E8\u7F72\u4EA7\u7269\u5230\u8BB0\u5F55\u5931\u8D25: ${detail}`);
|
|
2552
|
+
return null;
|
|
2553
|
+
}
|
|
2550
2554
|
}
|
|
2551
2555
|
return {
|
|
2552
2556
|
objectKey,
|
|
@@ -4691,7 +4695,7 @@ var DeployExecutionError = class extends Error {
|
|
|
4691
4695
|
};
|
|
4692
4696
|
|
|
4693
4697
|
// src/commands/deploy/internal/wisdom-auto-deploy.ts
|
|
4694
|
-
import { existsSync as existsSync17, readFileSync as readFileSync14 } from "node:fs";
|
|
4698
|
+
import { existsSync as existsSync17, readFileSync as readFileSync14, statSync as statSync7 } from "node:fs";
|
|
4695
4699
|
import path4 from "node:path";
|
|
4696
4700
|
import { spawnSync as spawnSync4 } from "node:child_process";
|
|
4697
4701
|
|
|
@@ -4835,19 +4839,30 @@ async function uploadAndMaybeExtract(settings, localZip, extract) {
|
|
|
4835
4839
|
async function runWisdomSftpDeploy(params) {
|
|
4836
4840
|
const zipPath = path2.join(params.localDir, "..", ".deploy-sftp-dist.zip");
|
|
4837
4841
|
const resolvedZipPath = path2.resolve(zipPath);
|
|
4842
|
+
const packOnly = Boolean(params.packOnly);
|
|
4838
4843
|
let zipSizeBytes = 0;
|
|
4844
|
+
let artifactUploaded = false;
|
|
4839
4845
|
try {
|
|
4840
4846
|
zipSizeBytes = await zipDirectory(params.localDir, resolvedZipPath);
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4845
|
-
|
|
4846
|
-
|
|
4847
|
+
if (!packOnly) {
|
|
4848
|
+
await uploadAndMaybeExtract(
|
|
4849
|
+
params.settings,
|
|
4850
|
+
resolvedZipPath,
|
|
4851
|
+
params.extract
|
|
4852
|
+
);
|
|
4853
|
+
} else {
|
|
4854
|
+
console.error("[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7 SFTP \u8FDC\u7A0B\u4E0A\u4F20");
|
|
4855
|
+
}
|
|
4856
|
+
const artifact = await uploadDeployArtifactZip({
|
|
4847
4857
|
zipPath: resolvedZipPath,
|
|
4848
4858
|
projectName: params.projectName,
|
|
4849
|
-
kind: "frontend"
|
|
4859
|
+
kind: "frontend",
|
|
4860
|
+
uploadWithoutRunId: packOnly
|
|
4850
4861
|
});
|
|
4862
|
+
artifactUploaded = artifact !== null;
|
|
4863
|
+
if (packOnly && artifactUploaded) {
|
|
4864
|
+
console.error("\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09");
|
|
4865
|
+
}
|
|
4851
4866
|
} finally {
|
|
4852
4867
|
try {
|
|
4853
4868
|
await unlink(resolvedZipPath);
|
|
@@ -4861,7 +4876,9 @@ async function runWisdomSftpDeploy(params) {
|
|
|
4861
4876
|
host: params.settings.host,
|
|
4862
4877
|
remotePath: params.settings.remotePath,
|
|
4863
4878
|
zipSizeBytes,
|
|
4864
|
-
extracted: params.extract
|
|
4879
|
+
extracted: packOnly ? false : params.extract,
|
|
4880
|
+
packOnly,
|
|
4881
|
+
artifactUploaded
|
|
4865
4882
|
};
|
|
4866
4883
|
}
|
|
4867
4884
|
|
|
@@ -5385,19 +5402,63 @@ async function restartRemoteService(client, config) {
|
|
|
5385
5402
|
const script = buildRemoteRestartScript(config.remoteAppDir);
|
|
5386
5403
|
await runRemoteServiceScript(client, script, "restart");
|
|
5387
5404
|
}
|
|
5405
|
+
function listAllLibFilesForArchive(libDir) {
|
|
5406
|
+
return readdirSync5(libDir).filter((name) => name.endsWith(".jar")).sort().map((jarName) => ({
|
|
5407
|
+
path: path3.join(libDir, jarName),
|
|
5408
|
+
arcname: jarName,
|
|
5409
|
+
reason: "\u4EC5\u6253\u5305\u5F52\u6863"
|
|
5410
|
+
}));
|
|
5411
|
+
}
|
|
5388
5412
|
async function runWisdomBackendDeploy(options) {
|
|
5389
5413
|
const projectRoot = path3.resolve(options.projectRoot ?? process.cwd());
|
|
5390
5414
|
const config = options.config;
|
|
5415
|
+
const packOnly = Boolean(options.packOnly);
|
|
5391
5416
|
log(`=== \u81EA\u52A8\u90E8\u7F72: ${config.projectName} ===`);
|
|
5392
5417
|
log(`\u914D\u7F6E\u6587\u4EF6: ${path3.join(workspaceApmDir(), "apm.config.json")}`);
|
|
5393
5418
|
log(`\u9879\u76EE\u6839\u76EE\u5F55: ${projectRoot}`);
|
|
5394
5419
|
log(
|
|
5395
|
-
`\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"}`
|
|
5420
|
+
`\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" : ""}`
|
|
5396
5421
|
);
|
|
5397
5422
|
runMavenBuild(projectRoot, config.mavenLocalRepo, {
|
|
5398
5423
|
source: config.mavenLocalRepoSource,
|
|
5399
5424
|
sourceDetail: config.mavenLocalRepoSourceDetail
|
|
5400
5425
|
});
|
|
5426
|
+
if (packOnly) {
|
|
5427
|
+
if (config.mode === "full") {
|
|
5428
|
+
const mainJar = locateMainJar(projectRoot);
|
|
5429
|
+
const archiveZipPath = await createUpdatePackage(
|
|
5430
|
+
[
|
|
5431
|
+
{
|
|
5432
|
+
path: mainJar,
|
|
5433
|
+
arcname: path3.basename(mainJar),
|
|
5434
|
+
reason: "\u5168\u91CF JAR \u5F52\u6863"
|
|
5435
|
+
}
|
|
5436
|
+
],
|
|
5437
|
+
`.deploy-archive-${config.projectName}.jar.zip`
|
|
5438
|
+
);
|
|
5439
|
+
await uploadDeployArtifactZip({
|
|
5440
|
+
zipPath: archiveZipPath,
|
|
5441
|
+
projectName: config.projectName,
|
|
5442
|
+
kind: "backend",
|
|
5443
|
+
uploadWithoutRunId: true
|
|
5444
|
+
});
|
|
5445
|
+
} else {
|
|
5446
|
+
const libDir = locateLibDir(projectRoot);
|
|
5447
|
+
const entries = listAllLibFilesForArchive(libDir);
|
|
5448
|
+
if (entries.length === 0) {
|
|
5449
|
+
fail("lib \u76EE\u5F55\u4E0B\u6CA1\u6709\u53EF\u5F52\u6863\u7684 JAR");
|
|
5450
|
+
}
|
|
5451
|
+
const zipPath = await createUpdatePackage(entries, config.packageName);
|
|
5452
|
+
await uploadDeployArtifactZip({
|
|
5453
|
+
zipPath,
|
|
5454
|
+
projectName: config.projectName,
|
|
5455
|
+
kind: "backend",
|
|
5456
|
+
uploadWithoutRunId: true
|
|
5457
|
+
});
|
|
5458
|
+
}
|
|
5459
|
+
log("\u4EC5\u6253\u5305\u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF09");
|
|
5460
|
+
return;
|
|
5461
|
+
}
|
|
5401
5462
|
const conn = await connectSsh(config);
|
|
5402
5463
|
try {
|
|
5403
5464
|
if (config.mode === "full") {
|
|
@@ -5543,14 +5604,48 @@ function runShellCommand2(command, cwd, captureOutput) {
|
|
|
5543
5604
|
}
|
|
5544
5605
|
return output;
|
|
5545
5606
|
}
|
|
5607
|
+
function resolveFrontendDistDir(cwd) {
|
|
5608
|
+
const candidates = ["dist", "apps/web/dist"];
|
|
5609
|
+
for (const rel of candidates) {
|
|
5610
|
+
const full = path4.join(cwd, rel);
|
|
5611
|
+
try {
|
|
5612
|
+
if (existsSync17(full) && statSync7(full).isDirectory()) {
|
|
5613
|
+
return full;
|
|
5614
|
+
}
|
|
5615
|
+
} catch {
|
|
5616
|
+
}
|
|
5617
|
+
}
|
|
5618
|
+
return path4.join(cwd, "dist");
|
|
5619
|
+
}
|
|
5546
5620
|
async function runWisdomAutoDeploy(options) {
|
|
5547
5621
|
const cwd = path4.resolve(options.cwd ?? process.cwd());
|
|
5548
5622
|
const captureOutput = options.captureOutput ?? false;
|
|
5623
|
+
const packOnly = Boolean(options.packOnly);
|
|
5549
5624
|
const projectType = detectWisdomProjectType(cwd);
|
|
5625
|
+
const configPath = options.configPath ?? path4.join(workspaceApmDir(cwd), "apm.config.json");
|
|
5626
|
+
const cfg = loadApmConfig({ configPath });
|
|
5550
5627
|
console.error(
|
|
5551
|
-
`[apm] \u533B\u52A1\u5B58\u91CF\u9879\u76EE\u81EA\u52A8\u8BC6\u522B: ${projectType === "frontend" ? "\u524D\u7AEF Vue" : "\u540E\u7AEF Java"}`
|
|
5628
|
+
`[apm] \u533B\u52A1\u5B58\u91CF\u9879\u76EE\u81EA\u52A8\u8BC6\u522B: ${projectType === "frontend" ? "\u524D\u7AEF Vue" : "\u540E\u7AEF Java"}${packOnly ? "\uFF08\u4EC5\u6253\u5305\u6A21\u5F0F\uFF09" : ""}`
|
|
5552
5629
|
);
|
|
5553
5630
|
if (projectType === "frontend") {
|
|
5631
|
+
if (packOnly) {
|
|
5632
|
+
const projectName = (cfg.name ?? "").trim();
|
|
5633
|
+
if (!projectName) {
|
|
5634
|
+
throw new DeployExecutionError(
|
|
5635
|
+
"\u8BF7\u5728 .apm/apm.config.json \u9876\u5C42\u914D\u7F6E name\uFF08\u4F5C\u4E3A\u90E8\u7F72\u4EA7\u7269\u9879\u76EE\u540D\uFF09",
|
|
5636
|
+
1
|
|
5637
|
+
);
|
|
5638
|
+
}
|
|
5639
|
+
const settings2 = resolveWisdomDeployFromApmConfig(cfg);
|
|
5640
|
+
await runWisdomSftpDeploy({
|
|
5641
|
+
localDir: resolveFrontendDistDir(cwd),
|
|
5642
|
+
settings: settings2,
|
|
5643
|
+
extract: false,
|
|
5644
|
+
projectName,
|
|
5645
|
+
packOnly: true
|
|
5646
|
+
});
|
|
5647
|
+
return { projectType };
|
|
5648
|
+
}
|
|
5554
5649
|
const deployCmd = resolveFrontendDeployCommand(options.env, cwd);
|
|
5555
5650
|
if (!deployCmd) {
|
|
5556
5651
|
const lines = formatWisdomFrontendDeployNotConfiguredLines(
|
|
@@ -5562,15 +5657,18 @@ async function runWisdomAutoDeploy(options) {
|
|
|
5562
5657
|
runShellCommand2(deployCmd, cwd, captureOutput);
|
|
5563
5658
|
return { projectType };
|
|
5564
5659
|
}
|
|
5565
|
-
const configPath = options.configPath ?? path4.join(workspaceApmDir(cwd), "apm.config.json");
|
|
5566
|
-
const cfg = loadApmConfig({ configPath });
|
|
5567
5660
|
const settings = resolveWisdomBackendDeployFromApmConfig(cfg);
|
|
5568
|
-
|
|
5569
|
-
`[apm] \u540E\u7AEF\
|
|
5570
|
-
|
|
5661
|
+
if (packOnly) {
|
|
5662
|
+
console.error(`[apm] \u540E\u7AEF\u4EC5\u6253\u5305\u6A21\u5F0F\uFF0C\u5FFD\u7565\u73AF\u5883\u53C2\u6570: ${options.env}`);
|
|
5663
|
+
} else {
|
|
5664
|
+
console.error(
|
|
5665
|
+
`[apm] \u540E\u7AEF\u90E8\u7F72\u4E0D\u533A\u5206 test/online\uFF0C\u5FFD\u7565\u73AF\u5883\u53C2\u6570: ${options.env}`
|
|
5666
|
+
);
|
|
5667
|
+
}
|
|
5571
5668
|
await runWisdomBackendDeploy({
|
|
5572
5669
|
config: settings,
|
|
5573
|
-
projectRoot: cwd
|
|
5670
|
+
projectRoot: cwd,
|
|
5671
|
+
packOnly
|
|
5574
5672
|
});
|
|
5575
5673
|
return { projectType };
|
|
5576
5674
|
}
|
|
@@ -5749,6 +5847,15 @@ async function executeDeploy(options) {
|
|
|
5749
5847
|
const captureOutput = options.captureOutput ?? false;
|
|
5750
5848
|
const outputParts = [];
|
|
5751
5849
|
try {
|
|
5850
|
+
const configSyncResult = await syncRemoteDeploymentConfig(
|
|
5851
|
+
cwd,
|
|
5852
|
+
workspaceApmDir(cwd)
|
|
5853
|
+
);
|
|
5854
|
+
if (configSyncResult.synced && configSyncResult.configName) {
|
|
5855
|
+
outputParts.push(
|
|
5856
|
+
`[apm] \u90E8\u7F72\u524D\u5DF2\u540C\u6B65\u5E73\u53F0\u90E8\u7F72\u914D\u7F6E: ${configSyncResult.configName}`
|
|
5857
|
+
);
|
|
5858
|
+
}
|
|
5752
5859
|
const syncResult = await syncDeployBaselineBeforeDeploy(cwd);
|
|
5753
5860
|
if (syncResult.log.trim()) {
|
|
5754
5861
|
outputParts.push(syncResult.log);
|
|
@@ -5768,7 +5875,8 @@ async function executeDeploy(options) {
|
|
|
5768
5875
|
env: options.env,
|
|
5769
5876
|
cwd,
|
|
5770
5877
|
configPath: options.configPath,
|
|
5771
|
-
captureOutput
|
|
5878
|
+
captureOutput,
|
|
5879
|
+
packOnly: options.packOnly
|
|
5772
5880
|
});
|
|
5773
5881
|
return outputParts.join("\n");
|
|
5774
5882
|
} catch (error) {
|
|
@@ -5916,28 +6024,33 @@ async function runDeployWithBackendTracking(options) {
|
|
|
5916
6024
|
// src/commands/deploy/deploy.ts
|
|
5917
6025
|
function registerDeployMainCommand(program) {
|
|
5918
6026
|
program.command("deploy").description(
|
|
5919
|
-
"\u7EDF\u4E00\u90E8\u7F72\
|
|
6027
|
+
"\u7EDF\u4E00\u90E8\u7F72\uFF08\u6267\u884C\u524D\u81EA\u52A8\u540C\u6B65\u90E8\u7F72\u914D\u7F6E\u5E76\u5408\u5E76\u57FA\u7EBF\u5206\u652F\uFF09\uFF1A\u533B\u52A1\u5B58\u91CF\u81EA\u52A8\u8BC6\u522B\u524D\u540E\u7AEF\uFF1B\u5176\u4ED6\u9879\u76EE\u6309 deploy.<\u73AF\u5883> \u6267\u884C shell \u547D\u4EE4"
|
|
5920
6028
|
).argument("<env>", "\u90E8\u7F72\u73AF\u5883\u540D\uFF08\u5982 test\u3001online\uFF09").option(
|
|
5921
6029
|
"--config <path>",
|
|
5922
6030
|
"apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
|
|
5923
6031
|
).option(
|
|
5924
6032
|
"--session <sessionId>",
|
|
5925
6033
|
"\u6C9F\u901A\u7FA4 ID\uFF1B\u4F20\u5165\u65F6\u5728\u5E73\u53F0\u521B\u5EFA\u90E8\u7F72\u8BB0\u5F55\u5E76\u540C\u6B65\u65E5\u5FD7"
|
|
6034
|
+
).option(
|
|
6035
|
+
"--pack-only",
|
|
6036
|
+
"\u4EC5\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF08\u533B\u52A1\u5B58\u91CF SFTP / Java \u90E8\u7F72\uFF09"
|
|
5926
6037
|
).action(
|
|
5927
6038
|
async (env, opts) => {
|
|
5928
6039
|
const cwd = process.cwd();
|
|
5929
6040
|
const sessionId = opts.session?.trim();
|
|
6041
|
+
const packOnly = Boolean(opts.packOnly);
|
|
5930
6042
|
try {
|
|
5931
6043
|
if (sessionId) {
|
|
5932
6044
|
await runDeployWithBackendTracking({
|
|
5933
6045
|
env,
|
|
5934
6046
|
cwd,
|
|
5935
6047
|
configPath: opts.config,
|
|
5936
|
-
sessionId
|
|
6048
|
+
sessionId,
|
|
6049
|
+
packOnly
|
|
5937
6050
|
});
|
|
5938
6051
|
return;
|
|
5939
6052
|
}
|
|
5940
|
-
await executeDeploy({ env, cwd, configPath: opts.config });
|
|
6053
|
+
await executeDeploy({ env, cwd, configPath: opts.config, packOnly });
|
|
5941
6054
|
} catch (error) {
|
|
5942
6055
|
if (error instanceof DeployExecutionError) {
|
|
5943
6056
|
printDeployExecutionError(error);
|
|
@@ -6182,7 +6295,7 @@ var DockerodeClient = class {
|
|
|
6182
6295
|
var createDockerodeClient = (config) => new DockerodeClient(config);
|
|
6183
6296
|
|
|
6184
6297
|
// src/commands/deploy/internal/backend-deploy/dockerode-client/env.ts
|
|
6185
|
-
import { existsSync as existsSync19, readFileSync as readFileSync16, statSync as
|
|
6298
|
+
import { existsSync as existsSync19, readFileSync as readFileSync16, statSync as statSync8 } from "node:fs";
|
|
6186
6299
|
import path7 from "node:path";
|
|
6187
6300
|
function stripSurroundingQuotes(value) {
|
|
6188
6301
|
const t = value.trim();
|
|
@@ -6199,7 +6312,7 @@ function loadEnvFromFile(envFilePath) {
|
|
|
6199
6312
|
return {};
|
|
6200
6313
|
}
|
|
6201
6314
|
const targetPath = path7.resolve(envFilePath);
|
|
6202
|
-
if (!existsSync19(targetPath) || !
|
|
6315
|
+
if (!existsSync19(targetPath) || !statSync8(targetPath).isFile()) {
|
|
6203
6316
|
return {};
|
|
6204
6317
|
}
|
|
6205
6318
|
const raw = readFileSync16(targetPath, "utf-8");
|
|
@@ -6503,7 +6616,7 @@ function registerDeployBackendCommands(program) {
|
|
|
6503
6616
|
}
|
|
6504
6617
|
|
|
6505
6618
|
// src/commands/deploy/frontend.ts
|
|
6506
|
-
import { copyFile, readdir as readdir3, stat } from "node:fs/promises";
|
|
6619
|
+
import { copyFile, readdir as readdir3, stat, unlink as unlink2 } from "node:fs/promises";
|
|
6507
6620
|
import path11 from "node:path";
|
|
6508
6621
|
function resolveArtifactNamePrefix(cfg) {
|
|
6509
6622
|
const nameRaw = (cfg.name ?? "").trim();
|
|
@@ -6567,6 +6680,44 @@ async function ensureArtifactRootIndexHtml(root) {
|
|
|
6567
6680
|
);
|
|
6568
6681
|
process.exit(1);
|
|
6569
6682
|
}
|
|
6683
|
+
async function runFrontendPackOnlyDeploy(root, namePrefix) {
|
|
6684
|
+
const zipPath = path11.resolve(root, "..", ".deploy-frontend-dist.zip");
|
|
6685
|
+
let zipSizeBytes = 0;
|
|
6686
|
+
let artifactUploaded = false;
|
|
6687
|
+
try {
|
|
6688
|
+
zipSizeBytes = await zipDirectory(root, zipPath);
|
|
6689
|
+
console.error("[apm] \u4EC5\u6253\u5305\u6A21\u5F0F\uFF1A\u8DF3\u8FC7\u524D\u7AEF\u8BBF\u95EE\u6876\u4E0A\u4F20");
|
|
6690
|
+
const artifact = await uploadDeployArtifactZip({
|
|
6691
|
+
zipPath,
|
|
6692
|
+
projectName: namePrefix,
|
|
6693
|
+
kind: "frontend",
|
|
6694
|
+
uploadWithoutRunId: true
|
|
6695
|
+
});
|
|
6696
|
+
artifactUploaded = artifact !== null;
|
|
6697
|
+
if (artifactUploaded) {
|
|
6698
|
+
console.error("\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\u5B8C\u6210\uFF08\u672A\u4E0A\u4F20\u81F3\u524D\u7AEF\u8BBF\u95EE\u6876\uFF09");
|
|
6699
|
+
}
|
|
6700
|
+
console.log(
|
|
6701
|
+
JSON.stringify(
|
|
6702
|
+
{
|
|
6703
|
+
ok: true,
|
|
6704
|
+
packOnly: true,
|
|
6705
|
+
namePrefix,
|
|
6706
|
+
zipSizeBytes,
|
|
6707
|
+
artifactUploaded
|
|
6708
|
+
},
|
|
6709
|
+
null,
|
|
6710
|
+
2
|
|
6711
|
+
)
|
|
6712
|
+
);
|
|
6713
|
+
} finally {
|
|
6714
|
+
try {
|
|
6715
|
+
await unlink2(zipPath);
|
|
6716
|
+
console.error(`\u5DF2\u6E05\u7406\u672C\u5730\u4E34\u65F6\u6587\u4EF6: ${zipPath}`);
|
|
6717
|
+
} catch {
|
|
6718
|
+
}
|
|
6719
|
+
}
|
|
6720
|
+
}
|
|
6570
6721
|
function registerDeployFrontendCommands(program) {
|
|
6571
6722
|
program.command("deploy-frontend").description(
|
|
6572
6723
|
"\u9012\u5F52\u4E0A\u4F20\u524D\u7AEF\u4EA7\u7269\u76EE\u5F55\u5230 MinIO\uFF0C\u5E76\u5728\u6210\u529F\u540E\u4E3A\u8BE5\u6876\u8BBE\u7F6E\u533F\u540D\u53EF\u8BFB\u7B56\u7565\uFF08MinIO \u8FDE\u63A5\u4FE1\u606F\u4EC5\u6765\u81EA apm.config.json frontendDeploy\uFF09"
|
|
@@ -6581,10 +6732,23 @@ function registerDeployFrontendCommands(program) {
|
|
|
6581
6732
|
"--max-file-size-mb <mb>",
|
|
6582
6733
|
`\u5355\u6587\u4EF6\u5927\u5C0F\u4E0A\u9650\uFF0C\u9ED8\u8BA4 ${DEFAULT_MAX_FILE_SIZE_MB}`,
|
|
6583
6734
|
(v) => Number.parseInt(String(v), 10)
|
|
6735
|
+
).option(
|
|
6736
|
+
"--pack-only",
|
|
6737
|
+
"\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"
|
|
6584
6738
|
).action(
|
|
6585
6739
|
async (name, opts) => {
|
|
6586
6740
|
const cfg = loadApmConfig({ configPath: opts.config });
|
|
6587
6741
|
const namePrefix = resolveArtifactNamePrefix(cfg);
|
|
6742
|
+
const root = path11.resolve(process.cwd(), opts.dir || "apps/web/dist");
|
|
6743
|
+
if (!await isDirectoryPath(root)) {
|
|
6744
|
+
console.error(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`);
|
|
6745
|
+
process.exit(1);
|
|
6746
|
+
}
|
|
6747
|
+
await ensureArtifactRootIndexHtml(root);
|
|
6748
|
+
if (opts.packOnly) {
|
|
6749
|
+
await runFrontendPackOnlyDeploy(root, namePrefix);
|
|
6750
|
+
return;
|
|
6751
|
+
}
|
|
6588
6752
|
const settings = resolveFrontendDeployFromApmConfig(cfg);
|
|
6589
6753
|
const minio = new MinioClient({
|
|
6590
6754
|
endPoint: settings.endpoint,
|
|
@@ -6594,12 +6758,6 @@ function registerDeployFrontendCommands(program) {
|
|
|
6594
6758
|
secretKey: settings.secretKey
|
|
6595
6759
|
});
|
|
6596
6760
|
const bucket = settings.bucket;
|
|
6597
|
-
const root = path11.resolve(process.cwd(), opts.dir || "apps/web/dist");
|
|
6598
|
-
if (!await isDirectoryPath(root)) {
|
|
6599
|
-
console.error(`\u4EA7\u7269\u76EE\u5F55\u4E0D\u5B58\u5728\uFF1A${root}`);
|
|
6600
|
-
process.exit(1);
|
|
6601
|
-
}
|
|
6602
|
-
await ensureArtifactRootIndexHtml(root);
|
|
6603
6761
|
const maxBytes = Math.max(
|
|
6604
6762
|
1,
|
|
6605
6763
|
Number.isFinite(opts.maxFileSizeMb) ? Math.floor(
|
|
@@ -6674,7 +6832,10 @@ function registerDeploySftpCommands(program) {
|
|
|
6674
6832
|
).option(
|
|
6675
6833
|
"--config <path>",
|
|
6676
6834
|
"apm.config.json \u8DEF\u5F84\uFF08\u9ED8\u8BA4 .apm/apm.config.json\uFF09"
|
|
6677
|
-
).option("--extract", "\u4E0A\u4F20\u540E\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u89E3\u538B zip \u5230 remotePath").
|
|
6835
|
+
).option("--extract", "\u4E0A\u4F20\u540E\u5728\u8FDC\u7A0B\u670D\u52A1\u5668\u89E3\u538B zip \u5230 remotePath").option(
|
|
6836
|
+
"--pack-only",
|
|
6837
|
+
"\u4EC5\u6253\u5305\u5E76\u4E0A\u4F20 MinIO \u5F52\u6863\uFF0C\u4E0D\u4E0A\u4F20\u8FDC\u7A0B\u670D\u52A1\u5668\uFF08\u4E0E --extract \u4E92\u65A5\uFF09"
|
|
6838
|
+
).action(
|
|
6678
6839
|
async (opts) => {
|
|
6679
6840
|
const cfg = loadApmConfig({ configPath: opts.config });
|
|
6680
6841
|
const settings = resolveWisdomDeployFromApmConfig(cfg);
|
|
@@ -6691,16 +6852,23 @@ function registerDeploySftpCommands(program) {
|
|
|
6691
6852
|
process.exit(1);
|
|
6692
6853
|
}
|
|
6693
6854
|
try {
|
|
6855
|
+
const packOnly = Boolean(opts.packOnly);
|
|
6856
|
+
if (packOnly && opts.extract) {
|
|
6857
|
+
console.error("--pack-only \u4E0E --extract \u4E0D\u80FD\u540C\u65F6\u4F7F\u7528");
|
|
6858
|
+
process.exit(1);
|
|
6859
|
+
}
|
|
6694
6860
|
const result = await runWisdomSftpDeploy({
|
|
6695
6861
|
localDir: root,
|
|
6696
6862
|
settings,
|
|
6697
6863
|
extract: Boolean(opts.extract),
|
|
6698
|
-
projectName
|
|
6864
|
+
projectName,
|
|
6865
|
+
packOnly
|
|
6699
6866
|
});
|
|
6700
6867
|
console.log(JSON.stringify(result, null, 2));
|
|
6701
6868
|
} catch (err) {
|
|
6702
6869
|
const message = err instanceof Error ? err.message : String(err);
|
|
6703
|
-
|
|
6870
|
+
const action = opts.packOnly ? "\u6253\u5305" : opts.extract ? "\u90E8\u7F72" : "\u4E0A\u4F20";
|
|
6871
|
+
console.error(`${action}\u5931\u8D25:`, message);
|
|
6704
6872
|
process.exit(1);
|
|
6705
6873
|
}
|
|
6706
6874
|
}
|
package/package.json
CHANGED
|
@@ -6,6 +6,13 @@
|
|
|
6
6
|
|
|
7
7
|
**sessionId**:从当前工作项目录 `.apm/sessions/<sessionId>/` 或 `session.yaml` 获取;必须传入 `--session`,平台才会记录部署。
|
|
8
8
|
|
|
9
|
+
部署前会自动:
|
|
10
|
+
|
|
11
|
+
1. 从平台同步最新部署配置(`.apm/apm.config.json`)
|
|
12
|
+
2. 合并仓库基线分支最新代码到当前分支
|
|
13
|
+
|
|
14
|
+
若平台刚更新过部署配置,也可先手动执行 `apm sync-deploy-config` 再部署。
|
|
15
|
+
|
|
9
16
|
- **成功**:部署完成,在回信中说明测试环境地址或部署结果。
|
|
10
17
|
- **失败且输出含「未配置自动化部署」或「可跳过部署」**:本项目不支持自动化部署,属正常情况;放弃部署,在回信说明已跳过即可,无需修复配置或重试。
|
|
11
18
|
- **其他失败**:按输出排查并修复后重试。
|