in packages/@aws-cdk/toolkit-lib/lib/api/deployments/deploy-stack.ts [718:790]
async function canSkipDeploy(
deployStackOptions: DeployStackOptions,
cloudFormationStack: CloudFormationStack,
parameterChanges: ParameterChanges,
ioHelper: IoHelper,
): Promise<boolean> {
const deployName = deployStackOptions.deployName || deployStackOptions.stack.stackName;
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: checking if we can skip deploy`));
// Forced deploy
if (deployStackOptions.forceDeployment) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: forced deployment`));
return false;
}
// Creating changeset only (default true), never skip
if (
deployStackOptions.deploymentMethod?.method === 'change-set' &&
deployStackOptions.deploymentMethod.execute === false
) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: --no-execute, always creating change set`));
return false;
}
// No existing stack
if (!cloudFormationStack.exists) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: no existing stack`));
return false;
}
// Template has changed (assets taken into account here)
if (JSON.stringify(deployStackOptions.stack.template) !== JSON.stringify(await cloudFormationStack.template())) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: template has changed`));
return false;
}
// Tags have changed
if (!compareTags(cloudFormationStack.tags, deployStackOptions.tags ?? [])) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: tags have changed`));
return false;
}
// Notification arns have changed
if (!arrayEquals(cloudFormationStack.notificationArns, deployStackOptions.notificationArns ?? [])) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: notification arns have changed`));
return false;
}
// Termination protection has been updated
if (!!deployStackOptions.stack.terminationProtection !== !!cloudFormationStack.terminationProtection) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: termination protection has been updated`));
return false;
}
// Parameters have changed
if (parameterChanges) {
if (parameterChanges === 'ssm') {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: some parameters come from SSM so we have to assume they may have changed`));
} else {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: parameters have changed`));
}
return false;
}
// Existing stack is in a failed state
if (cloudFormationStack.stackStatus.isFailure) {
await ioHelper.notify(IO.DEFAULT_TOOLKIT_DEBUG.msg(`${deployName}: stack is in a failure state`));
return false;
}
// We can skip deploy
return true;
}