openxiangda 1.0.237 → 1.0.239
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/lib/delivery-v2-executor.js +164 -3
- package/lib/delivery-v2-package.js +32 -1
- package/package.json +1 -1
|
@@ -2,6 +2,8 @@ const crypto = require('crypto');
|
|
|
2
2
|
const fs = require('fs');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const {
|
|
5
|
+
collectConfigurationManifestCodes,
|
|
6
|
+
collectManifestCodes,
|
|
5
7
|
compileAppPackage,
|
|
6
8
|
sha256,
|
|
7
9
|
sha256Canonical,
|
|
@@ -220,17 +222,25 @@ function createDeliveryV2Executor(dependencies) {
|
|
|
220
222
|
const originalCwd = process.cwd();
|
|
221
223
|
const executionTarget = {
|
|
222
224
|
...input.target,
|
|
223
|
-
deploymentId:
|
|
225
|
+
deploymentId:
|
|
226
|
+
input.run?.deploymentId ||
|
|
227
|
+
input.run?.control?.deploymentId ||
|
|
228
|
+
input.target.deploymentId ||
|
|
229
|
+
null,
|
|
224
230
|
};
|
|
225
231
|
let activeRun = input.run;
|
|
226
232
|
let currentStep = 'preparing';
|
|
227
233
|
let currentComponent = 'delivery-v2';
|
|
228
234
|
try {
|
|
229
235
|
process.chdir(input.executionRoot);
|
|
236
|
+
const executionTargets = normalizeLegacyPackageTargetsForExecution(
|
|
237
|
+
input.targets,
|
|
238
|
+
input.executionRoot
|
|
239
|
+
);
|
|
230
240
|
deps.installDeliveryContext(
|
|
231
241
|
executionTarget,
|
|
232
242
|
activeRun,
|
|
233
|
-
|
|
243
|
+
executionTargets
|
|
234
244
|
);
|
|
235
245
|
restoreDeliveryCheckpointFiles(
|
|
236
246
|
input.executionRoot,
|
|
@@ -252,7 +262,7 @@ function createDeliveryV2Executor(dependencies) {
|
|
|
252
262
|
);
|
|
253
263
|
const steps = decorateSteps(
|
|
254
264
|
buildWorkspaceReleaseSteps(
|
|
255
|
-
|
|
265
|
+
executionTargets,
|
|
256
266
|
input.packageManifest.runtimeMode,
|
|
257
267
|
executionTarget.profileName,
|
|
258
268
|
activeRun.control?.changeId
|
|
@@ -285,6 +295,14 @@ function createDeliveryV2Executor(dependencies) {
|
|
|
285
295
|
activeRun.result?.[doneStage] || { resumed: true };
|
|
286
296
|
continue;
|
|
287
297
|
}
|
|
298
|
+
if (step.id === 'app-finalize') {
|
|
299
|
+
prepareAppFinalizeStep(step, {
|
|
300
|
+
executionRoot: input.executionRoot,
|
|
301
|
+
run: activeRun,
|
|
302
|
+
target: executionTarget,
|
|
303
|
+
steps,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
288
306
|
currentStep = step.id;
|
|
289
307
|
currentComponent = step.stagedKind || step.id;
|
|
290
308
|
const result = await deps.runOpenXiangdaInProcess(step.args, {
|
|
@@ -785,6 +803,22 @@ function decorateSteps(
|
|
|
785
803
|
step.args.push('--environment-id', target.environmentId);
|
|
786
804
|
}
|
|
787
805
|
step.args.push('--delivery-run-id', run.id);
|
|
806
|
+
const stagedIndex = step.args.indexOf('--staged-resources-json');
|
|
807
|
+
if (stagedIndex >= 0 && target.deploymentId) {
|
|
808
|
+
step.args[stagedIndex + 1] = path
|
|
809
|
+
.relative(
|
|
810
|
+
executionRoot,
|
|
811
|
+
path.join(
|
|
812
|
+
deliveryReleaseDirectory(
|
|
813
|
+
executionRoot,
|
|
814
|
+
run.control?.changeId,
|
|
815
|
+
target.deploymentId
|
|
816
|
+
),
|
|
817
|
+
'staged-resources.json'
|
|
818
|
+
)
|
|
819
|
+
)
|
|
820
|
+
.replace(/\\/g, '/');
|
|
821
|
+
}
|
|
788
822
|
}
|
|
789
823
|
step.command = commandFromArgs(step.args);
|
|
790
824
|
result.push(step);
|
|
@@ -852,6 +886,70 @@ function compactStepResult(stepId, result, context = {}) {
|
|
|
852
886
|
return compact;
|
|
853
887
|
}
|
|
854
888
|
|
|
889
|
+
function prepareAppFinalizeStep(step, context = {}) {
|
|
890
|
+
const stagedIndex = step.args.indexOf('--staged-resources-json');
|
|
891
|
+
if (stagedIndex < 0) {
|
|
892
|
+
return {
|
|
893
|
+
mode: 'frozen-capture',
|
|
894
|
+
stagedResourceCount: 0,
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
const stagedStepIds = (context.steps || [])
|
|
899
|
+
.filter(candidate => Boolean(candidate.stagedKind))
|
|
900
|
+
.map(candidate => candidate.id);
|
|
901
|
+
const incompleteStagedCheckpoints = stagedStepIds.filter(stepId => {
|
|
902
|
+
const checkpointResult =
|
|
903
|
+
context.run?.result?.[checkpointName('done', stepId)];
|
|
904
|
+
if (!checkpointResult?.id) return false;
|
|
905
|
+
return (
|
|
906
|
+
normalizeCheckpointStagedResources(
|
|
907
|
+
checkpointResult.stagedResources || []
|
|
908
|
+
).length === 0
|
|
909
|
+
);
|
|
910
|
+
});
|
|
911
|
+
if (incompleteStagedCheckpoints.length > 0) {
|
|
912
|
+
throw deliveryError(
|
|
913
|
+
'DELIVERY_CHECKPOINT_STAGED_RESOURCES_MISSING',
|
|
914
|
+
`服务端检查点 ${incompleteStagedCheckpoints.join(
|
|
915
|
+
', '
|
|
916
|
+
)} 已记录子 Release,但缺少可恢复 stagedResources`,
|
|
917
|
+
false
|
|
918
|
+
);
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
const restored = restoreDeliveryCheckpointFiles(
|
|
922
|
+
context.executionRoot,
|
|
923
|
+
context.run,
|
|
924
|
+
context.target
|
|
925
|
+
);
|
|
926
|
+
if (restored.stagedResourceCount === 0) {
|
|
927
|
+
step.args.splice(stagedIndex, 2);
|
|
928
|
+
step.command = commandFromArgs(step.args);
|
|
929
|
+
return {
|
|
930
|
+
mode: 'frozen-capture',
|
|
931
|
+
stagedResourceCount: 0,
|
|
932
|
+
};
|
|
933
|
+
}
|
|
934
|
+
|
|
935
|
+
const stagedResourcesPath = path.resolve(
|
|
936
|
+
context.executionRoot,
|
|
937
|
+
step.args[stagedIndex + 1]
|
|
938
|
+
);
|
|
939
|
+
if (!fs.existsSync(stagedResourcesPath)) {
|
|
940
|
+
throw deliveryError(
|
|
941
|
+
'DELIVERY_CHECKPOINT_FILE_MISSING',
|
|
942
|
+
'服务端 stagedResources 检查点已恢复,但 app-finalize 暂存资源文件缺失',
|
|
943
|
+
false
|
|
944
|
+
);
|
|
945
|
+
}
|
|
946
|
+
step.command = commandFromArgs(step.args);
|
|
947
|
+
return {
|
|
948
|
+
mode: 'staged-children',
|
|
949
|
+
stagedResourceCount: restored.stagedResourceCount,
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
|
|
855
953
|
function restoreDeliveryCheckpointFiles(executionRoot, run, target) {
|
|
856
954
|
const changeId = String(run?.control?.changeId || '').trim();
|
|
857
955
|
if (!changeId) return { stagedResourceCount: 0, restored: false };
|
|
@@ -1090,6 +1188,66 @@ function defaultIdempotencyKey(kind, target, digest) {
|
|
|
1090
1188
|
].join(':');
|
|
1091
1189
|
}
|
|
1092
1190
|
|
|
1191
|
+
function normalizeLegacyPackageTargetsForExecution(targets, executionRoot) {
|
|
1192
|
+
const selectors = targets?.resourceSelectors?.dataViews;
|
|
1193
|
+
if (!Array.isArray(selectors) || selectors.length === 0) return targets;
|
|
1194
|
+
const dataViewDir = path.join(
|
|
1195
|
+
path.resolve(executionRoot),
|
|
1196
|
+
'src',
|
|
1197
|
+
'resources',
|
|
1198
|
+
'data-views'
|
|
1199
|
+
);
|
|
1200
|
+
if (!fs.existsSync(dataViewDir)) return targets;
|
|
1201
|
+
|
|
1202
|
+
const actualCodes = new Set();
|
|
1203
|
+
const legacyNestedCodes = new Set();
|
|
1204
|
+
const visit = directory => {
|
|
1205
|
+
for (const entry of fs
|
|
1206
|
+
.readdirSync(directory, { withFileTypes: true })
|
|
1207
|
+
.sort((left, right) => left.name.localeCompare(right.name))) {
|
|
1208
|
+
const absolute = path.join(directory, entry.name);
|
|
1209
|
+
if (entry.isDirectory()) {
|
|
1210
|
+
visit(absolute);
|
|
1211
|
+
continue;
|
|
1212
|
+
}
|
|
1213
|
+
if (!entry.isFile() || !entry.name.endsWith('.json')) continue;
|
|
1214
|
+
let value;
|
|
1215
|
+
try {
|
|
1216
|
+
value = JSON.parse(fs.readFileSync(absolute, 'utf8'));
|
|
1217
|
+
} catch {
|
|
1218
|
+
// The resource command remains responsible for reporting malformed
|
|
1219
|
+
// manifests. This compatibility normalization only narrows selectors.
|
|
1220
|
+
continue;
|
|
1221
|
+
}
|
|
1222
|
+
const topLevelCodes = collectConfigurationManifestCodes(
|
|
1223
|
+
'data-view',
|
|
1224
|
+
value
|
|
1225
|
+
);
|
|
1226
|
+
for (const code of topLevelCodes) {
|
|
1227
|
+
actualCodes.add(code);
|
|
1228
|
+
}
|
|
1229
|
+
const topLevelSet = new Set(topLevelCodes);
|
|
1230
|
+
for (const code of collectManifestCodes(value)) {
|
|
1231
|
+
if (!topLevelSet.has(code)) legacyNestedCodes.add(code);
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
};
|
|
1235
|
+
visit(dataViewDir);
|
|
1236
|
+
if (actualCodes.size === 0 || legacyNestedCodes.size === 0) return targets;
|
|
1237
|
+
|
|
1238
|
+
const filtered = selectors.filter(
|
|
1239
|
+
code => !legacyNestedCodes.has(String(code)) || actualCodes.has(String(code))
|
|
1240
|
+
);
|
|
1241
|
+
if (filtered.length === selectors.length) return targets;
|
|
1242
|
+
return {
|
|
1243
|
+
...targets,
|
|
1244
|
+
resourceSelectors: {
|
|
1245
|
+
...(targets.resourceSelectors || {}),
|
|
1246
|
+
dataViews: filtered,
|
|
1247
|
+
},
|
|
1248
|
+
};
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1093
1251
|
function normalizeDigest(value) {
|
|
1094
1252
|
const digest = String(value || '')
|
|
1095
1253
|
.trim()
|
|
@@ -1162,6 +1320,9 @@ module.exports = {
|
|
|
1162
1320
|
CONFIG_TARGET_BY_RESOURCE_TYPE,
|
|
1163
1321
|
compactStepResult,
|
|
1164
1322
|
createDeliveryV2Executor,
|
|
1323
|
+
decorateSteps,
|
|
1324
|
+
normalizeLegacyPackageTargetsForExecution,
|
|
1325
|
+
prepareAppFinalizeStep,
|
|
1165
1326
|
releaseTargets,
|
|
1166
1327
|
restoreDeliveryCheckpointFiles,
|
|
1167
1328
|
structuredFailure,
|
|
@@ -285,7 +285,9 @@ function discoverResourceInventory(workspaceRoot, files) {
|
|
|
285
285
|
relative.startsWith(prefix)
|
|
286
286
|
);
|
|
287
287
|
if (matched) {
|
|
288
|
-
for (const code of
|
|
288
|
+
for (const code of collectConfigurationManifestCodes(matched[1], value)) {
|
|
289
|
+
addConfiguration(matched[1], code);
|
|
290
|
+
}
|
|
289
291
|
}
|
|
290
292
|
}
|
|
291
293
|
return {
|
|
@@ -301,6 +303,33 @@ function discoverResourceInventory(workspaceRoot, files) {
|
|
|
301
303
|
};
|
|
302
304
|
}
|
|
303
305
|
|
|
306
|
+
function collectConfigurationManifestCodes(type, value) {
|
|
307
|
+
if (type !== 'data-view') return collectManifestCodes(value);
|
|
308
|
+
|
|
309
|
+
const result = new Set();
|
|
310
|
+
const addItem = item => {
|
|
311
|
+
if (!item || typeof item !== 'object' || Array.isArray(item)) return;
|
|
312
|
+
const code = String(item.code || item.resourceCode || '').trim();
|
|
313
|
+
if (code) result.add(code);
|
|
314
|
+
};
|
|
315
|
+
if (Array.isArray(value)) {
|
|
316
|
+
value.forEach(addItem);
|
|
317
|
+
return [...result];
|
|
318
|
+
}
|
|
319
|
+
if (!value || typeof value !== 'object') return [];
|
|
320
|
+
const rootCode = String(value.code || value.resourceCode || '').trim();
|
|
321
|
+
if (rootCode) {
|
|
322
|
+
result.add(rootCode);
|
|
323
|
+
return [...result];
|
|
324
|
+
}
|
|
325
|
+
for (const key of ['dataViews', 'data-views']) {
|
|
326
|
+
const items = value[key];
|
|
327
|
+
if (Array.isArray(items)) items.forEach(addItem);
|
|
328
|
+
else addItem(items);
|
|
329
|
+
}
|
|
330
|
+
return [...result];
|
|
331
|
+
}
|
|
332
|
+
|
|
304
333
|
function collectManifestCodes(value, result = new Set()) {
|
|
305
334
|
if (Array.isArray(value)) {
|
|
306
335
|
for (const item of value) collectManifestCodes(item, result);
|
|
@@ -686,6 +715,8 @@ module.exports = {
|
|
|
686
715
|
COMPILER_VERSION,
|
|
687
716
|
PACKAGE_SCHEMA_VERSION,
|
|
688
717
|
canonicalJson,
|
|
718
|
+
collectConfigurationManifestCodes,
|
|
719
|
+
collectManifestCodes,
|
|
689
720
|
compileAppPackage,
|
|
690
721
|
discoverResourceInventory,
|
|
691
722
|
layerForSourceFile,
|