@aws-cdk/integ-runner 2.197.10 → 2.197.11

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.
@@ -4670,7 +4670,7 @@ var require_semver2 = __commonJS({
4670
4670
  // ../cloud-assembly-schema/cli-version.json
4671
4671
  var require_cli_version = __commonJS({
4672
4672
  "../cloud-assembly-schema/cli-version.json"(exports2, module2) {
4673
- module2.exports = { version: "2.1115.1" };
4673
+ module2.exports = { version: "2.1116.0" };
4674
4674
  }
4675
4675
  });
4676
4676
 
@@ -79283,7 +79283,7 @@ var init_messages = __esm({
79283
79283
  code: "CDK_TOOLKIT_W8010",
79284
79284
  description: "Refactor execution not yet supported"
79285
79285
  }),
79286
- // 9: Bootstrap & gc (9xxx)
79286
+ // 9: Bootstrap, gc, flags & publish (9xxx)
79287
79287
  CDK_TOOLKIT_I9000: info({
79288
79288
  code: "CDK_TOOLKIT_I9000",
79289
79289
  description: "Provides bootstrap times",
@@ -79310,12 +79310,27 @@ var init_messages = __esm({
79310
79310
  description: "Bootstrap failed",
79311
79311
  interface: "ErrorPayload"
79312
79312
  }),
79313
- // flags (93xxx)
79313
+ // flags (93xx)
79314
79314
  CDK_TOOLKIT_I9300: info({
79315
79315
  code: "CDK_TOOLKIT_I9300",
79316
79316
  description: "Confirm the feature flag configuration changes",
79317
79317
  interface: "FeatureFlagChangeRequest"
79318
79318
  }),
79319
+ // publish (94xx)
79320
+ CDK_TOOLKIT_I9400: info({
79321
+ code: "CDK_TOOLKIT_I9400",
79322
+ description: "All assets are already published"
79323
+ }),
79324
+ CDK_TOOLKIT_I9401: info({
79325
+ code: "CDK_TOOLKIT_I9401",
79326
+ description: "Publishing assets",
79327
+ interface: "AssetsPayload"
79328
+ }),
79329
+ CDK_TOOLKIT_I9402: result({
79330
+ code: "CDK_TOOLKIT_I9402",
79331
+ description: "Publish assets results on success",
79332
+ interface: "AssetsPayload"
79333
+ }),
79319
79334
  // Notices
79320
79335
  CDK_TOOLKIT_I0100: info({
79321
79336
  code: "CDK_TOOLKIT_I0100",
@@ -122603,7 +122618,7 @@ var require_dist_cjs57 = __commonJS({
122603
122618
  __name(this, "GetGeneratedTemplateCommand");
122604
122619
  }
122605
122620
  };
122606
- var GetHookResultCommand = class extends smithyClient.Command.classBuilder().ep(commonParams6).m(function(Command, cs, config, o6) {
122621
+ var GetHookResultCommand2 = class extends smithyClient.Command.classBuilder().ep(commonParams6).m(function(Command, cs, config, o6) {
122607
122622
  return [middlewareEndpoint.getEndpointPlugin(config, Command.getEndpointParameterInstructions())];
122608
122623
  }).s("CloudFormation", "GetHookResult", {}).n("CloudFormationClient", "GetHookResultCommand").sc(schemas_0.GetHookResult$).build() {
122609
122624
  static {
@@ -123847,7 +123862,7 @@ var require_dist_cjs57 = __commonJS({
123847
123862
  ExecuteChangeSetCommand: ExecuteChangeSetCommand2,
123848
123863
  ExecuteStackRefactorCommand: ExecuteStackRefactorCommand2,
123849
123864
  GetGeneratedTemplateCommand: GetGeneratedTemplateCommand2,
123850
- GetHookResultCommand,
123865
+ GetHookResultCommand: GetHookResultCommand2,
123851
123866
  GetStackPolicyCommand,
123852
123867
  GetTemplateCommand: GetTemplateCommand2,
123853
123868
  GetTemplateSummaryCommand: GetTemplateSummaryCommand2,
@@ -124538,7 +124553,7 @@ var require_dist_cjs57 = __commonJS({
124538
124553
  exports2.GeneratedTemplateStatus = GeneratedTemplateStatus;
124539
124554
  exports2.GeneratedTemplateUpdateReplacePolicy = GeneratedTemplateUpdateReplacePolicy;
124540
124555
  exports2.GetGeneratedTemplateCommand = GetGeneratedTemplateCommand2;
124541
- exports2.GetHookResultCommand = GetHookResultCommand;
124556
+ exports2.GetHookResultCommand = GetHookResultCommand2;
124542
124557
  exports2.GetStackPolicyCommand = GetStackPolicyCommand;
124543
124558
  exports2.GetTemplateCommand = GetTemplateCommand2;
124544
124559
  exports2.GetTemplateSummaryCommand = GetTemplateSummaryCommand2;
@@ -287536,7 +287551,8 @@ var init_sdk = __esm({
287536
287551
  },
287537
287552
  input
287538
287553
  );
287539
- }, "waitUntilStackRefactorExecuteComplete")
287554
+ }, "waitUntilStackRefactorExecuteComplete"),
287555
+ getHookResult: /* @__PURE__ */ __name((input) => client.send(new import_client_cloudformation.GetHookResultCommand(input)), "getHookResult")
287540
287556
  };
287541
287557
  }
287542
287558
  cloudWatchLogs() {
@@ -294917,6 +294933,8 @@ var init_stack_activity_monitor = __esm({
294917
294933
  ioHelper;
294918
294934
  stackName;
294919
294935
  stack;
294936
+ cfn;
294937
+ envResources;
294920
294938
  constructor({
294921
294939
  cfn,
294922
294940
  ioHelper,
@@ -294924,11 +294942,14 @@ var init_stack_activity_monitor = __esm({
294924
294942
  stackName,
294925
294943
  resourcesTotal,
294926
294944
  changeSetCreationTime,
294927
- pollingInterval = 2e3
294945
+ pollingInterval = 2e3,
294946
+ envResources
294928
294947
  }) {
294929
294948
  this.ioHelper = ioHelper;
294930
294949
  this.stack = stack;
294931
294950
  this.stackName = stackName;
294951
+ this.cfn = cfn;
294952
+ this.envResources = envResources;
294932
294953
  this.progressMonitor = new StackProgressMonitor(resourcesTotal);
294933
294954
  this.pollingInterval = pollingInterval;
294934
294955
  this.poller = new StackEventPoller(cfn, {
@@ -295016,6 +295037,65 @@ var init_stack_activity_monitor = __esm({
295016
295037
  }
295017
295038
  return resourceMetadata(this.stack, logicalId);
295018
295039
  }
295040
+ /**
295041
+ * Trims leading/trailing whitespace, collapses all internal whitespace
295042
+ * (including newlines) to a single space, and truncates to `maxChars`
295043
+ * characters, appending `[...truncated]` when the original was longer.
295044
+ */
295045
+ normalizeMessage(message2, maxChars = 400) {
295046
+ const normalized = message2.trim().replace(/\s+/g, " ");
295047
+ return normalized.length > maxChars ? normalized.substring(0, maxChars) + "[...truncated]" : normalized;
295048
+ }
295049
+ /**
295050
+ * Fetches Guard Hook annotation details via GetHookResult API and formats them
295051
+ * into a human-readable string. Returns undefined if the fetch fails or there
295052
+ * are no failed annotations.
295053
+ */
295054
+ async fetchGuardHookAnnotations(hookInvocationId) {
295055
+ try {
295056
+ const result2 = await this.cfn.getHookResult({ HookResultId: hookInvocationId });
295057
+ const annotations = result2.Annotations ?? [];
295058
+ const failedAnnotations = annotations.filter((a6) => a6.Status === "FAILED");
295059
+ if (failedAnnotations.length === 0) {
295060
+ return void 0;
295061
+ }
295062
+ const lines = ["NonCompliant Rules:", ""];
295063
+ for (const annotation of failedAnnotations) {
295064
+ if (annotation.AnnotationName) {
295065
+ lines.push(`[${annotation.AnnotationName}]`);
295066
+ }
295067
+ if (annotation.StatusMessage) {
295068
+ lines.push(`\u2022 ${this.normalizeMessage(annotation.StatusMessage)}`);
295069
+ }
295070
+ if (annotation.RemediationMessage) {
295071
+ lines.push(`Remediation: ${this.normalizeMessage(annotation.RemediationMessage)}`);
295072
+ }
295073
+ lines.push("");
295074
+ }
295075
+ return lines.join("\n").trimEnd();
295076
+ } catch (e6) {
295077
+ const errorMessage = e6 instanceof Error ? e6.message : String(e6);
295078
+ const isPermissionsError = e6.name === "AccessDeniedException" || typeof errorMessage === "string" && errorMessage.toLowerCase().includes("not authorized to perform: cloudformation:gethookresult");
295079
+ if (isPermissionsError && this.envResources) {
295080
+ let currentVersion = void 0;
295081
+ try {
295082
+ currentVersion = (await this.envResources.lookupToolkit()).version;
295083
+ } catch {
295084
+ }
295085
+ await this.ioHelper.defaults.warn(
295086
+ util6.format(
295087
+ `Failed to fetch result details for Hook invocation ${hookInvocationId}: ${errorMessage}. Make sure you have permissions to call the GetHookResult API, or re-bootstrap your environment by running 'cdk bootstrap' to update the Bootstrap CDK Toolkit stack.
295088
+ 'Bootstrap toolkit stack version 31 or later is needed; current version: ${currentVersion ?? "unknown"}.`
295089
+ )
295090
+ );
295091
+ } else {
295092
+ await this.ioHelper.defaults.warn(
295093
+ util6.format("Failed to fetch Guard Hook details for invocation %s: %s", hookInvocationId, errorMessage)
295094
+ );
295095
+ }
295096
+ return void 0;
295097
+ }
295098
+ }
295019
295099
  /**
295020
295100
  * Reads all new events from the stack history
295021
295101
  *
@@ -295025,6 +295105,12 @@ var init_stack_activity_monitor = __esm({
295025
295105
  const pollEvents = await this.poller.poll();
295026
295106
  for (const resourceEvent of pollEvents) {
295027
295107
  this.progressMonitor.process(resourceEvent.event);
295108
+ if (resourceEvent.event.HookInvocationId) {
295109
+ const annotations = await this.fetchGuardHookAnnotations(resourceEvent.event.HookInvocationId);
295110
+ if (annotations) {
295111
+ resourceEvent.event.HookStatusReason = annotations;
295112
+ }
295113
+ }
295028
295114
  const activity = {
295029
295115
  deployment: monitorId,
295030
295116
  event: resourceEvent.event,
@@ -295421,6 +295507,11 @@ async function getNestedStackArn(nestedStackLogicalId, listStackResources) {
295421
295507
  function isCdkManagedNestedStack(stackResource) {
295422
295508
  return stackResource.Type === "AWS::CloudFormation::Stack" && stackResource.Metadata && stackResource.Metadata["aws:asset:path"];
295423
295509
  }
295510
+ function templateContainsNestedStacks(template) {
295511
+ return Object.values(template?.Resources ?? {}).some(
295512
+ (resource) => resource.Type === "AWS::CloudFormation::Stack"
295513
+ );
295514
+ }
295424
295515
  var path23, fs26;
295425
295516
  var init_nested_stack_helpers = __esm({
295426
295517
  "../toolkit-lib/lib/api/cloudformation/nested-stack-helpers.ts"() {
@@ -295437,6 +295528,7 @@ var init_nested_stack_helpers = __esm({
295437
295528
  __name(getNestedStackTemplates, "getNestedStackTemplates");
295438
295529
  __name(getNestedStackArn, "getNestedStackArn");
295439
295530
  __name(isCdkManagedNestedStack, "isCdkManagedNestedStack");
295531
+ __name(templateContainsNestedStacks, "templateContainsNestedStacks");
295440
295532
  }
295441
295533
  });
295442
295534
 
@@ -295512,16 +295604,10 @@ async function waitForChangeSet(cfn, ioHelper, stackName, changeSetName, { fetch
295512
295604
  return ret;
295513
295605
  }
295514
295606
  async function createDiffChangeSet(ioHelper, options) {
295515
- for (const resource of Object.values(options.stack.template.Resources ?? {})) {
295516
- if (resource.Type === "AWS::CloudFormation::Stack") {
295517
- if (options.failOnError) {
295518
- throw new ToolkitError("NestedStacksNotSupported", "Changeset diff is not supported for stacks with nested stacks. Please use '--method=auto' to allow falling back to a template diff.");
295519
- }
295520
- await ioHelper.defaults.debug("This stack contains one or more nested stacks, falling back to template diff...");
295521
- return void 0;
295522
- }
295523
- }
295524
- return uploadBodyParameterAndCreateChangeSet(ioHelper, options);
295607
+ return uploadBodyParameterAndCreateChangeSet(ioHelper, {
295608
+ ...options,
295609
+ includeNestedStacks: templateContainsNestedStacks(options.stack.template)
295610
+ });
295525
295611
  }
295526
295612
  function templatesFromAssetManifestArtifact(artifact) {
295527
295613
  const assets = [];
@@ -295549,7 +295635,8 @@ async function uploadBodyParameterAndCreateChangeSet(ioHelper, options) {
295549
295635
  env.resources
295550
295636
  );
295551
295637
  const cfn = env.sdk.cloudFormation();
295552
- const exists = (await CloudFormationStack.lookup(cfn, options.stack.stackName, false)).exists;
295638
+ const stack = await CloudFormationStack.lookup(cfn, options.stack.stackName, false);
295639
+ const exists = stack.exists && stack.stackStatus.name !== "REVIEW_IN_PROGRESS";
295553
295640
  const executionRoleArn = await env.replacePlaceholders(options.stack.cloudFormationExecutionRoleArn);
295554
295641
  await ioHelper.defaults.info(
295555
295642
  "Hold on while we create a read-only change set to get a diff with accurate replacement information (use --method=template to use a less accurate but faster template-only diff)\n"
@@ -295565,6 +295652,7 @@ async function uploadBodyParameterAndCreateChangeSet(ioHelper, options) {
295565
295652
  parameters: options.parameters,
295566
295653
  resourcesToImport: options.resourcesToImport,
295567
295654
  importExistingResources: options.importExistingResources,
295655
+ includeNestedStacks: options.includeNestedStacks,
295568
295656
  role: executionRoleArn
295569
295657
  });
295570
295658
  } catch (e6) {
@@ -295612,6 +295700,7 @@ async function createChangeSet(ioHelper, options) {
295612
295700
  Parameters: stackParams.apiParameters,
295613
295701
  ResourcesToImport: options.resourcesToImport,
295614
295702
  ImportExistingResources: options.importExistingResources,
295703
+ IncludeNestedStacks: options.includeNestedStacks || void 0,
295615
295704
  RoleARN: options.role,
295616
295705
  Tags: toCfnTags(options.stack.tags),
295617
295706
  Capabilities: ["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM", "CAPABILITY_AUTO_EXPAND"]
@@ -309180,6 +309269,13 @@ var init_progress2 = __esm({
309180
309269
  }
309181
309270
  });
309182
309271
 
309272
+ // ../toolkit-lib/lib/payloads/publish-assets.ts
309273
+ var init_publish_assets = __esm({
309274
+ "../toolkit-lib/lib/payloads/publish-assets.ts"() {
309275
+ "use strict";
309276
+ }
309277
+ });
309278
+
309183
309279
  // ../toolkit-lib/lib/payloads/refactor.ts
309184
309280
  var init_refactor = __esm({
309185
309281
  "../toolkit-lib/lib/payloads/refactor.ts"() {
@@ -309257,6 +309353,7 @@ var init_payloads = __esm({
309257
309353
  init_synth();
309258
309354
  init_types6();
309259
309355
  init_progress2();
309356
+ init_publish_assets();
309260
309357
  init_refactor();
309261
309358
  init_watch();
309262
309359
  init_stack_details();
@@ -311213,6 +311310,7 @@ var init_deploy_stack = __esm({
311213
311310
  Description: `CDK Changeset for execution ${this.uuid}`,
311214
311311
  ClientToken: `create${this.uuid}`,
311215
311312
  ImportExistingResources: importExistingResources,
311313
+ IncludeNestedStacks: templateContainsNestedStacks(this.stackArtifact.template),
311216
311314
  DeploymentMode: revertDrift ? "REVERT_DRIFT" : void 0,
311217
311315
  ...this.commonPrepareOptions()
311218
311316
  });
@@ -311314,7 +311412,8 @@ var init_deploy_stack = __esm({
311314
311412
  stackName: this.stackName,
311315
311413
  resourcesTotal: expectedChanges,
311316
311414
  ioHelper: this.ioHelper,
311317
- changeSetCreationTime: startTime
311415
+ changeSetCreationTime: startTime,
311416
+ envResources: this.options.envResources
311318
311417
  });
311319
311418
  await monitor.start();
311320
311419
  let finalState = this.cloudFormationStack;
@@ -312950,6 +313049,9 @@ async function cfnDiff2(ioHelper, stacks, deployments, options, sdkProvider, inc
312950
313049
  methodOptions.fallbackToTemplate,
312951
313050
  methodOptions.importExistingResources
312952
313051
  ) : void 0;
313052
+ if (changeSet) {
313053
+ await attachNestedChangeSetData(deployments, stack, changeSet, nestedStacks);
313054
+ }
312953
313055
  const mappings = allMappings.find(
312954
313056
  (m6) => m6.environment.region === stack.environment.region && m6.environment.account === stack.environment.account
312955
313057
  )?.mappings ?? {};
@@ -312977,6 +313079,31 @@ async function changeSetDiff(ioHelper, deployments, stack, sdkProvider, resource
312977
313079
  importExistingResources
312978
313080
  });
312979
313081
  }
313082
+ async function attachNestedChangeSetData(deployments, stack, rootChangeSet, nestedStacks) {
313083
+ const env = await deployments.envs.accessStackForReadOnlyStackOperations(stack);
313084
+ const cfn = env.sdk.cloudFormation();
313085
+ for (const change of rootChangeSet.Changes ?? []) {
313086
+ const rc = change.ResourceChange;
313087
+ if (rc?.ResourceType !== "AWS::CloudFormation::Stack" || !rc.ChangeSetId || !rc.LogicalResourceId) {
313088
+ continue;
313089
+ }
313090
+ const nested = nestedStacks[rc.LogicalResourceId];
313091
+ if (!nested) {
313092
+ continue;
313093
+ }
313094
+ const nestedChangeSet = await cfn.describeChangeSet({
313095
+ ChangeSetName: rc.ChangeSetId,
313096
+ StackName: rc.PhysicalResourceId ?? rc.LogicalResourceId
313097
+ });
313098
+ nestedStacks[rc.LogicalResourceId] = {
313099
+ ...nested,
313100
+ changeSet: nestedChangeSet
313101
+ };
313102
+ if (nestedChangeSet && Object.keys(nested.nestedStackTemplates).length > 0) {
313103
+ await attachNestedChangeSetData(deployments, stack, nestedChangeSet, nested.nestedStackTemplates);
313104
+ }
313105
+ }
313106
+ }
312980
313107
  function appendObject(obj1, obj2) {
312981
313108
  for (const key in obj2) {
312982
313109
  obj1[key] = obj2[key];
@@ -312999,6 +313126,7 @@ var init_helpers4 = __esm({
312999
313126
  __name(localFileDiff, "localFileDiff");
313000
313127
  __name(cfnDiff2, "cfnDiff");
313001
313128
  __name(changeSetDiff, "changeSetDiff");
313129
+ __name(attachNestedChangeSetData, "attachNestedChangeSetData");
313002
313130
  __name(appendObject, "appendObject");
313003
313131
  }
313004
313132
  });
@@ -313695,6 +313823,14 @@ var init_bootstrap3 = __esm({
313695
313823
  });
313696
313824
 
313697
313825
  // ../toolkit-lib/lib/api/diff/diff-formatter.ts
313826
+ function permissionTypeFromDiff(diff) {
313827
+ if (diff.permissionsBroadened) {
313828
+ return "broadening" /* BROADENING */;
313829
+ } else if (diff.permissionsAnyChanges) {
313830
+ return "non-broadening" /* NON_BROADENING */;
313831
+ }
313832
+ return "none" /* NONE */;
313833
+ }
313698
313834
  function buildLogicalToPathMap(stack) {
313699
313835
  const map2 = {};
313700
313836
  for (const md of stack.findMetadataByType(cxschema9.ArtifactMetadataEntryType.LOGICAL_ID)) {
@@ -313756,44 +313892,35 @@ var init_diff_formatter = __esm({
313756
313892
  static {
313757
313893
  __name(this, "DiffFormatter");
313758
313894
  }
313759
- oldTemplate;
313760
- newTemplate;
313895
+ templateInfo;
313761
313896
  stackName;
313762
- changeSet;
313763
- nestedStacks;
313764
313897
  isImport;
313765
313898
  mappings;
313766
313899
  /**
313767
- * Stores the TemplateDiffs that get calculated in this DiffFormatter,
313768
- * indexed by the stack name.
313900
+ * Cache of computed TemplateDiffs, indexed by stack name.
313769
313901
  */
313770
- _diffs = {};
313902
+ cache = /* @__PURE__ */ new Map();
313771
313903
  constructor(props) {
313772
- this.oldTemplate = props.templateInfo.oldTemplate;
313773
- this.newTemplate = props.templateInfo.newTemplate;
313904
+ this.templateInfo = props.templateInfo;
313774
313905
  this.stackName = props.templateInfo.newTemplate.displayName ?? props.templateInfo.newTemplate.stackName;
313775
- this.changeSet = props.templateInfo.changeSet;
313776
- this.nestedStacks = props.templateInfo.nestedStacks;
313777
313906
  this.isImport = props.templateInfo.isImport ?? false;
313778
313907
  this.mappings = props.templateInfo.mappings ?? {};
313779
313908
  }
313780
313909
  get diffs() {
313781
- return this._diffs;
313910
+ return Object.fromEntries(this.cache);
313782
313911
  }
313783
313912
  /**
313784
- * Get or creates the diff of a stack.
313785
- * If it creates the diff, it stores the result in a map for
313786
- * easier retrieval later.
313913
+ * Compute the diff for a single stack. Results are cached by stack name.
313914
+ *
313915
+ * @param stackName - The name to cache the diff under
313916
+ * @param oldTemplate - The deployed template
313917
+ * @param newTemplate - The new/generated template (read from the artifact)
313918
+ * @param changeSet - The CloudFormation changeset for this specific stack, if available
313919
+ * @param mappings - Resource move mappings
313787
313920
  */
313788
- diff(stackName, oldTemplate, mappings = {}) {
313789
- const realStackName = stackName ?? this.stackName;
313790
- if (!this._diffs[realStackName]) {
313791
- const templateDiff = (0, import_cloudformation_diff2.fullDiff)(
313792
- oldTemplate ?? this.oldTemplate,
313793
- this.newTemplate.template,
313794
- this.changeSet,
313795
- this.isImport
313796
- );
313921
+ computeDiff(stackName, oldTemplate, newTemplate, changeSet, mappings) {
313922
+ if (!this.cache.has(stackName)) {
313923
+ const templateDiff = (0, import_cloudformation_diff2.fullDiff)(oldTemplate, newTemplate, changeSet, this.isImport);
313797
313924
  const setMove = /* @__PURE__ */ __name((change, direction, location) => {
313798
313925
  if (location != null) {
313799
313926
  const [sourceStackName, sourceLogicalId] = location.split(".");
@@ -313805,46 +313932,34 @@ var init_diff_formatter = __esm({
313805
313932
  }
313806
313933
  }, "setMove");
313807
313934
  templateDiff.resources.forEachDifference((id, change) => {
313808
- const location = `${realStackName}.${id}`;
313935
+ const location = `${stackName}.${id}`;
313809
313936
  if (change.isAddition && Object.values(mappings).includes(location)) {
313810
313937
  setMove(change, "from", Object.keys(mappings).find((k6) => mappings[k6] === location));
313811
313938
  } else if (change.isRemoval && Object.keys(mappings).includes(location)) {
313812
313939
  setMove(change, "to", mappings[location]);
313813
313940
  }
313814
313941
  });
313815
- this._diffs[realStackName] = templateDiff;
313816
- }
313817
- return this._diffs[realStackName];
313818
- }
313819
- /**
313820
- * Return whether the diff has security-impacting changes that need confirmation.
313821
- *
313822
- * If no stackName is given, then the root stack name is used.
313823
- */
313824
- permissionType() {
313825
- const diff = this.diff();
313826
- if (diff.permissionsBroadened) {
313827
- return "broadening" /* BROADENING */;
313828
- } else if (diff.permissionsAnyChanges) {
313829
- return "non-broadening" /* NON_BROADENING */;
313830
- } else {
313831
- return "none" /* NONE */;
313942
+ this.cache.set(stackName, templateDiff);
313832
313943
  }
313944
+ return this.cache.get(stackName);
313833
313945
  }
313834
313946
  /**
313835
- * Format the stack diff
313947
+ * Format the stack diff, including all nested stacks.
313836
313948
  */
313837
313949
  formatStackDiff(options = {}) {
313838
- return this.formatStackDiffHelper(
313839
- this.oldTemplate,
313840
- this.stackName,
313841
- this.nestedStacks,
313842
- options,
313843
- this.mappings
313844
- );
313845
- }
313846
- formatStackDiffHelper(oldTemplate, stackName, nestedStackTemplates, options, mappings = {}) {
313847
- let diff = this.diff(stackName, oldTemplate, mappings);
313950
+ return this.formatStackDiffHelper({
313951
+ oldTemplate: this.templateInfo.oldTemplate,
313952
+ newTemplate: this.templateInfo.newTemplate.template,
313953
+ stackName: this.stackName,
313954
+ nestedStacks: this.templateInfo.nestedStacks,
313955
+ changeSet: this.templateInfo.changeSet,
313956
+ mappings: this.mappings,
313957
+ logicalIdMap: buildLogicalToPathMap(this.templateInfo.newTemplate)
313958
+ }, options);
313959
+ }
313960
+ formatStackDiffHelper(params, options = {}) {
313961
+ const { oldTemplate, newTemplate, stackName, nestedStacks, changeSet, mappings, logicalIdMap } = params;
313962
+ const diff = this.computeDiff(stackName, oldTemplate, newTemplate, changeSet, mappings);
313848
313963
  const stream = new StringWriteStream();
313849
313964
  let numStacksWithChanges = 0;
313850
313965
  let formattedDiff = "";
@@ -313857,22 +313972,24 @@ var init_diff_formatter = __esm({
313857
313972
  if (!options.quiet && this.isImport) {
313858
313973
  stream.write("Parameters and rules created during migration do not affect resource configuration.\n");
313859
313974
  }
313975
+ let activeDiff = diff;
313860
313976
  if (diff.differenceCount && !options.strict) {
313861
- const mangledNewTemplate = JSON.parse((0, import_cloudformation_diff2.mangleLikeCloudFormation)(JSON.stringify(this.newTemplate.template)));
313862
- const mangledDiff = (0, import_cloudformation_diff2.fullDiff)(oldTemplate, mangledNewTemplate, this.changeSet);
313977
+ const mangledNewTemplate = JSON.parse((0, import_cloudformation_diff2.mangleLikeCloudFormation)(JSON.stringify(newTemplate)));
313978
+ const mangledDiff = (0, import_cloudformation_diff2.fullDiff)(oldTemplate, mangledNewTemplate, changeSet);
313863
313979
  filteredChangesCount = Math.max(0, diff.differenceCount - mangledDiff.differenceCount);
313864
313980
  if (filteredChangesCount > 0) {
313865
- diff = mangledDiff;
313981
+ activeDiff = mangledDiff;
313866
313982
  }
313867
313983
  }
313868
313984
  if (!options.strict) {
313869
- obscureDiff(diff);
313985
+ obscureDiff(activeDiff);
313870
313986
  }
313871
- if (!diff.isEmpty) {
313987
+ if (!activeDiff.isEmpty) {
313872
313988
  numStacksWithChanges++;
313873
- (0, import_cloudformation_diff2.formatDifferences)(stream, diff, {
313874
- ...logicalIdMapFromTemplate(this.oldTemplate),
313875
- ...buildLogicalToPathMap(this.newTemplate)
313989
+ (0, import_cloudformation_diff2.formatDifferences)(stream, activeDiff, {
313990
+ ...logicalIdMapFromTemplate(oldTemplate),
313991
+ ...logicalIdMapFromTemplate(newTemplate),
313992
+ ...logicalIdMap
313876
313993
  }, options.contextLines);
313877
313994
  } else if (!options.quiet) {
313878
313995
  stream.write(chalk19.green("There were no differences\n"));
@@ -313885,44 +314002,78 @@ var init_diff_formatter = __esm({
313885
314002
  formattedDiff = stream.toString();
313886
314003
  stream.end();
313887
314004
  }
313888
- for (const nestedStackLogicalId of Object.keys(nestedStackTemplates ?? {})) {
313889
- if (!nestedStackTemplates) {
313890
- break;
313891
- }
313892
- const nestedStack = nestedStackTemplates[nestedStackLogicalId];
313893
- this.newTemplate._template = nestedStack.generatedTemplate;
313894
- const nextDiff = this.formatStackDiffHelper(
313895
- nestedStack.deployedTemplate,
313896
- nestedStack.physicalName ?? nestedStackLogicalId,
313897
- nestedStack.nestedStackTemplates,
313898
- options,
313899
- this.mappings
313900
- );
314005
+ for (const [logicalId, nestedStack] of Object.entries(nestedStacks ?? {})) {
314006
+ const nextDiff = this.formatStackDiffHelper({
314007
+ oldTemplate: nestedStack.deployedTemplate,
314008
+ newTemplate: nestedStack.generatedTemplate,
314009
+ stackName: nestedStack.physicalName ?? logicalId,
314010
+ nestedStacks: nestedStack.nestedStackTemplates,
314011
+ changeSet: nestedStack.changeSet,
314012
+ mappings,
314013
+ logicalIdMap: {}
314014
+ }, options);
313901
314015
  numStacksWithChanges += nextDiff.numStacksWithChanges;
313902
314016
  formattedDiff += nextDiff.formattedDiff;
313903
314017
  }
313904
- return {
313905
- numStacksWithChanges,
313906
- formattedDiff
313907
- };
314018
+ return { numStacksWithChanges, formattedDiff };
313908
314019
  }
313909
314020
  /**
313910
- * Format the security diff
314021
+ * Format the security diff, including all nested stacks.
313911
314022
  */
313912
- formatSecurityDiff() {
313913
- const diff = this.diff();
314023
+ formatSecurityDiff(options = {}) {
314024
+ const { formattedDiff, permissionChangeType, numStacksWithChanges } = this.formatSecurityDiffHelper({
314025
+ oldTemplate: this.templateInfo.oldTemplate,
314026
+ newTemplate: this.templateInfo.newTemplate.template,
314027
+ stackName: this.stackName,
314028
+ nestedStacks: this.templateInfo.nestedStacks,
314029
+ changeSet: this.templateInfo.changeSet,
314030
+ logicalIdMap: buildLogicalToPathMap(this.templateInfo.newTemplate)
314031
+ }, options);
314032
+ return { formattedDiff, permissionChangeType, numStacksWithChanges };
314033
+ }
314034
+ formatSecurityDiffHelper(params, options = {}) {
314035
+ const { oldTemplate, newTemplate, stackName, nestedStacks, changeSet, logicalIdMap } = params;
314036
+ const diff = this.computeDiff(stackName, oldTemplate, newTemplate, changeSet, this.mappings);
314037
+ const permissionChangeType = permissionTypeFromDiff(diff);
313914
314038
  const stream = new StringWriteStream();
313915
- stream.write((0, import_node_util3.format)(`Stack ${chalk19.bold(this.stackName)}
314039
+ if (!options.quiet || permissionChangeType !== "none" /* NONE */) {
314040
+ stream.write((0, import_node_util3.format)(`Stack ${chalk19.bold(stackName)}
313916
314041
  `));
314042
+ }
313917
314043
  try {
313918
- (0, import_cloudformation_diff2.formatSecurityChanges)(stream, diff, buildLogicalToPathMap(this.newTemplate));
314044
+ (0, import_cloudformation_diff2.formatSecurityChanges)(stream, diff, {
314045
+ ...logicalIdMapFromTemplate(newTemplate),
314046
+ ...logicalIdMap
314047
+ });
313919
314048
  } finally {
313920
314049
  stream.end();
313921
314050
  }
313922
- const formattedDiff = stream.toString();
313923
- return { formattedDiff, permissionChangeType: this.permissionType() };
314051
+ let formattedDiff = stream.toString();
314052
+ if (!options.quiet && permissionChangeType === "none" /* NONE */) {
314053
+ formattedDiff += chalk19.green("There were no security-related changes (limitations: https://github.com/aws/aws-cdk/issues/1299)\n");
314054
+ }
314055
+ let numStacksWithChanges = permissionChangeType !== "none" /* NONE */ ? 1 : 0;
314056
+ let escalatedPermissionType = permissionChangeType;
314057
+ for (const [logicalId, nestedStack] of Object.entries(nestedStacks ?? {})) {
314058
+ const nestedResult = this.formatSecurityDiffHelper({
314059
+ oldTemplate: nestedStack.deployedTemplate,
314060
+ newTemplate: nestedStack.generatedTemplate,
314061
+ stackName: nestedStack.physicalName ?? logicalId,
314062
+ nestedStacks: nestedStack.nestedStackTemplates,
314063
+ changeSet: nestedStack.changeSet
314064
+ }, options);
314065
+ formattedDiff += nestedResult.formattedDiff ? "\n" + nestedResult.formattedDiff : "";
314066
+ numStacksWithChanges += nestedResult.numStacksWithChanges;
314067
+ if (nestedResult.permissionChangeType === "broadening" /* BROADENING */) {
314068
+ escalatedPermissionType = "broadening" /* BROADENING */;
314069
+ } else if (nestedResult.permissionChangeType === "non-broadening" /* NON_BROADENING */ && escalatedPermissionType === "none" /* NONE */) {
314070
+ escalatedPermissionType = "non-broadening" /* NON_BROADENING */;
314071
+ }
314072
+ }
314073
+ return { formattedDiff, permissionChangeType: escalatedPermissionType, numStacksWithChanges };
313924
314074
  }
313925
314075
  };
314076
+ __name(permissionTypeFromDiff, "permissionTypeFromDiff");
313926
314077
  __name(buildLogicalToPathMap, "buildLogicalToPathMap");
313927
314078
  __name(logicalIdMapFromTemplate, "logicalIdMapFromTemplate");
313928
314079
  __name(obscureDiff, "obscureDiff");
@@ -315506,6 +315657,7 @@ var init_toolkit = __esm({
315506
315657
  const strict = !!options.strict;
315507
315658
  const contextLines = options.contextLines || 3;
315508
315659
  let diffs = 0;
315660
+ let securityDiffs = 0;
315509
315661
  const templateInfos = await prepareDiff(diffSpan.asHelper, stacks, deployments, await this.sdkProvider("diff"), options);
315510
315662
  const templateDiffs = {};
315511
315663
  for (const templateInfo of templateInfos) {
@@ -315519,11 +315671,13 @@ var init_toolkit = __esm({
315519
315671
  await diffSpan.defaults.info(securityDiff.formattedDiff);
315520
315672
  }
315521
315673
  diffs += stackDiff.numStacksWithChanges;
315674
+ securityDiffs += securityDiff.numStacksWithChanges;
315522
315675
  appendObject(templateDiffs, formatter.diffs);
315523
315676
  await diffSpan.notify(IO.CDK_TOOLKIT_I4002.msg(stackDiff.formattedDiff, {
315524
315677
  stack: templateInfo.newTemplate,
315525
315678
  diffs: formatter.diffs,
315526
315679
  numStacksWithChanges: stackDiff.numStacksWithChanges,
315680
+ numStacksWithSecurityChanges: securityDiff.numStacksWithChanges,
315527
315681
  permissionChanges: securityDiff.permissionChangeType,
315528
315682
  formattedDiff: {
315529
315683
  diff: stackDiff.formattedDiff,
@@ -315533,6 +315687,7 @@ var init_toolkit = __esm({
315533
315687
  }
315534
315688
  await diffSpan.end(`\u2728 Number of stacks with differences: ${diffs}`, {
315535
315689
  numStacksWithChanges: diffs,
315690
+ numStacksWithSecurityChanges: securityDiffs,
315536
315691
  diffs: templateDiffs
315537
315692
  });
315538
315693
  return templateDiffs;
@@ -315613,6 +315768,72 @@ var init_toolkit = __esm({
315613
315768
  _promise && await _promise;
315614
315769
  }
315615
315770
  }
315771
+ /**
315772
+ * Publish Assets Action
315773
+ *
315774
+ * Publishes assets for the selected stacks without deploying
315775
+ */
315776
+ async publishAssets(cx, options = {}) {
315777
+ var _stack = [];
315778
+ try {
315779
+ this.requireUnstableFeature("publish-assets");
315780
+ const ioHelper = asIoHelper(this.ioHost, "publish-assets");
315781
+ const selectStacks = stacksOpt(options);
315782
+ const assembly = __using(_stack, await synthAndMeasure(ioHelper, cx, selectStacks), true);
315783
+ const stackCollection = await assembly.selectStacksV2(selectStacks);
315784
+ await this.validateStacksMetadata(stackCollection, ioHelper);
315785
+ if (stackCollection.stackCount === 0) {
315786
+ await ioHelper.notify(IO.CDK_TOOLKIT_E5001.msg("No stacks selected"));
315787
+ return {
315788
+ publishedAssets: []
315789
+ };
315790
+ }
315791
+ const deployments = await this.deploymentsForAction("publish-assets");
315792
+ const stacks = stackCollection.stackArtifacts;
315793
+ const stacksAndTheirAssetManifests = stacks.flatMap((stack) => [
315794
+ stack,
315795
+ ...stack.dependencies.filter((x6) => cxapi8.AssetManifestArtifact.isAssetManifestArtifact(x6))
315796
+ ]);
315797
+ const workGraph = new WorkGraphBuilder(
315798
+ ioHelper,
315799
+ true
315800
+ // prebuild all assets
315801
+ ).build(stacksAndTheirAssetManifests);
315802
+ if (!options.force) {
315803
+ await removePublishedAssetsFromWorkGraph(workGraph, deployments, options);
315804
+ }
315805
+ const assetNodes = Object.values(workGraph.nodes).filter((n6) => n6.type === "asset-publish");
315806
+ if (assetNodes.length === 0) {
315807
+ await ioHelper.notify(IO.CDK_TOOLKIT_I9400.msg(chalk23.green("\n\u2728 All assets are already published\n")));
315808
+ return {
315809
+ publishedAssets: []
315810
+ };
315811
+ }
315812
+ const assets = assetNodes.map((n6) => n6.asset);
315813
+ await ioHelper.notify(IO.CDK_TOOLKIT_I9401.msg("Publishing assets", { assets }));
315814
+ const concurrency = options.concurrency ?? 4;
315815
+ const graphConcurrency = {
315816
+ "stack": 1,
315817
+ "asset-build": concurrency,
315818
+ "asset-publish": concurrency
315819
+ };
315820
+ await workGraph.doParallel(graphConcurrency, {
315821
+ deployStack: /* @__PURE__ */ __name(async () => {
315822
+ }, "deployStack"),
315823
+ buildAsset: this.createBuildAssetFunction(ioHelper, deployments, void 0),
315824
+ publishAsset: this.createPublishAssetFunction(ioHelper, deployments, void 0, options.force)
315825
+ });
315826
+ await ioHelper.notify(IO.CDK_TOOLKIT_I9402.msg(chalk23.green("\n\u2728 Assets published successfully\n"), { assets }));
315827
+ return {
315828
+ publishedAssets: assets
315829
+ };
315830
+ } catch (_2) {
315831
+ var _error = _2, _hasError = true;
315832
+ } finally {
315833
+ var _promise = __callDispose(_stack, _error, _hasError);
315834
+ _promise && await _promise;
315835
+ }
315836
+ }
315616
315837
  /**
315617
315838
  * List Action
315618
315839
  *
@@ -315682,34 +315903,6 @@ var init_toolkit = __esm({
315682
315903
  const stacks = stackCollection.stackArtifacts;
315683
315904
  const stackOutputs = {};
315684
315905
  const outputsFile = options.outputsFile;
315685
- const buildAsset = /* @__PURE__ */ __name(async (assetNode) => {
315686
- const buildAssetSpan = await ioHelper.span(SPAN.BUILD_ASSET).begin({
315687
- asset: assetNode.asset
315688
- });
315689
- await deployments.buildSingleAsset(
315690
- assetNode.assetManifestArtifact,
315691
- assetNode.assetManifest,
315692
- assetNode.asset,
315693
- {
315694
- stack: assetNode.parentStack,
315695
- roleArn: options.roleArn,
315696
- stackName: assetNode.parentStack.stackName
315697
- }
315698
- );
315699
- await buildAssetSpan.end();
315700
- }, "buildAsset");
315701
- const publishAsset = /* @__PURE__ */ __name(async (assetNode) => {
315702
- const publishAssetSpan = await ioHelper.span(SPAN.PUBLISH_ASSET).begin({
315703
- asset: assetNode.asset
315704
- });
315705
- await deployments.publishSingleAsset(assetNode.assetManifest, assetNode.asset, {
315706
- stack: assetNode.parentStack,
315707
- roleArn: options.roleArn,
315708
- stackName: assetNode.parentStack.stackName,
315709
- forcePublish: options.forceAssetPublishing
315710
- });
315711
- await publishAssetSpan.end();
315712
- }, "publishAsset");
315713
315906
  const deployStack2 = /* @__PURE__ */ __name(async (stackNode) => {
315714
315907
  const stack = stackNode.stack;
315715
315908
  if (stackCollection.stackCount !== 1) {
@@ -315915,8 +316108,8 @@ ${deployResult.stackArn}`));
315915
316108
  };
315916
316109
  await workGraph.doParallel(graphConcurrency, {
315917
316110
  deployStack: deployStack2,
315918
- buildAsset,
315919
- publishAsset
316111
+ buildAsset: this.createBuildAssetFunction(ioHelper, deployments, options.roleArn),
316112
+ publishAsset: this.createPublishAssetFunction(ioHelper, deployments, options.roleArn, options.forceAssetPublishing)
315920
316113
  });
315921
316114
  return ret;
315922
316115
  }
@@ -316397,6 +316590,44 @@ ${deployResult.stackArn}`));
316397
316590
  throw new ToolkitError("UnstableFeatureNotEnabled", `Unstable feature '${requestedFeature}' is not enabled. Please enable it under 'unstableFeatures'`);
316398
316591
  }
316399
316592
  }
316593
+ /**
316594
+ * Create a buildAsset function for use in WorkGraph
316595
+ */
316596
+ createBuildAssetFunction(ioHelper, deployments, roleArn) {
316597
+ return async (assetNode) => {
316598
+ const buildAssetSpan = await ioHelper.span(SPAN.BUILD_ASSET).begin({
316599
+ asset: assetNode.asset
316600
+ });
316601
+ await deployments.buildSingleAsset(
316602
+ assetNode.assetManifestArtifact,
316603
+ assetNode.assetManifest,
316604
+ assetNode.asset,
316605
+ {
316606
+ stack: assetNode.parentStack,
316607
+ roleArn,
316608
+ stackName: assetNode.parentStack.stackName
316609
+ }
316610
+ );
316611
+ await buildAssetSpan.end();
316612
+ };
316613
+ }
316614
+ /**
316615
+ * Create a publishAsset function for use in WorkGraph
316616
+ */
316617
+ createPublishAssetFunction(ioHelper, deployments, roleArn, forcePublish) {
316618
+ return async (assetNode) => {
316619
+ const publishAssetSpan = await ioHelper.span(SPAN.PUBLISH_ASSET).begin({
316620
+ asset: assetNode.asset
316621
+ });
316622
+ await deployments.publishSingleAsset(assetNode.assetManifest, assetNode.asset, {
316623
+ stack: assetNode.parentStack,
316624
+ roleArn,
316625
+ stackName: assetNode.parentStack.stackName,
316626
+ forcePublish
316627
+ });
316628
+ await publishAssetSpan.end();
316629
+ };
316630
+ }
316400
316631
  };
316401
316632
  __name(stacksOpt, "stacksOpt");
316402
316633
  __name(synthAndMeasure, "synthAndMeasure");
@@ -316447,6 +316678,13 @@ var init_list2 = __esm({
316447
316678
  }
316448
316679
  });
316449
316680
 
316681
+ // ../toolkit-lib/lib/actions/publish-assets/index.ts
316682
+ var init_publish_assets2 = __esm({
316683
+ "../toolkit-lib/lib/actions/publish-assets/index.ts"() {
316684
+ "use strict";
316685
+ }
316686
+ });
316687
+
316450
316688
  // ../toolkit-lib/lib/actions/refactor/index.ts
316451
316689
  var init_refactor2 = __esm({
316452
316690
  "../toolkit-lib/lib/actions/refactor/index.ts"() {
@@ -316495,6 +316733,7 @@ var init_actions = __esm({
316495
316733
  init_diff();
316496
316734
  init_drift4();
316497
316735
  init_list2();
316736
+ init_publish_assets2();
316498
316737
  init_refactor2();
316499
316738
  init_rollback2();
316500
316739
  init_synth2();
package/package.json CHANGED
@@ -66,12 +66,12 @@
66
66
  "@aws-cdk/aws-service-spec": "^0.1.167",
67
67
  "@aws-cdk/cdk-assets-lib": "1.4.2",
68
68
  "@aws-cdk/cloud-assembly-api": "2.2.1",
69
- "@aws-cdk/cloud-assembly-schema": ">=53.11.0",
70
- "@aws-cdk/cloudformation-diff": "2.186.0",
69
+ "@aws-cdk/cloud-assembly-schema": ">=53.12.0",
70
+ "@aws-cdk/cloudformation-diff": "2.187.0",
71
71
  "@aws-cdk/cx-api": "^2",
72
- "@aws-cdk/toolkit-lib": "1.20.1",
72
+ "@aws-cdk/toolkit-lib": "1.21.0",
73
73
  "@aws-sdk/client-cloudformation": "^3",
74
- "aws-cdk": "2.1115.1",
74
+ "aws-cdk": "2.1116.0",
75
75
  "chalk": "^4",
76
76
  "chokidar": "^4",
77
77
  "fs-extra": "^9",
@@ -80,7 +80,7 @@
80
80
  },
81
81
  "dependencies": {
82
82
  "@aws-cdk/aws-service-spec": "0.1.167",
83
- "aws-cdk": "2.1115.1"
83
+ "aws-cdk": "2.1116.0"
84
84
  },
85
85
  "keywords": [
86
86
  "aws",
@@ -95,7 +95,7 @@
95
95
  "publishConfig": {
96
96
  "access": "public"
97
97
  },
98
- "version": "2.197.10",
98
+ "version": "2.197.11",
99
99
  "types": "lib/index.d.ts",
100
100
  "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"npx projen\"."
101
101
  }