Skip to content
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
9 changes: 9 additions & 0 deletions packages/@aws-cdk/aws-codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,15 @@ const project = new codebuild.Project(this, 'MyProject', {
}
```

You can also add the Project to the Pipeline directly:

```ts
// equivalent to the code above:
project.addBuildToPipeline(buildStage, 'CodeBuild', {
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just addToPipeline? It's a build project after all...
If this is because a build project can be added as a test action, this can be indicated in a prop

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You're correct Elad - the reason is that there will also be a test Action in the future (PipelineTestAction) that uses CodeBuild Projects.

My justification for separating them is that PipelineBuildAction and PipelineTestAction may actually have different construction properties (the test Action doesn't produce outputs, for example). Separation into addBuildToPipeline and addTestToPipeline gives us the flexibility to have these different props. If we have one addToPipeline method with a type: ProjectType.BUILD/.TEST property, we will forever be locked into them having the same properties.

Does this make sense?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Actually, we simply can't express addToPipeline at all now - this method would have to return either the PipelineBuildAction or the PipelineTestAction type, and there is no way of expressing that without using generics, which JSII does not support.

Copy link
Contributor

Choose a reason for hiding this comment

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

They could share a base class that has a disambiguator property. But that's not so great developer experience...

inputArtifact: sourceAction.artifact,
})
```

### Using Project as an event target

The `Project` construct implements the `IEventRuleTarget` interface. This means that it can be
Expand Down
11 changes: 9 additions & 2 deletions packages/@aws-cdk/aws-codebuild/lib/pipeline-actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import cdk = require('@aws-cdk/cdk');
import { ProjectRef } from './project';

/**
* Construction properties of the {@link PipelineBuildAction CodeBuild build CodePipeline Action}.
* Common properties for creating {@link PipelineBuildAction} -
* either directly, through its constructor,
* or through {@link ProjectRef#addBuildToPipeline}.
*/
export interface PipelineBuildActionProps extends codepipeline.CommonActionProps {
export interface CommonPipelineBuildActionProps {
/**
* The source to use as input for this build
*/
Expand All @@ -15,7 +17,12 @@ export interface PipelineBuildActionProps extends codepipeline.CommonActionProps
* The name of the build's output artifact
*/
artifactName?: string;
}

/**
* Construction properties of the {@link PipelineBuildAction CodeBuild build CodePipeline Action}.
*/
export interface PipelineBuildActionProps extends CommonPipelineBuildActionProps, codepipeline.CommonActionProps {
/**
* The build project
*/
Expand Down
19 changes: 19 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import cloudwatch = require('@aws-cdk/aws-cloudwatch');
import codepipeline = require('@aws-cdk/aws-codepipeline-api');
import events = require('@aws-cdk/aws-events');
import iam = require('@aws-cdk/aws-iam');
import kms = require('@aws-cdk/aws-kms');
import s3 = require('@aws-cdk/aws-s3');
import cdk = require('@aws-cdk/cdk');
import { BuildArtifacts, CodePipelineBuildArtifacts, NoBuildArtifacts } from './artifacts';
import { cloudformation, ProjectArn, ProjectName } from './codebuild.generated';
import { CommonPipelineBuildActionProps, PipelineBuildAction } from './pipeline-actions';
import { BuildSource } from './source';

const CODEPIPELINE_TYPE = 'CODEPIPELINE';
Expand Down Expand Up @@ -75,6 +77,23 @@ export abstract class ProjectRef extends cdk.Construct implements events.IEventR
};
}

/**
* Convenience method for creating a new {@link PipelineBuildAction} build Action,
* and adding it to the given Stage.
*
* @param stage the Pipeline Stage to add the new Action to
* @param name the name of the newly created Action
* @param props the properties of the new Action
* @returns the newly created {@link PipelineSource} Action
*/
public addBuildToPipeline(stage: codepipeline.IStage, name: string, props: CommonPipelineBuildActionProps): PipelineBuildAction {
return new PipelineBuildAction(this.parent!, name, {
stage,
project: this,
...props,
});
}

/**
* Defines a CloudWatch event rule triggered when the build project state
* changes. You can filter specific build status events using an event
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,8 @@ const project = new codebuild.Project(stack, 'MyBuildProject', {
});

const buildStage = new codepipeline.Stage(pipeline, 'build', { pipeline });
new codebuild.PipelineBuildAction(buildStage, 'build', {
stage: buildStage,
project.addBuildToPipeline(buildStage, 'build', {
inputArtifact: source.artifact,
project,
});

process.stdout.write(app.run());
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', {
});

const sourceStage = new codepipeline.Stage(stack, 'Source', { pipeline });
const sourceAction = new s3.PipelineSource(stack, 'S3Source', {
stage: sourceStage,
bucket,
const sourceAction = bucket.addToPipeline(sourceStage, 'S3Source', {
bucketKey: 'application.zip',
artifactName: 'SourceOutput',
});
Expand Down
10 changes: 10 additions & 0 deletions packages/@aws-cdk/aws-s3/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ const sourceAction = new s3.PipelineSource(this, 'S3Source', {
// use sourceAction.artifact as the inputArtifact to later Actions...
```

You can also add the Bucket to the Pipeline directly:

```ts
// equivalent to the code above:
const sourceAction = sourceBucket.addToPipeline(sourceStage, 'CodeCommit', {
bucketKey: 'path/to/file.zip',
artifactName: 'SourceOutput',
});
```

### Importing and Exporting Buckets

You can create a `Bucket` construct that represents an external/existing/unowned bucket by using the `Bucket.import` factory method.
Expand Down
19 changes: 19 additions & 0 deletions packages/@aws-cdk/aws-s3/lib/bucket.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import actions = require('@aws-cdk/aws-codepipeline-api');
import iam = require('@aws-cdk/aws-iam');
import kms = require('@aws-cdk/aws-kms');
import { IBucketNotificationDestination } from '@aws-cdk/aws-s3-notifications';
import cdk = require('@aws-cdk/cdk');
import { BucketPolicy } from './bucket-policy';
import { BucketNotifications } from './notifications-resource';
import perms = require('./perms');
import { CommonPipelineSourceProps, PipelineSource } from './pipeline-action';
import { LifecycleRule } from './rule';
import { BucketArn, BucketDomainName, BucketDualStackDomainName, BucketName, cloudformation } from './s3.generated';
import { parseBucketArn, parseBucketName, validateBucketName } from './util';
Expand Down Expand Up @@ -99,6 +101,23 @@ export abstract class BucketRef extends cdk.Construct {
};
}

/**
* Convenience method for creating a new {@link PipelineSource} Action,
* and adding it to the given Stage.
*
* @param stage the Pipeline Stage to add the new Action to
* @param name the name of the newly created Action
* @param props the properties of the new Action
* @returns the newly created {@link PipelineSource} Action
*/
public addToPipeline(stage: actions.IStage, name: string, props: CommonPipelineSourceProps): PipelineSource {
return new PipelineSource(this.parent!, name, {
stage,
bucket: this,
...props,
});
}

/**
* Adds a statement to the resource policy for a principal (i.e.
* account/role/service) to perform actions on this bucket and/or it's
Expand Down
25 changes: 17 additions & 8 deletions packages/@aws-cdk/aws-s3/lib/pipeline-action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,21 @@ import cdk = require('@aws-cdk/cdk');
import { BucketRef } from './bucket';

/**
* Construction properties of the {@link PipelineSource S3 source Action}.
* Common properties for creating {@link PipelineSource} -
* either directly, through its constructor,
* or through {@link BucketRef#addToPipeline}.
*/
export interface PipelineSourceProps extends actions.CommonActionProps {
export interface CommonPipelineSourceProps {
/**
* The name of the source's output artifact. Output artifacts are used by CodePipeline as
* inputs into other actions.
*/
artifactName: string;

/**
* The Amazon S3 bucket that stores the source code
*/
bucket: BucketRef;

/**
* The key within the S3 bucket that stores the source code
* The key within the S3 bucket that stores the source code.
*
* @example 'path/to/file.zip'
*/
bucketKey: string;

Expand All @@ -31,6 +30,16 @@ export interface PipelineSourceProps extends actions.CommonActionProps {
pollForSourceChanges?: boolean;
}

/**
* Construction properties of the {@link PipelineSource S3 source Action}.
*/
export interface PipelineSourceProps extends CommonPipelineSourceProps, actions.CommonActionProps {
/**
* The Amazon S3 bucket that stores the source code
*/
bucket: BucketRef;
}

/**
* Source that is provided by a specific Amazon S3 object.
*/
Expand Down