openxiangda-devkit-core 2.71.5 → 2.71.6
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/application-services.d.ts +320 -31
- package/dist/application-services.d.ts.map +1 -1
- package/dist/application-services.js +52 -19
- package/dist/application-services.js.map +1 -1
- package/dist/deployment-prerequisites.d.ts +2 -1
- package/dist/deployment-prerequisites.d.ts.map +1 -1
- package/dist/deployment-prerequisites.js +15 -3
- package/dist/deployment-prerequisites.js.map +1 -1
- package/dist/developer-operations.d.ts +71 -4
- package/dist/developer-operations.d.ts.map +1 -1
- package/dist/developer-operations.js +2 -0
- package/dist/developer-operations.js.map +1 -1
- package/dist/development-lifecycle.d.ts +108 -8
- package/dist/development-lifecycle.d.ts.map +1 -1
- package/dist/development-lifecycle.js +33 -5
- package/dist/development-lifecycle.js.map +1 -1
- package/package.json +2 -2
|
@@ -1147,8 +1147,8 @@ export class OpenXiangdaApplicationServices {
|
|
|
1147
1147
|
if (diagnostics.length > 0) {
|
|
1148
1148
|
return this.result("deployment.plan", workspace.context.workspace, undefined, diagnostics);
|
|
1149
1149
|
}
|
|
1150
|
-
const source = await operationStage('source', '
|
|
1151
|
-
const lifecycle = developmentLifecycle(workspace.root, this.appSpecContractIndex(workspace, true));
|
|
1150
|
+
const source = await operationStage('source', '核对远端主线与源码(网络不可达时保留本地来源)', () => publishedDeliverySource(workspace.root));
|
|
1151
|
+
const lifecycle = developmentLifecycle(workspace.root, this.appSpecContractIndex(workspace, true), undefined, input.appSpecChangeId, 'warning-first');
|
|
1152
1152
|
if (!lifecycle.readyForTest)
|
|
1153
1153
|
return this.result('deployment.plan', workspace.context.workspace, { lifecycle: summarizeLifecycle(lifecycle) }, lifecycle.diagnostics);
|
|
1154
1154
|
const sources = compileApplicationSources(workspace.config, this.toolchainVersion);
|
|
@@ -1158,6 +1158,7 @@ export class OpenXiangdaApplicationServices {
|
|
|
1158
1158
|
return this.result("deployment.plan", workspace.context.workspace, {
|
|
1159
1159
|
runtimeCapacity,
|
|
1160
1160
|
workflowActivation,
|
|
1161
|
+
lifecycle: summarizeLifecycle(lifecycle),
|
|
1161
1162
|
environment: input.environment,
|
|
1162
1163
|
appCode: workspace.config.app.code,
|
|
1163
1164
|
sealed: false,
|
|
@@ -1168,7 +1169,7 @@ export class OpenXiangdaApplicationServices {
|
|
|
1168
1169
|
backendRoot: workspace.config.backend.root,
|
|
1169
1170
|
configDigest: sources.config.digest,
|
|
1170
1171
|
contractDigest: sources.contracts.digest,
|
|
1171
|
-
}, workflowActivation);
|
|
1172
|
+
}, [...workflowActivation, ...lifecycle.diagnostics]);
|
|
1172
1173
|
}
|
|
1173
1174
|
async deploy(input) {
|
|
1174
1175
|
const workspace = await this.workspace(input.root);
|
|
@@ -1181,14 +1182,18 @@ export class OpenXiangdaApplicationServices {
|
|
|
1181
1182
|
this.diagnostic("DEPLOY_PREPRODUCTION_ONLY", "Native 2.0 只允许直接部署到预发环境", String(input.environment), "使用 openxiangda deploy;生产环境必须显式复用成功的测试 DeploymentRun"),
|
|
1182
1183
|
]);
|
|
1183
1184
|
}
|
|
1184
|
-
const source = await operationStage('source', '
|
|
1185
|
+
const source = await operationStage('source', '核对远端主线与源码(网络不可达时保留本地来源)', () => publishedDeliverySource(workspace.root));
|
|
1185
1186
|
const client = await this.client(workspace.root);
|
|
1186
1187
|
const capabilities = await client.capabilities();
|
|
1188
|
+
let prerequisiteWarnings = [];
|
|
1187
1189
|
if (capabilities.features?.['application.deployment-prerequisites']?.status === 'available') {
|
|
1188
|
-
await operationStage('prerequisites', '
|
|
1190
|
+
const prerequisites = await operationStage('prerequisites', '检查内核、源码托管与镜像仓库(源码异常转为警告)', async () => {
|
|
1189
1191
|
const backend = backendRuntimeRequired(workspace.config);
|
|
1190
|
-
|
|
1192
|
+
const report = await client.deploymentPrerequisites(workspace.config.app.code, backend);
|
|
1193
|
+
const warnings = assertDeploymentPrerequisites(report, workspace.config.app.code, backend);
|
|
1194
|
+
return { report, warnings };
|
|
1191
1195
|
});
|
|
1196
|
+
prerequisiteWarnings = prerequisites.warnings;
|
|
1192
1197
|
}
|
|
1193
1198
|
const sources = compileApplicationSources(workspace.config, this.toolchainVersion);
|
|
1194
1199
|
await operationStage('target-preflight', '目标平台只读预检', () => this.validateTargetConfigurationCompatibility(workspace, input.environment, compileLocalConfiguration(workspace.config, this.toolchainVersion)));
|
|
@@ -1204,8 +1209,8 @@ export class OpenXiangdaApplicationServices {
|
|
|
1204
1209
|
const generated = await this.generate({ root: workspace.root, check: true });
|
|
1205
1210
|
if (!generated.ok)
|
|
1206
1211
|
return { ...generated, operation: 'deploy' };
|
|
1207
|
-
const lifecycle = await operationStage('development-records', '
|
|
1208
|
-
const lifecycle = developmentLifecycle(workspace.root, this.appSpecContractIndex(workspace, true));
|
|
1212
|
+
const lifecycle = await operationStage('development-records', '读取需求、架构与测试验收计划(缺口转为警告)', async () => {
|
|
1213
|
+
const lifecycle = developmentLifecycle(workspace.root, this.appSpecContractIndex(workspace, true), undefined, input.appSpecChangeId, 'warning-first');
|
|
1209
1214
|
return { ...lifecycle, ok: lifecycle.readyForTest };
|
|
1210
1215
|
});
|
|
1211
1216
|
if (!lifecycle.readyForTest)
|
|
@@ -1255,7 +1260,11 @@ export class OpenXiangdaApplicationServices {
|
|
|
1255
1260
|
...(input.requestId ? { requestId: input.requestId } : {}),
|
|
1256
1261
|
...(input.approvalLink ? { approvalLink: true } : {}),
|
|
1257
1262
|
});
|
|
1258
|
-
return this.result("deploy", workspace.context.workspace, deployment,
|
|
1263
|
+
return this.result("deploy", workspace.context.workspace, deployment, [
|
|
1264
|
+
...workflowActivation,
|
|
1265
|
+
...prerequisiteWarnings,
|
|
1266
|
+
...lifecycle.diagnostics,
|
|
1267
|
+
], [
|
|
1259
1268
|
{
|
|
1260
1269
|
code: "status",
|
|
1261
1270
|
label: "查看部署状态",
|
|
@@ -1448,7 +1457,7 @@ export class OpenXiangdaApplicationServices {
|
|
|
1448
1457
|
if (!appVersionId)
|
|
1449
1458
|
throw new Error("DEPLOYMENT_APP_VERSION_NOT_AVAILABLE");
|
|
1450
1459
|
const diagnostics = await this.productionPromotionDiagnostics(workspace, client, source, appVersionId);
|
|
1451
|
-
if (diagnostics.
|
|
1460
|
+
if (diagnostics.some(item => item.severity === 'error')) {
|
|
1452
1461
|
return this.result("deploy", workspace.context.workspace, undefined, diagnostics);
|
|
1453
1462
|
}
|
|
1454
1463
|
const deployment = await operationStage('submit', '提交生产晋级', () => client.promote({
|
|
@@ -1457,7 +1466,7 @@ export class OpenXiangdaApplicationServices {
|
|
|
1457
1466
|
environmentKind: environment,
|
|
1458
1467
|
idempotencyKey: `promote:${source.packageDigest}:${environment}`,
|
|
1459
1468
|
}));
|
|
1460
|
-
return this.
|
|
1469
|
+
return this.result("deploy", workspace.context.workspace, deployment, diagnostics, [
|
|
1461
1470
|
{ code: "status", label: "查看生产部署状态", command: `openxiangda status ${deployment.id}` },
|
|
1462
1471
|
]);
|
|
1463
1472
|
}
|
|
@@ -1477,12 +1486,21 @@ export class OpenXiangdaApplicationServices {
|
|
|
1477
1486
|
assertProductionPromotionPreflight(version, {
|
|
1478
1487
|
appCode: workspace.config.app.code, sourceDeploymentId: source.id, appVersionId, packageDigest: source.packageDigest,
|
|
1479
1488
|
});
|
|
1480
|
-
|
|
1489
|
+
let testedLifecycle;
|
|
1490
|
+
try {
|
|
1491
|
+
testedLifecycle = lifecycleAtCommit(workspace.root, version.source.commit, this.appSpecContractIndex(workspace, true));
|
|
1492
|
+
}
|
|
1493
|
+
catch (error) {
|
|
1494
|
+
// 生产晋级使用已封存的 packageDigest;当前机器无法读取来源仓库时仅提示,
|
|
1495
|
+
// 不把本地 Git、VPN 或远端仓库可达性误判成制品不可发布。
|
|
1496
|
+
diagnostics.push(this.advisoryDiagnostic(this.diagnostic('APPSPEC_TESTED_SOURCE_UNAVAILABLE', '无法从测试版本来源读取 AppSpec 验收计划;仍可按不可变测试制品晋级', 'appspec', '网络恢复后补齐验收记录;本次以测试 DeploymentRun 和 packageDigest 为准', { message: error instanceof Error ? error.message : String(error) })));
|
|
1497
|
+
testedLifecycle = { changeId: null, acceptanceIds: [], design: { diagnostics: [] } };
|
|
1498
|
+
}
|
|
1481
1499
|
if (!testedLifecycle.changeId || !testedLifecycle.acceptanceIds.length) {
|
|
1482
|
-
diagnostics.push(this.diagnostic('APPSPEC_TESTED_PLAN_REQUIRED', '
|
|
1500
|
+
diagnostics.push(this.advisoryDiagnostic(this.diagnostic('APPSPEC_TESTED_PLAN_REQUIRED', '指定测试版本缺少可追溯的需求与验收计划;仍可继续生产晋级,请在后续补齐记录', 'appspec', '补齐真实记录并在下一次发布前复核;本次仅作为发布风险提示')));
|
|
1483
1501
|
}
|
|
1484
1502
|
// 原测试提交中的设计基线也必须有效,当前主线的补写不能补签旧版本。
|
|
1485
|
-
diagnostics.push(...testedLifecycle.design.diagnostics);
|
|
1503
|
+
diagnostics.push(...this.advisoryDiagnostics(testedLifecycle.design.diagnostics));
|
|
1486
1504
|
const acceptance = await operationStage('business-acceptance', '核对原测试版本的业务验收报告', async () => {
|
|
1487
1505
|
const result = verifyBusinessAcceptance(workspace.root, source, testedLifecycle);
|
|
1488
1506
|
if (result.ok)
|
|
@@ -1493,13 +1511,13 @@ export class OpenXiangdaApplicationServices {
|
|
|
1493
1511
|
});
|
|
1494
1512
|
return result;
|
|
1495
1513
|
});
|
|
1496
|
-
diagnostics.push(...acceptance.diagnostics);
|
|
1514
|
+
diagnostics.push(...this.advisoryDiagnostics(acceptance.diagnostics));
|
|
1497
1515
|
}
|
|
1498
1516
|
catch (error) {
|
|
1499
1517
|
return [this.configurationCompatibilityDiagnostic(error)];
|
|
1500
1518
|
}
|
|
1501
1519
|
if (workspace.context.workspace.dirty || version.source.dirty) {
|
|
1502
|
-
diagnostics.push(this.diagnostic("PRODUCTION_SOURCE_DIRTY", "
|
|
1520
|
+
diagnostics.push(this.advisoryDiagnostic(this.diagnostic("PRODUCTION_SOURCE_DIRTY", "测试版本或当前工作区存在未提交变更;本次仍复用已封存测试制品晋级", "git", "后续发布前补齐来源快照;当前制品仍按不可变 packageDigest 晋级")));
|
|
1503
1521
|
}
|
|
1504
1522
|
const repository = git(workspace.root, ["config", "--get", "remote.origin.url"]);
|
|
1505
1523
|
const currentRepository = this.repositoryIdentity(repository);
|
|
@@ -1507,9 +1525,9 @@ export class OpenXiangdaApplicationServices {
|
|
|
1507
1525
|
if (!currentRepository ||
|
|
1508
1526
|
!sourceRepository ||
|
|
1509
1527
|
currentRepository !== sourceRepository) {
|
|
1510
|
-
diagnostics.push(this.diagnostic("PRODUCTION_SOURCE_REPOSITORY_MISMATCH", "当前工作区仓库与 AppVersion
|
|
1528
|
+
diagnostics.push(this.advisoryDiagnostic(this.diagnostic("PRODUCTION_SOURCE_REPOSITORY_MISMATCH", "当前工作区仓库与 AppVersion 来源仓库不一致;仓库归属仅作溯源提示", "git.remote.origin.url", "确认 packageDigest 和测试 DeploymentRun 后继续;如需完整溯源再补充仓库信息", { current: repository || null, source: version.source.repository })));
|
|
1511
1529
|
}
|
|
1512
|
-
if (diagnostics.
|
|
1530
|
+
if (diagnostics.some(item => item.severity === 'error'))
|
|
1513
1531
|
return diagnostics;
|
|
1514
1532
|
try {
|
|
1515
1533
|
await operationStage('promotion-source', '核对测试制品的主线来源', () => publishedDeliverySource(workspace.root, version.source.commit));
|
|
@@ -1517,7 +1535,7 @@ export class OpenXiangdaApplicationServices {
|
|
|
1517
1535
|
catch (error) {
|
|
1518
1536
|
if (!(error instanceof DeliverySourceError))
|
|
1519
1537
|
throw error;
|
|
1520
|
-
diagnostics.push(this.diagnostic(error.code, error.message, 'git', String(error.data.remediation), error.data));
|
|
1538
|
+
diagnostics.push(this.advisoryDiagnostic(this.diagnostic(error.code, error.message, 'git', String(error.data.remediation), error.data)));
|
|
1521
1539
|
}
|
|
1522
1540
|
return diagnostics;
|
|
1523
1541
|
}
|
|
@@ -2081,6 +2099,21 @@ export class OpenXiangdaApplicationServices {
|
|
|
2081
2099
|
...(details ? { details } : {}),
|
|
2082
2100
|
};
|
|
2083
2101
|
}
|
|
2102
|
+
advisoryDiagnostic(diagnostic) {
|
|
2103
|
+
return {
|
|
2104
|
+
...diagnostic,
|
|
2105
|
+
severity: diagnostic.severity === 'error' ? 'warning' : diagnostic.severity,
|
|
2106
|
+
retryable: true,
|
|
2107
|
+
details: {
|
|
2108
|
+
...diagnostic.details,
|
|
2109
|
+
gateClass: 'advisory',
|
|
2110
|
+
affects: ['release-readiness'],
|
|
2111
|
+
},
|
|
2112
|
+
};
|
|
2113
|
+
}
|
|
2114
|
+
advisoryDiagnostics(diagnostics) {
|
|
2115
|
+
return diagnostics.map(diagnostic => this.advisoryDiagnostic(diagnostic));
|
|
2116
|
+
}
|
|
2084
2117
|
connectedDevelopmentFailure(error, workspaceRoot) {
|
|
2085
2118
|
const rawCode = String(error?.code ||
|
|
2086
2119
|
(error instanceof Error ? error.message.split(":", 1)[0] : "") ||
|