@@ -17,17 +17,15 @@ import { EvaluateCloudFormationTemplate } from '../evaluate-cloudformation-templ
1717import { isHotswappableAppSyncChange } from '../hotswap/appsync-mapping-templates' ;
1818import { isHotswappableCodeBuildProjectChange } from '../hotswap/code-build-projects' ;
1919import type {
20- ChangeHotswapResult ,
20+ HotswapChange ,
2121 HotswapOperation ,
22- NonHotswappableChange ,
22+ RejectedChange ,
2323 HotswapPropertyOverrides ,
24- ClassifiedResourceChanges ,
2524 HotswapResult ,
2625} from '../hotswap/common' ;
2726import {
2827 ICON ,
29- reportNonHotswappableChange ,
30- reportNonHotswappableResource ,
28+ nonHotswappableResource ,
3129} from '../hotswap/common' ;
3230import { isHotswappableEcsServiceChange } from '../hotswap/ecs-services' ;
3331import { isHotswappableLambdaFunctionChange } from '../hotswap/lambda-functions' ;
@@ -48,7 +46,7 @@ type HotswapDetector = (
4846 change : ResourceChange ,
4947 evaluateCfnTemplate : EvaluateCloudFormationTemplate ,
5048 hotswapPropertyOverrides : HotswapPropertyOverrides ,
51- ) => Promise < ChangeHotswapResult > ;
49+ ) => Promise < HotswapChange [ ] > ;
5250
5351type HotswapMode = 'hotswap-only' | 'fall-back' ;
5452
@@ -72,17 +70,13 @@ const RESOURCE_DETECTORS: { [key: string]: HotswapDetector } = {
7270 logicalId : string ,
7371 change : ResourceChange ,
7472 evaluateCfnTemplate : EvaluateCloudFormationTemplate ,
75- ) : Promise < ChangeHotswapResult > => {
73+ ) : Promise < HotswapChange [ ] > => {
7674 // If the policy is for a S3BucketDeploymentChange, we can ignore the change
7775 if ( await skipChangeForS3DeployCustomResourcePolicy ( logicalId , change , evaluateCfnTemplate ) ) {
7876 return [ ] ;
7977 }
8078
81- return reportNonHotswappableResource (
82- change ,
83- NonHotswappableReason . RESOURCE_UNSUPPORTED ,
84- 'This resource type is not supported for hotswap deployments' ,
85- ) ;
79+ return [ nonHotswappableResource ( change ) ] ;
8680 } ,
8781
8882 'AWS::CDK::Metadata' : async ( ) => [ ] ,
@@ -162,7 +156,7 @@ async function hotswapDeployment(
162156 } ) ;
163157
164158 const stackChanges = cfn_diff . fullDiff ( currentTemplate . deployedRootTemplate , stack . template ) ;
165- const { hotswapOperations, nonHotswappableChanges } = await classifyResourceChanges (
159+ const { hotswappable : hotswapOperations , nonHotswappable : nonHotswappableChanges } = await classifyResourceChanges (
166160 stackChanges ,
167161 evaluateCfnTemplate ,
168162 sdk ,
@@ -196,6 +190,11 @@ async function hotswapDeployment(
196190 } ;
197191}
198192
193+ interface ClassifiedChanges {
194+ hotswappable : HotswapOperation [ ] ;
195+ nonHotswappable : RejectedChange [ ] ;
196+ }
197+
199198/**
200199 * Classifies all changes to all resources as either hotswappable or not.
201200 * Metadata changes are excluded from the list of (non)hotswappable resources.
@@ -206,19 +205,18 @@ async function classifyResourceChanges(
206205 sdk : SDK ,
207206 nestedStackNames : { [ nestedStackName : string ] : NestedStackTemplates } ,
208207 hotswapPropertyOverrides : HotswapPropertyOverrides ,
209- ) : Promise < ClassifiedResourceChanges > {
208+ ) : Promise < ClassifiedChanges > {
210209 const resourceDifferences = getStackResourceDifferences ( stackChanges ) ;
211210
212- const promises : Array < ( ) => Promise < ChangeHotswapResult > > = [ ] ;
211+ const promises : Array < ( ) => Promise < HotswapChange [ ] > > = [ ] ;
213212 const hotswappableResources = new Array < HotswapOperation > ( ) ;
214- const nonHotswappableResources = new Array < NonHotswappableChange > ( ) ;
213+ const nonHotswappableResources = new Array < RejectedChange > ( ) ;
215214 for ( const logicalId of Object . keys ( stackChanges . outputs . changes ) ) {
216215 nonHotswappableResources . push ( {
217216 hotswappable : false ,
218217 reason : NonHotswappableReason . OUTPUT ,
219218 description : 'output was changed' ,
220219 logicalId,
221- rejectedChanges : [ ] ,
222220 resourceType : 'Stack Output' ,
223221 } ) ;
224222 }
@@ -233,8 +231,8 @@ async function classifyResourceChanges(
233231 sdk ,
234232 hotswapPropertyOverrides ,
235233 ) ;
236- hotswappableResources . push ( ...nestedHotswappableResources . hotswapOperations ) ;
237- nonHotswappableResources . push ( ...nestedHotswappableResources . nonHotswappableChanges ) ;
234+ hotswappableResources . push ( ...nestedHotswappableResources . hotswappable ) ;
235+ nonHotswappableResources . push ( ...nestedHotswappableResources . nonHotswappable ) ;
238236
239237 continue ;
240238 }
@@ -256,18 +254,12 @@ async function classifyResourceChanges(
256254 RESOURCE_DETECTORS [ resourceType ] ( logicalId , hotswappableChangeCandidate , evaluateCfnTemplate , hotswapPropertyOverrides ) ,
257255 ) ;
258256 } else {
259- reportNonHotswappableChange (
260- nonHotswappableResources ,
261- hotswappableChangeCandidate ,
262- NonHotswappableReason . RESOURCE_UNSUPPORTED ,
263- undefined ,
264- 'This resource type is not supported for hotswap deployments' ,
265- ) ;
257+ nonHotswappableResources . push ( nonHotswappableResource ( hotswappableChangeCandidate ) ) ;
266258 }
267259 }
268260
269261 // resolve all detector results
270- const changesDetectionResults : Array < ChangeHotswapResult > = [ ] ;
262+ const changesDetectionResults : Array < HotswapChange [ ] > = [ ] ;
271263 for ( const detectorResultPromises of promises ) {
272264 // Constant set of promises per resource
273265 // eslint-disable-next-line @cdklabs/promiseall-no-unbounded-parallelism
@@ -284,8 +276,8 @@ async function classifyResourceChanges(
284276 }
285277
286278 return {
287- hotswapOperations : hotswappableResources ,
288- nonHotswappableChanges : nonHotswappableResources ,
279+ hotswappable : hotswappableResources ,
280+ nonHotswappable : nonHotswappableResources ,
289281 } ;
290282}
291283
@@ -348,18 +340,17 @@ async function findNestedHotswappableChanges(
348340 evaluateCfnTemplate : EvaluateCloudFormationTemplate ,
349341 sdk : SDK ,
350342 hotswapPropertyOverrides : HotswapPropertyOverrides ,
351- ) : Promise < ClassifiedResourceChanges > {
343+ ) : Promise < ClassifiedChanges > {
352344 const nestedStack = nestedStackTemplates [ logicalId ] ;
353345 if ( ! nestedStack . physicalName ) {
354346 return {
355- hotswapOperations : [ ] ,
356- nonHotswappableChanges : [
347+ hotswappable : [ ] ,
348+ nonHotswappable : [
357349 {
358350 hotswappable : false ,
359351 logicalId,
360352 reason : NonHotswappableReason . NESTED_STACK_CREATION ,
361353 description : `physical name for AWS::CloudFormation::Stack '${ logicalId } ' could not be found in CloudFormation, so this is a newly created nested stack and cannot be hotswapped` ,
362- rejectedChanges : [ ] ,
363354 resourceType : 'AWS::CloudFormation::Stack' ,
364355 } ,
365356 ] ,
@@ -425,14 +416,13 @@ function makeRenameDifference(
425416function isCandidateForHotswapping (
426417 change : cfn_diff . ResourceDifference ,
427418 logicalId : string ,
428- ) : HotswapOperation | NonHotswappableChange | ResourceChange {
419+ ) : RejectedChange | ResourceChange {
429420 // a resource has been removed OR a resource has been added; we can't short-circuit that change
430421 if ( ! change . oldValue ) {
431422 return {
432423 hotswappable : false ,
433424 resourceType : change . newValue ! . Type ,
434425 logicalId,
435- rejectedChanges : [ ] ,
436426 reason : NonHotswappableReason . RESOURCE_CREATION ,
437427 description : `resource '${ logicalId } ' was created by this deployment` ,
438428 } ;
@@ -441,7 +431,6 @@ function isCandidateForHotswapping(
441431 hotswappable : false ,
442432 resourceType : change . oldValue ! . Type ,
443433 logicalId,
444- rejectedChanges : [ ] ,
445434 reason : NonHotswappableReason . RESOURCE_DELETION ,
446435 description : `resource '${ logicalId } ' was destroyed by this deployment` ,
447436 } ;
@@ -453,7 +442,6 @@ function isCandidateForHotswapping(
453442 hotswappable : false ,
454443 resourceType : change . newValue ?. Type ,
455444 logicalId,
456- rejectedChanges : [ ] ,
457445 reason : NonHotswappableReason . RESOURCE_TYPE_CHANGED ,
458446 description : `resource '${ logicalId } ' had its type changed from '${ change . oldValue ?. Type } ' to '${ change . newValue ?. Type } '` ,
459447 } ;
@@ -530,7 +518,7 @@ function formatWaiterErrorResult(result: WaiterResult) {
530518
531519async function logNonHotswappableChanges (
532520 ioSpan : IMessageSpan < any > ,
533- nonHotswappableChanges : NonHotswappableChange [ ] ,
521+ nonHotswappableChanges : RejectedChange [ ] ,
534522 hotswapMode : HotswapMode ,
535523) : Promise < void > {
536524 if ( nonHotswappableChanges . length === 0 ) {
@@ -560,12 +548,12 @@ async function logNonHotswappableChanges(
560548 }
561549
562550 for ( const change of nonHotswappableChanges ) {
563- if ( change . rejectedChanges . length > 0 ) {
551+ if ( change . rejectedProperties ? .length ) {
564552 messages . push ( format (
565553 ' logicalID: %s, type: %s, rejected changes: %s, reason: %s' ,
566554 chalk . bold ( change . logicalId ) ,
567555 chalk . bold ( change . resourceType ) ,
568- chalk . bold ( change . rejectedChanges ) ,
556+ chalk . bold ( change . rejectedProperties ) ,
569557 chalk . red ( change . description ) ,
570558 ) ) ;
571559 } else {
0 commit comments