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

[BREAKING] Pass the Pipeline to Stage through props instead of parent #568

Merged
merged 1 commit into from
Aug 15, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 {
Copy link
Contributor

Choose a reason for hiding this comment

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

document, tell users that they don't need to use it directly and what they should be using

Copy link
Contributor Author

Choose a reason for hiding this comment

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

👍🏻

// _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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

might make sense to allow people to customize the stage name such that it's not the construct id (which is a sensible default)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes! This is actually part of a bigger discussion about Stage / Action naming that I want to have with you guys.

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