Skip to content

Commit

Permalink
refactor(aws-codepipeline): Pass the Pipeline to Stage through props …
Browse files Browse the repository at this point in the history
…instead of parent. (#568)

BREAKING CHANGE: this commit changes the way we pass a Pipeline to a newly created Stage.
Instead of passing it as a parent, in the first argument of the constructor,
we now pass it through a separate props object, in the pipeline property.
This is in order to make Stage more consistent with other Constructs,
and with the changes made to the Actions API in #459.
  • Loading branch information
skinny85 authored Aug 15, 2018
1 parent 518cef3 commit 0b92202
Show file tree
Hide file tree
Showing 17 changed files with 88 additions and 66 deletions.
8 changes: 6 additions & 2 deletions packages/@aws-cdk/aws-codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,18 @@ const project = new codebuild.PipelineProject(this, 'MyProject');

const pipeline = new codepipeline.Pipeline(this, 'MyPipeline');

const sourceStage = new codepipeline.Stage(pipeline, 'Source');
const sourceStage = new codepipeline.Stage(this, 'Source', {
pipeline,
});
const sourceAction = new codecommit.PipelineSource(this, 'CodeCommit', {
stage: sourceStage,
artifactName: 'SourceOutput',
repository,
});

const buildStage = new codepipeline.Stage(pipeline, 'Build');
const buildStage = new codepipeline.Stage(this, 'Build', {
pipeline,
});
new codebuild.PipelineBuildAction(this, 'CodeBuild', {
stage: buildStage,
inputArtifact: sourceAction.artifact,
Expand Down
6 changes: 4 additions & 2 deletions packages/@aws-cdk/aws-codecommit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ const repository = new codecommit.Repository( // ...
const pipeline = new codepipeline.Pipeline(this, 'MyPipeline', {
pipelineName: 'MyPipeline',
});
const sourceStage = new codepipeline.Stage(pipeline, 'Source');
const sourceStage = new codepipeline.Stage(this, 'Source', {
pipeline,
}));
const sourceAction = new codecommit.PipelineSource(this, 'CodeCommit', {
stage: sourceStage,
artifactName: 'SourceOutput', //name can be arbitrary
artifactName: 'SourceOutput', // name can be arbitrary
repository,
});
// use sourceAction.artifact as the inputArtifact to later Actions...
Expand Down
12 changes: 6 additions & 6 deletions packages/@aws-cdk/aws-codepipeline/README.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
## AWS CodePipeline construct library

Construct an empty pipeline:
Construct an empty Pipeline:

```ts
const pipeline = new Pipeline(this, 'MyFirstPipeline', {
pipelineName: 'MyFirstPipeline',
});
```

All of the components of a pipeline are modeled as constructs.

Append a stage to the pipeline:
Append a Stage to the Pipeline:

```ts
const sourceStage = new Stage(pipeline, 'Source');
const sourceStage = new Stage(this, 'Source', {
pipeline,
});
```

Add an action to a stage:
Add an Action to a Stage:

```ts
new codecommit.PipelineSource(this, 'Source', {
Expand Down
25 changes: 13 additions & 12 deletions packages/@aws-cdk/aws-codepipeline/lib/pipeline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,21 +211,22 @@ export class Pipeline extends cdk.Construct implements events.IEventRuleTarget {
}

/**
* If a stage is added as a child, add it to the list of stages.
* TODO: This is a hack that should be removed once the CDK has an
* onChildAdded type hook.
* @override
* Adds a Stage to this Pipeline.
* This is an internal operation -
* a Stage is added to a Pipeline when it's constructed
* (the Pipeline is passed through the {@link StageProps#pipeline} property),
* so there is never a need to call this method explicitly.
*
* @param stage the newly created Stage to add to this Pipeline
*/
protected addChild(child: cdk.Construct, name: string) {
super.addChild(child, name);
if (child instanceof Stage) {
this.appendStage(child);
public _addStage(stage: Stage): void {
// _addStage should be idempotent, in case a customer ever calls it directly
if (this.stages.includes(stage)) {
return;
}
}

private appendStage(stage: Stage) {
if (this.stages.find(x => x.id === stage.id)) {
throw new Error(`A stage with name '${stage.id}' already exists`);
if (this.stages.find(x => x.name === stage.name)) {
throw new Error(`A stage with name '${stage.name}' already exists`);
}

this.stages.push(stage);
Expand Down
35 changes: 23 additions & 12 deletions packages/@aws-cdk/aws-codepipeline/lib/stage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,45 @@ import { cloudformation } from './codepipeline.generated';
import { Pipeline } from './pipeline';

/**
* A stage in a pipeline. Stages are added to a pipeline by constructing a Stage with
* the pipeline as the first argument to the constructor.
* The construction properties for {@link Stage}.
*/
export interface StageProps {
/**
* The Pipeline to add the newly created Stage to.
*/
pipeline: Pipeline;
}

/**
* A Stage in a Pipeline.
* Stages are added to a Pipeline by constructing a new Stage,
* and passing the Pipeline it belongs to through the {@link StageProps#pipeline} attribute.
*
* @example
* // add a stage to a pipeline
* new Stage(pipeline, 'MyStage');
* // add a Stage to a Pipeline
* new Stage(this, 'MyStage', {
* pipeline: myPipeline,
* });
*/
export class Stage extends cdk.Construct implements actions.IStage {
/**
* The Pipeline this stage is a member of
* The Pipeline this Stage is a part of.
*/
public readonly pipeline: Pipeline;
public readonly name: string;

private readonly _actions = new Array<actions.Action>();

/**
* Append a new stage to the pipeline
*
* Only a Pipeline can be passed in as a parent because stages should
* always be attached to a pipeline. It's illogical to construct a Stage
* with any other parent.
* Create a new Stage.
*/
constructor(parent: Pipeline, name: string) {
constructor(parent: cdk.Construct, name: string, props: StageProps) {
super(parent, name);
this.name = name;
this.pipeline = parent;
this.pipeline = props.pipeline;
actions.validateName('Stage', name);

this.pipeline._addStage(this);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ const pipeline = new codepipeline.Pipeline(stack, 'Pipeline');
const repo = new codecommit.Repository(stack, 'TemplateRepo', {
repositoryName: 'template-repo'
});
const sourceStage = new codepipeline.Stage(pipeline, 'Source');
const sourceStage = new codepipeline.Stage(pipeline, 'Source', { pipeline });
const source = new codecommit.PipelineSource(stack, 'Source', {
stage: sourceStage,
repository: repo,
artifactName: 'SourceArtifact',
});

// Deployment stage: create and deploy changeset with manual approval
const prodStage = new codepipeline.Stage(pipeline, 'Deploy');
const prodStage = new codepipeline.Stage(pipeline, 'Deploy', { pipeline });
const stackName = 'OurStack';
const changeSetName = 'StagedChangeSet';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-lambda');

const pipeline = new codepipeline.Pipeline(stack, 'Pipeline');

const sourceStage = new codepipeline.Stage(pipeline, 'Source');
const sourceStage = new codepipeline.Stage(pipeline, 'Source', { pipeline });
const bucket = new s3.Bucket(stack, 'PipelineBucket', {
versioned: true,
});
Expand All @@ -29,7 +29,7 @@ const lambdaFun = new lambda.Function(stack, 'LambdaFun', {
handler: 'index.handler',
runtime: lambda.Runtime.NodeJS610,
});
const lambdaStage = new codepipeline.Stage(pipeline, 'Lambda');
const lambdaStage = new codepipeline.Stage(pipeline, 'Lambda', { pipeline });
new lambda.PipelineInvokeAction(stack, 'Lambda', {
stage: lambdaStage,
lambda: lambdaFun,
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-codepipeline/test/integ.pipeline-cfn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const stack = new cdk.Stack(app, 'aws-cdk-codepipeline-cloudformation');

const pipeline = new codepipeline.Pipeline(stack, 'Pipeline');

const sourceStage = new codepipeline.Stage(pipeline, 'Source');
const sourceStage = new codepipeline.Stage(pipeline, 'Source', { pipeline });
const bucket = new s3.Bucket(stack, 'PipelineBucket', {
versioned: true,
});
Expand All @@ -23,7 +23,7 @@ const source = new s3.PipelineSource(stack, 'Source', {
bucketKey: 'key',
});

const cfnStage = new codepipeline.Stage(pipeline, 'CFN');
const cfnStage = new codepipeline.Stage(stack, 'CFN', { pipeline });

const changeSetName = "ChangeSetIntegTest";
const stackName = "IntegTest-TestActionStack";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const repository = new codecommit.Repository(stack, 'MyRepo', {

const pipeline = new codepipeline.Pipeline(stack, 'Pipeline');

const sourceStage = new codepipeline.Stage(pipeline, 'source');
const sourceStage = new codepipeline.Stage(pipeline, 'source', { pipeline });
const source = new codecommit.PipelineSource(stack, 'source', {
stage: sourceStage,
artifactName: 'SourceArtifact',
Expand All @@ -24,7 +24,7 @@ const project = new codebuild.Project(stack, 'MyBuildProject', {
source: new codebuild.CodePipelineSource(),
});

const buildStage = new codepipeline.Stage(pipeline, 'build');
const buildStage = new codepipeline.Stage(pipeline, 'build', { pipeline });
new codebuild.PipelineBuildAction(buildStage, 'build', {
stage: buildStage,
inputArtifact: source.artifact,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ const repo = new codecommit.Repository(stack, 'MyRepo', { repositoryName: 'my-re

const pipeline = new codepipeline.Pipeline(stack, 'Pipeline');

const sourceStage = new codepipeline.Stage(pipeline, 'source');
const sourceStage = new codepipeline.Stage(pipeline, 'source', { pipeline });
new codecommit.PipelineSource(stack, 'source', {
stage: sourceStage,
artifactName: 'SourceArtifact',
repository: repo,
});

const buildStage = new codepipeline.Stage(pipeline, 'build');
const buildStage = new codepipeline.Stage(stack, 'build', { pipeline });
new codepipeline.ManualApprovalAction(stack, 'manual', {
stage: buildStage,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ const app = new cdk.App(process.argv);
const stack = new cdk.Stack(app, 'aws-cdk-pipeline-event-target');

const pipeline = new codepipeline.Pipeline(stack, 'MyPipeline');
const sourceStage = new codepipeline.Stage(pipeline, 'Source');
const buildStage = new codepipeline.Stage(pipeline, 'Build');
const sourceStage = new codepipeline.Stage(stack, 'Source', { pipeline });
const buildStage = new codepipeline.Stage(stack, 'Build', { pipeline });

const repository = new codecommit.Repository(stack, 'CodeCommitRepo', {
repositoryName: 'foo'
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-codepipeline/test/test.action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export = {
'standard action with artifacts'(test: Test) {
const stack = new cdk.Stack();
const pipeline = new codepipeline.Pipeline(stack, 'pipeline');
const stage = new codepipeline.Stage(pipeline, 'stage');
const stage = new codepipeline.Stage(stack, 'stage', { pipeline });
const action = new TestAction(stack, 'TestAction', {
stage,
artifactBounds: actions.defaultBounds(),
Expand Down Expand Up @@ -95,7 +95,7 @@ export = {
function boundsValidationResult(numberOfArtifacts: number, min: number, max: number): string[] {
const stack = new cdk.Stack();
const pipeline = new codepipeline.Pipeline(stack, 'pipeline');
const stage = new codepipeline.Stage(pipeline, 'stage');
const stage = new codepipeline.Stage(stack, 'stage', { pipeline });
const action = new TestAction(stack, 'TestAction', {
stage,
artifactBounds: actions.defaultBounds(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export = {
/** Source! */
const repo = new Repository(stack, 'MyVeryImportantRepo', { repositoryName: 'my-very-important-repo' });

const sourceStage = new Stage(pipeline, 'source');
const sourceStage = new Stage(pipeline, 'source', { pipeline });

const source = new PipelineSource(stack, 'source', {
stage: sourceStage,
Expand All @@ -34,7 +34,7 @@ export = {

/** Build! */

const buildStage = new Stage(pipeline, 'build');
const buildStage = new Stage(pipeline, 'build', { pipeline });
const buildArtifacts = new CodePipelineBuildArtifacts();
const project = new Project(stack, 'MyBuildProject', {
source: new CodePipelineSource(),
Expand All @@ -53,7 +53,7 @@ export = {
// To execute a change set - yes, you probably do need *:* 🤷‍♀️
changeSetExecRole.addToPolicy(new PolicyStatement().addAllResources().addAction("*"));

const prodStage = new Stage(pipeline, 'prod');
const prodStage = new Stage(stack, 'prod', { pipeline });
const stackName = 'BrelandsStack';
const changeSetName = 'MyMagicalChangeSet';

Expand Down Expand Up @@ -366,8 +366,8 @@ class TestFixture extends cdk.Stack {
super();

this.pipeline = new Pipeline(this, 'Pipeline');
this.sourceStage = new Stage(this.pipeline, 'Source');
this.deployStage = new Stage(this.pipeline, 'Deploy');
this.sourceStage = new Stage(this.pipeline, 'Source', { pipeline: this.pipeline });
this.deployStage = new Stage(this.pipeline, 'Deploy', { pipeline: this.pipeline });
this.repo = new Repository(this, 'MyVeryImportantRepo', { repositoryName: 'my-very-important-repo' });
this.source = new PipelineSource(this, 'Source', {
stage: this.sourceStage,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,8 @@ export = {
'should fail if Pipeline has a Source Action in a non-first Stage'(test: Test) {
const stack = new cdk.Stack();
const pipeline = new Pipeline(stack, 'Pipeline');
const firstStage = new Stage(pipeline, 'FirstStage');
const secondStage = new Stage(pipeline, 'SecondStage');
const firstStage = new Stage(stack, 'FirstStage', { pipeline });
const secondStage = new Stage(stack, 'SecondStage', { pipeline });

const bucket = new s3.Bucket(stack, 'PipelineBucket');
new s3.PipelineSource(stack, 'FirstAction', {
Expand All @@ -83,5 +83,5 @@ export = {
function stageForTesting(): Stage {
const stack = new cdk.Stack();
const pipeline = new Pipeline(stack, 'pipeline');
return new Stage(pipeline, 'stage');
return new Stage(stack, 'stage', { pipeline });
}
Loading

0 comments on commit 0b92202

Please sign in to comment.