Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(diff): make dedicated file and class for incorporating changeset to templateDiff #30332

Merged
merged 58 commits into from
May 28, 2024

Conversation

bergjaak
Copy link
Contributor

@bergjaak bergjaak commented May 24, 2024

Reason for this change

I am making this change as part of #30268, but implementing the bug fix in a satisfactory way is becoming much, much, much more difficult than I thought it would. As it's now possible to view the changed values before and after a changeset is applied by using the DescribeChangeSets api with IncludePropertyValues, but the API is difficult to use because of not being supported in all regions, not including StatusReason, and being unable to paginate. So, I want to make that fix in a separate PR, once this refactor change is done.

Description of changes

  • A ton of unit tests and moved changeset diff logic into a dedicated class and file.

Description of how you validated changes

  • Many unit tests, integration tests, and manual tests

Checklist


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

changeSetResources: types.ChangeSetResources;

constructor(
args: {
Copy link
Contributor

@colifran colifran May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: The convention we typically go for is constructor arguments being passed in via a defined interface. Going a little deeper, we try to consolidate all required property on a props interface and all optional properties on an options interface. Typically the props interface would extend the options interface. Something like:

interface TemplateAndChangeSetDiffMergerOptions {
  /*
   * Description of property
   *
   * @default - description of default
  */
  readonly changeSetResources?: types.ChangeSetResources;
}
export interface TemplateAndChangeSetDiffMergerProps extends TemplateAndChangeSetDiffMergerOptions {
  /*
   * Description of property
  */
  readonly changeSet: DescribeChangeSetOutput;
}

Then,

constructor(props: TemplateAndChangeSetDiffMergerProps) {}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great, thanks!

Comment on lines 36 to 37
changeSet: DescribeChangeSetOutput | undefined;
changeSetResources: types.ChangeSetResources;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we give these a public or private?

}
change.forEachDifference((type: 'Property' | 'Other', name: string, value: types.Difference<any> | types.PropertyDifference<any>) => {
if (type === 'Property') {
if (!this.changeSetResources[logicalId]) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this essentially just a new resource being added?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is us writing over the "ChangeImpact" that was computed from the template difference, and instead using the ChangeImpact that is included from the ChangeSet. Using the ChangeSet ChangeImpact is more accurate. The ChangeImpact tells us what the consequence is of changing the field. If changing the field causes resource replacement (e.g., changing the name of an IAM role requires deleting and replacing the role), then ChangeImpact is "Always".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am going to include this as a comment in the code

// otherwise, defer to the changeImpact from the template diff
}
} else if (type === 'Other') {
switch (name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there any cases in here that wouldn't be Metadata, like an undefined or something?

(value as types.PropertyDifference<any>).changeImpact = types.ResourceImpact.NO_CHANGE;
(value as types.PropertyDifference<any>).isDifferent = false;
break;
// otherwise, defer to the changeImpact from the template diff
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What case would be an otherwise situation? Would it make sense to make undefined the default case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just want to refactor in this code change, so this is just a copy of what already exists being lifted into this new file. Not sure what would be an otherwise situation, though

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. It makes sense to leave it as is for now.


public findResourceImports(): string[] {
const importedResourceLogicalIds = [];
for (const resourceChange of this.changeSet?.Changes ?? []) {
Copy link
Contributor

@colifran colifran May 28, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would changeSet be undefined? It looks like it is a required property used to construct this class.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is just me being extra defensive... we could get rid of that, but I'd rather just be overly cautious?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think its needed though since you can't construct the class without a changeSet provided. Because of that we know changeSet can never be undefined.

const importedResourceLogicalIds = [];
for (const resourceChange of this.changeSet?.Changes ?? []) {
if (resourceChange.ResourceChange?.Action === 'Import') {
importedResourceLogicalIds.push(resourceChange.ResourceChange.LogicalResourceId!);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any chance we can avoid using !? Maybe just a check and throw an error if the resource ID is undefined? This way I think the compiler will know it wouldn't be undefined. Something like this:

const logicalResourceId = resourceChange.ResourceChange.LogicalResourceId;
if (logicalResourceId === undefined) {
  throw new Error('...');
}
importedResourceLogicalIds.push(logicalResourceId);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch! I didn't change this from the refactor. I would like to change by making the function signature (string | undefined)[]

Copy link
Contributor

@colifran colifran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love the refactor! This looks great so far. I just have a few minor stylistic suggestions and questions.

@aws-cdk-automation aws-cdk-automation removed the pr/needs-maintainer-review This PR needs a review from a Core Team Member label May 28, 2024
Copy link
Contributor

@colifran colifran left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

Copy link
Contributor

mergify bot commented May 28, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

@mergify mergify bot temporarily deployed to test-pipeline May 28, 2024 19:26 Inactive
@aws-cdk-automation
Copy link
Collaborator

➡️ PR build request submitted to test-main-pipeline ⬅️

A maintainer must now check the pipeline and add the pr-linter/cli-integ-tested label once the pipeline succeeds.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: fb267b3
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@mergify mergify bot merged commit 526d4ad into main May 28, 2024
12 checks passed
@mergify mergify bot deleted the bergjaak/ResourceDiffRefactor branch May 28, 2024 19:53
Copy link
Contributor

mergify bot commented May 28, 2024

Thank you for contributing! Your pull request will be updated from main and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork).

atanaspam pushed a commit to atanaspam/aws-cdk that referenced this pull request Jun 3, 2024
…eset to templateDiff (aws#30332)

### Reason for this change

I am making this change as part of aws#30268, but implementing the bug fix in a satisfactory way is becoming much, much, much more difficult than I thought it would. As it's now possible to view the changed values before and after a changeset is applied by using the DescribeChangeSets api with IncludePropertyValues, but the API is difficult to use because of not being supported in all regions, not including StatusReason, and being unable to paginate. So, I want to make that fix in a separate PR, once this refactor change is done.

### Description of changes

* A ton of unit tests and moved changeset diff logic into a dedicated class and file.

### Description of how you validated changes

* Many unit tests, integration tests, and manual tests

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
vdahlberg pushed a commit to vdahlberg/aws-cdk that referenced this pull request Jun 10, 2024
…eset to templateDiff (aws#30332)

### Reason for this change

I am making this change as part of aws#30268, but implementing the bug fix in a satisfactory way is becoming much, much, much more difficult than I thought it would. As it's now possible to view the changed values before and after a changeset is applied by using the DescribeChangeSets api with IncludePropertyValues, but the API is difficult to use because of not being supported in all regions, not including StatusReason, and being unable to paginate. So, I want to make that fix in a separate PR, once this refactor change is done.

### Description of changes

* A ton of unit tests and moved changeset diff logic into a dedicated class and file.

### Description of how you validated changes

* Many unit tests, integration tests, and manual tests

### Checklist
- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

----

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
@aws-cdk-automation
Copy link
Collaborator

Comments on closed issues and PRs are hard for our team to see. If you need help, please open a new issue that references this one.

@aws aws locked as resolved and limited conversation to collaborators Jul 25, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
contribution/core This is a PR that came from AWS. p2
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants