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

New Pipeline#addStage convenience method #647

Merged
merged 1 commit into from
Sep 17, 2018

Conversation

skinny85
Copy link
Contributor

Added to make creating Stage objects a little more concise.

See #265 for more discussion on this feature.


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

@skinny85 skinny85 requested a review from eladb August 30, 2018 21:53
@skinny85 skinny85 force-pushed the feature/pipeline-add-stage branch from c1e3ee1 to 0e44fc9 Compare August 31, 2018 16:51
@skinny85 skinny85 changed the base branch from adamruka/codebuild-add-to-pipeline to master August 31, 2018 16:51
@skinny85
Copy link
Contributor Author

Rebased and changed the PR base branch to master after merging #642.

* @returns the newly created Stage
*/
public addStage(name: string): Stage {
return new Stage(this.parent!, name, {
Copy link
Contributor

Choose a reason for hiding this comment

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

Always use this (instead of this.parent) - the reason is that the parent construct is a lexical scope and the construct IDs must be unique amongst it's siblings. Since you don't control the parent's children, this will fail:

class MyConstruct extends cdk.Construct {
  constructor(...) {
    supre(...);

   new s3.Bucket(this, 'Hello');

    const pl = new codepipeline.Pipeline(this, 'MyPipeline');
    pl.addStage('Hello'); // BOOM! Two children with the same name ("Hello").
    
  }
}

Also, since construct ID must be unique, it means no two stages can have the same name. I don't believe this is a constraints in CodePipeline, but it will be a constraint here. Are we okay with this? If not, maybe you want to add an optional props here that will allow specifying stageName (or displayName) explicitly in case users do want this behavior.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry, I'm not following your example.

This will also fail:

  constructor(...) {
    super(...);

    new s3.Bucket(this, 'Hello');

    const pl = new codepipeline.Pipeline(this, 'MyPipeline');
    const stage = new codepipeline.Stage(this, 'Hello', { pipeline: pl }); // BOOM! Two children with the same name ("Hello").
  }

Which is exactly what we want - pipeline.addStage('x') should be exactly equivalent to new Stage(this, 'x', { pipeline }).

Also, since construct ID must be unique, it means no two stages can have the same name. I don't believe this is a constraints in CodePipeline, but it will be a constraint here.

It is in fact a constraint in CodePipeline (and one that we explicitly validate in the CodePipeline L2).

Copy link
Contributor

Choose a reason for hiding this comment

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

As a CDK developer, I expected the code new Stage(this, 'Hello') to fail (since I defined two constructs under the same parent) but not addStage(Hello) (which hides the fact that a stage is a construct).

Not sure I understand why for some reason you insist on pinning the inner stage construct to the parent's parent?

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 don't agree.

We keep saying that this addStage method is just 'syntactic sugar', a convenience that is equivalent to creating the Stage explicitly.

So, if as a CDK developer, I go from this code, which works:

cost stage = pipeline.addStage('Hello');

to this, which we claim is equivalent:

const stage = new codepipeline.Stage(this, 'Hello', { pipeline });

In your example, I will get an exception. So, they are clearly not equivalent, and that is quite surprising, and (in my mind) misleading.

Not to mention that if the Stage itself has any Constructs under it, going between the two forms will change the logical IDs of those children, and thus will re-create them in the Stack, and show up in the diff.

I argue that this is not what we want.

Copy link
Contributor

Choose a reason for hiding this comment

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

Following up on our chat conversation: I don't believe it is currently priority to make addStage and new Stage seamlessly interchangeable, and I do think there's value in maintaining the lexical and contextual scope when instantiating the inner Stage construct. If we could enforce this pattern by the compiler (and maybe at some point we will), we would have done that.

Let's just decide that instantiation of constructs always looks like this:

new MyConstruct(this, '<id>', props)

Since <id> is scoped by this, using a different scope (i.e. this.parent) can cause conflicts with that other scope, that users can't fix.

@eladb
Copy link
Contributor

eladb commented Sep 13, 2018

What's up with this?

@skinny85
Copy link
Contributor Author

What's up with this?

I've responded to your comments above. In particular, I disagree with using this instead of this.parent.

@eladb
Copy link
Contributor

eladb commented Sep 16, 2018

Awaiting updates

@skinny85 skinny85 force-pushed the feature/pipeline-add-stage branch from 0e44fc9 to cb20617 Compare September 17, 2018 18:13
@skinny85
Copy link
Contributor Author

Awaiting updates

Changed to use this in the call to new Stage, and rebased.

Copy link
Contributor

@eladb eladb left a comment

Choose a reason for hiding this comment

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

Please add a unit test

@@ -16,6 +16,13 @@ const sourceStage = new Stage(this, 'Source', {
});
```

There's also a utility method on the `Pipeline` class that can be used for this purpose:
Copy link
Contributor

Choose a reason for hiding this comment

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

I terms of the README narrative, I would recommend starting with this as the recommended way to add a stage to the pipeline and then mention that it is also possible to instantiate Stage directly (I don't even think it's worth providing an example unless there's a clear use case to demonstrate, such as defining a reusable subclass of Stage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

Added to make creating Stage objects a little more concise.
@skinny85 skinny85 force-pushed the feature/pipeline-add-stage branch from cb20617 to ea7541f Compare September 17, 2018 21:51
@skinny85
Copy link
Contributor Author

Please add a unit test

Done.

@skinny85 skinny85 merged commit 25c9fa0 into aws:master Sep 17, 2018
@skinny85 skinny85 deleted the feature/pipeline-add-stage branch September 17, 2018 22:14
eladb pushed a commit that referenced this pull request Sep 20, 2018
__NOTICE__: This release includes a framework-wide [__breaking
change__](#712) which changes the type
of all the string resource attributes across the framework. Instead of using
strong-types that extend `cdk.Token` (such as `QueueArn`, `TopicName`, etc), we
now represent all these attributes as normal `string`s, and codify the tokens
into the string (using the feature introduced in [#168](#168)).

Furthermore, the `cdk.Arn` type has been removed. In order to format/parse ARNs,
use the static methods on `cdk.ArnUtils`.

See motivation and discussion in [#695](#695).

* **cfn2ts:** use stringified tokens for resource attributes instead of strong types ([#712](#712)) ([6508f78](6508f78)), closes [#518](#518) [#695](#695) [#744](#744)
* **aws-dynamodb:** Attribute type for keys, changes the signature of the `addPartitionKey` and `addSortKey` methods to be consistent across the board. ([#720](#720)) ([e6cc189](e6cc189))
* **aws-codebuild:** fix typo "priviledged" -> "privileged

* **assets:** cab't use multiple assets in the same stack ([#725](#725)) ([bba2e5b](bba2e5b)), closes [#706](#706)
* **aws-codebuild:** typo in BuildEnvironment "priviledged" -> "privileged     ([#734](#734)) ([72fec36](72fec36))
* **aws-ecr:** fix addToResourcePolicy ([#737](#737)) ([eadbda5](eadbda5))
* **aws-events:** ruleName can now be specified ([#726](#726)) ([a7bc5ee](a7bc5ee)), closes [#708](#708)
* **aws-lambda:** jsii use no long requires 'sourceAccount' ([#728](#728)) ([9e7d311](9e7d311)), closes [#714](#714)
* **aws-s3:** remove `policy` argument ([#730](#730)) ([a79190c](a79190c)), closes [#672](#672)
* **cdk:** "cdk init" java template is broken ([#732](#732)) ([281c083](281c083)), closes [#711](#711) [aws/jsii#233](aws/jsii#233)

* **aws-apigateway:** new API Gateway Construct Library ([#665](#665)) ([b0f3857](b0f3857))
* **aws-cdk:** detect presence of EC2 credentials ([#724](#724)) ([8e8c295](8e8c295)), closes [#702](#702) [#130](#130)
* **aws-codepipeline:** make the Stage insertion API in CodePipeline more flexible ([#460](#460)) ([d182818](d182818))
* **aws-codepipeline:** new "Pipeline#addStage" convenience method ([#647](#647)) ([25c9fa0](25c9fa0))
* **aws-rds:** add support for parameter groups ([#729](#729)) ([2541508](2541508)), closes [#719](#719)
* **docs:** add documentation for CDK toolkit plugings ([#733](#733)) ([965b918](965b918))
* **dependencies:** upgrade to [jsii 0.7.6](https://github.com/awslabs/jsii/releases/tag/v0.7.6)
eladb pushed a commit that referenced this pull request Sep 20, 2018
* v0.9.2

__NOTICE__: This release includes a framework-wide [__breaking
change__](#712) which changes the type
of all the string resource attributes across the framework. Instead of using
strong-types that extend `cdk.Token` (such as `QueueArn`, `TopicName`, etc), we
now represent all these attributes as normal `string`s, and codify the tokens
into the string (using the feature introduced in [#168](#168)).

Furthermore, the `cdk.Arn` type has been removed. In order to format/parse ARNs,
use the static methods on `cdk.ArnUtils`.

See motivation and discussion in [#695](#695).

* **cfn2ts:** use stringified tokens for resource attributes instead of strong types ([#712](#712)) ([6508f78](6508f78)), closes [#518](#518) [#695](#695) [#744](#744)
* **aws-dynamodb:** Attribute type for keys, changes the signature of the `addPartitionKey` and `addSortKey` methods to be consistent across the board. ([#720](#720)) ([e6cc189](e6cc189))
* **aws-codebuild:** fix typo "priviledged" -> "privileged

* **assets:** cab't use multiple assets in the same stack ([#725](#725)) ([bba2e5b](bba2e5b)), closes [#706](#706)
* **aws-codebuild:** typo in BuildEnvironment "priviledged" -> "privileged     ([#734](#734)) ([72fec36](72fec36))
* **aws-ecr:** fix addToResourcePolicy ([#737](#737)) ([eadbda5](eadbda5))
* **aws-events:** ruleName can now be specified ([#726](#726)) ([a7bc5ee](a7bc5ee)), closes [#708](#708)
* **aws-lambda:** jsii use no long requires 'sourceAccount' ([#728](#728)) ([9e7d311](9e7d311)), closes [#714](#714)
* **aws-s3:** remove `policy` argument ([#730](#730)) ([a79190c](a79190c)), closes [#672](#672)
* **cdk:** "cdk init" java template is broken ([#732](#732)) ([281c083](281c083)), closes [#711](#711) [aws/jsii#233](aws/jsii#233)

* **aws-apigateway:** new API Gateway Construct Library ([#665](#665)) ([b0f3857](b0f3857))
* **aws-cdk:** detect presence of EC2 credentials ([#724](#724)) ([8e8c295](8e8c295)), closes [#702](#702) [#130](#130)
* **aws-codepipeline:** make the Stage insertion API in CodePipeline more flexible ([#460](#460)) ([d182818](d182818))
* **aws-codepipeline:** new "Pipeline#addStage" convenience method ([#647](#647)) ([25c9fa0](25c9fa0))
* **aws-rds:** add support for parameter groups ([#729](#729)) ([2541508](2541508)), closes [#719](#719)
* **docs:** add documentation for CDK toolkit plugings ([#733](#733)) ([965b918](965b918))
* **dependencies:** upgrade to [jsii 0.7.6](https://github.com/awslabs/jsii/releases/tag/v0.7.6)
@NGL321 NGL321 added the contribution/core This is a PR that came from AWS. label Sep 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants