async function canSkipDeploy()

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;
}