Skip to content

Commit

Permalink
fix(codebuild): API cleanup.
Browse files Browse the repository at this point in the history
Change the names of the source classes to be more consistent with other integrations.
Introduce an ISource interface. Make all Source subclasses package-private,
and use static factory methods on Source (renamed from BuildSource) instead.

Change the names of artifacts classes to be more consistent with other integrations.
Introduce the IArtifacts interface. Make all Artifacts subclasses package-private,
and use static factory methods on Artifacts (renamed from BuildArtifacts) instead.

Get rid of the SourceType enum.

Remove the buildScriptAsset and buildScriptAssetEntrypoint properties.

Make Project implements ec2.IConnectable instead of exposing secuirtyGroups directly.

BREAKING CHANGE:
* codebuild: rename BuildSource to Source, BuildArtifacts to Artifacts
* codebuild: all Source and Artifacts classes can only be created through static factory methods instead of constructors
* codebuild: the construction properties buildScriptAsset and buildScriptAssetEntrypoint were removed
* codebuild: the Projet.securityGroups property has been removed; Project now implements ec2.IConnectable instead
  • Loading branch information
skinny85 committed Jun 17, 2019
1 parent be574a1 commit 6403b4f
Show file tree
Hide file tree
Showing 25 changed files with 499 additions and 898 deletions.
49 changes: 28 additions & 21 deletions packages/@aws-cdk/aws-codebuild/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,10 @@ methods and attributes.
## Source

Build projects are usually associated with a _source_, which is specified via
the `source` property which accepts a class that extends the `BuildSource`
abstract base class. The supported sources are:

### `NoSource`

This is the default and implies that no source is associated with this
build project.

The `buildSpec` option is required in this case.
the `source` property which accepts a class that extends the `Source`
abstract base class.
The default is to have no source associated with the build project;
the `buildSpec` option is required in that case.

Here's a CodeBuild project with no source which simply prints `Hello,
CodeBuild!`:
Expand All @@ -67,11 +62,11 @@ import codecommit = require('@aws-cdk/aws-codecommit');

const repository = new codecommit.Repository(this, 'MyRepo', { repositoryName: 'foo' });
new codebuild.Project(this, 'MyFirstCodeCommitProject', {
source: new codebuild.CodeCommitSource({ repository }),
source: codebuild.Source.codeCommit({ repository }),
});
```

### `S3BucketSource`
### `S3Source`

Create a CodeBuild project with an S3 bucket as the source:

Expand All @@ -81,25 +76,20 @@ import s3 = require('@aws-cdk/aws-s3');

const bucket = new s3.Bucket(this, 'MyBucket');
new codebuild.Project(this, 'MyProject', {
source: new codebuild.S3BucketSource({
source: codebuild.Source.s3({
bucket: bucket,
path: 'path/to/file.zip',
}),
});
```

### `CodePipelineSource`

Used as a special source type when a CodeBuild project is used as a
CodePipeline action.

### `GitHubSource` and `GitHubEnterpriseSource`

These source types can be used to build code from a GitHub repository.
Example:

```typescript
const gitHubSource = new codebuild.GitHubSource({
const gitHubSource = codebuild.Source.gitHub({
owner: 'awslabs',
repo: 'aws-cdk',
webhook: true, // optional, default: true if `webhookFilteres` were provided, false otherwise
Expand All @@ -121,6 +111,23 @@ aws codebuild import-source-credentials --server-type GITHUB --auth-type PERSONA

This source type can be used to build code from a BitBucket repository.

## CodePipeline

To add a CodeBuild Project as an Action to CodePipeline,
use the `PipelineProject` class instead of `Project`.
It's a simple class that doesn't allow you to specify `sources`,
`secondarySources`, `artifacts` or `secondaryArtifacts`,
as these are handled by setting input and output CodePipeline `Artifact` instances on the Action,
instead of setting them on the Project.

```typescript
const project = new codebuild.PipelineProject(this, 'Project', {
// properties as above...
})
```

For more details, see the readme of the `@aws-cdk/@aws-codepipeline` package.

## Caching

You can save time when your project builds by using a cache. A cache can store reusable pieces of your build environment and use them across multiple builds. Your build project can use one of two types of caching: Amazon S3 or local. In general, S3 caching is a good option for small and intermediate build artifacts that are more expensive to build than to download. Local caching is a good option for large intermediate build artifacts because the cache is immediately available on the build host.
Expand Down Expand Up @@ -225,13 +232,13 @@ multiple outputs. For example:
```ts
const project = new codebuild.Project(this, 'MyProject', {
secondarySources: [
new codebuild.CodeCommitSource({
codebuild.Source.codeCommit({
identifier: 'source2',
repository: repo,
}),
],
secondaryArtifacts: [
new codebuild.S3BucketBuildArtifacts({
codebuild.Artifacts.s3({
identifier: 'artifact2',
bucket: bucket,
path: 'some/path',
Expand Down Expand Up @@ -324,7 +331,7 @@ const securityGroup = new ec2.SecurityGroup(stack, 'SecurityGroup1', {
vpc: vpc,
});
new Project(stack, 'MyProject', {
buildScriptAsset: new assets.ZipDirectoryAsset(stack, 'Bundle', { path: 'script_bundle' }),
buildScript: new assets.ZipDirectoryAsset(stack, 'Bundle', { path: 'script_bundle' }),
securityGroups: [securityGroup],
vpc: vpc
});
Expand Down
131 changes: 64 additions & 67 deletions packages/@aws-cdk/aws-codebuild/lib/artifacts.ts
Original file line number Diff line number Diff line change
@@ -1,84 +1,83 @@
import s3 = require('@aws-cdk/aws-s3');
import { Construct } from '@aws-cdk/cdk';
import { CfnProject } from './codebuild.generated';
import { Project } from './project';
import { IProject } from './project';

/**
* Properties common to all Artifacts classes.
* The type returned from {@link IArtifacts#bind}.
*/
export interface BuildArtifactsProps {
export interface ArtifactsConfig {
/**
* The artifact identifier.
* This property is required on secondary artifacts.
* The low-level CloudFormation artifacts property.
*/
readonly identifier?: string;
readonly artifactsProperty: CfnProject.ArtifactsProperty;
}

/**
* Artifacts definition for a CodeBuild Project.
* The abstract interface of a CodeBuild build output.
* Implemented by {@link Artifacts}.
*/
export abstract class BuildArtifacts {
public readonly identifier?: string;
protected abstract readonly type: string;

constructor(props: BuildArtifactsProps) {
this.identifier = props.identifier;
}

export interface IArtifacts {
/**
* @internal
* The artifact identifier.
* This property is required on secondary artifacts.
*/
public _bind(_project: Project) {
return;
}
readonly identifier?: string;

public toArtifactsJSON(): CfnProject.ArtifactsProperty {
const artifactsProp = this.toArtifactsProperty();
return {
artifactIdentifier: this.identifier,
type: this.type,
...artifactsProp,
};
}
/**
* The CodeBuild type of this artifact.
*/
readonly type: string;

protected toArtifactsProperty(): any {
return {
};
}
/**
* Callback when an Artifacts class is used in a CodeBuild Project.
*
* @param scope a root Construct that allows creating new Constructs
* @param project the Project this Artifacts is used in
*/
bind(scope: Construct, project: IProject): ArtifactsConfig;
}

/**
* A `NO_ARTIFACTS` CodeBuild Project Artifact definition.
* This is the default artifact type,
* if none was specified when creating the Project
* (and the source was not specified to be CodePipeline).
* *Note*: the `NO_ARTIFACTS` type cannot be used as a secondary artifact,
* and because of that, you're not allowed to specify an identifier for it.
* Properties common to all Artifacts classes.
*/
export class NoBuildArtifacts extends BuildArtifacts {
protected readonly type = 'NO_ARTIFACTS';

constructor() {
super({});
}
export interface ArtifactsProps {
/**
* The artifact identifier.
* This property is required on secondary artifacts.
*/
readonly identifier?: string;
}

/**
* CodePipeline Artifact definition for a CodeBuild Project.
* *Note*: this type cannot be used as a secondary artifact,
* and because of that, you're not allowed to specify an identifier for it.
* Artifacts definition for a CodeBuild Project.
*/
export class CodePipelineBuildArtifacts extends BuildArtifacts {
protected readonly type = 'CODEPIPELINE';
export abstract class Artifacts implements IArtifacts {
public static s3(props: S3ArtifactsProps): Artifacts {
return new S3Artifacts(props);
}

constructor() {
super({});
public readonly identifier?: string;
public abstract readonly type: string;

protected constructor(props: ArtifactsProps) {
this.identifier = props.identifier;
}

public bind(_scope: Construct, _project: IProject): ArtifactsConfig {
return {
artifactsProperty: {
artifactIdentifier: this.identifier,
type: this.type,
},
};
}
}

/**
* Construction properties for {@link S3BucketBuildArtifacts}.
* Construction properties for {@link S3Artifacts}.
*/
export interface S3BucketBuildArtifactsProps extends BuildArtifactsProps {
export interface S3ArtifactsProps extends ArtifactsProps {
/**
* The name of the output bucket.
*/
Expand Down Expand Up @@ -119,27 +118,25 @@ export interface S3BucketBuildArtifactsProps extends BuildArtifactsProps {
/**
* S3 Artifact definition for a CodeBuild Project.
*/
export class S3BucketBuildArtifacts extends BuildArtifacts {
protected readonly type = 'S3';
class S3Artifacts extends Artifacts {
public readonly type = 'S3';

constructor(private readonly props: S3BucketBuildArtifactsProps) {
constructor(private readonly props: S3ArtifactsProps) {
super(props);
}

/**
* @internal
*/
public _bind(project: Project) {
public bind(_scope: Construct, project: IProject): ArtifactsConfig {
this.props.bucket.grantReadWrite(project);
}

protected toArtifactsProperty(): any {
const superConfig = super.bind(_scope, project);
return {
location: this.props.bucket.bucketName,
path: this.props.path,
namespaceType: this.props.includeBuildId === false ? 'NONE' : 'BUILD_ID',
name: this.props.name,
packaging: this.props.packageZip === false ? 'NONE' : 'ZIP',
artifactsProperty: {
...superConfig.artifactsProperty,
location: this.props.bucket.bucketName,
path: this.props.path,
namespaceType: this.props.includeBuildId === false ? 'NONE' : 'BUILD_ID',
name: this.props.name,
packaging: this.props.packageZip === false ? 'NONE' : 'ZIP',
}
};
}
}
14 changes: 14 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/codepipeline-artifacts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Artifacts } from './artifacts';

/**
* CodePipeline Artifact definition for a CodeBuild Project.
* *Note*: this type cannot be used as a secondary artifact,
* and because of that, you're not allowed to specify an identifier for it.
*/
export class CodePipelineArtifacts extends Artifacts {
public readonly type = 'CODEPIPELINE';

constructor() {
super({});
}
}
15 changes: 15 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/codepipeline-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Source } from './source';
import { CODEPIPELINE_SOURCE_ARTIFACTS_TYPE } from './source-types';

/**
* CodePipeline Source definition for a CodeBuild Project.
* *Note*: this type cannot be used as a secondary source,
* and because of that, you're not allowed to specify an identifier for it.
*/
export class CodePipelineSource extends Source {
public readonly type = CODEPIPELINE_SOURCE_ARTIFACTS_TYPE;

constructor() {
super({});
}
}
19 changes: 19 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/no-artifacts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Artifacts } from './artifacts';

/**
* A `NO_ARTIFACTS` CodeBuild Project Artifact definition.
* This is the default artifact type,
* if none was specified when creating the Project
* (and the source was not specified to be CodePipeline).
* *Note*: the `NO_ARTIFACTS` type cannot be used as a secondary artifact,
* and because of that, you're not allowed to specify an identifier for it.
*
* This class is private to the @aws-codebuild package.
*/
export class NoArtifacts extends Artifacts {
public readonly type = 'NO_ARTIFACTS';

constructor() {
super({});
}
}
19 changes: 19 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/no-source.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { Source } from './source';
import { NO_SOURCE_TYPE } from './source-types';

/**
* A `NO_SOURCE` CodeBuild Project Source definition.
* This is the default source type,
* if none was specified when creating the Project.
* *Note*: the `NO_SOURCE` type cannot be used as a secondary source,
* and because of that, you're not allowed to specify an identifier for it.
*
* This class is private to the aws-codebuild package.
*/
export class NoSource extends Source {
public readonly type = NO_SOURCE_TYPE;

constructor() {
super({});
}
}
6 changes: 3 additions & 3 deletions packages/@aws-cdk/aws-codebuild/lib/pipeline-project.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import cdk = require('@aws-cdk/cdk');
import { CodePipelineBuildArtifacts } from './artifacts';
import { CodePipelineArtifacts } from './codepipeline-artifacts';
import { CodePipelineSource } from './codepipeline-source';
import { CommonProjectProps, Project } from './project';
import { CodePipelineSource } from './source';

// tslint:disable-next-line:no-empty-interface
export interface PipelineProjectProps extends CommonProjectProps {
Expand All @@ -14,7 +14,7 @@ export class PipelineProject extends Project {
constructor(scope: cdk.Construct, id: string, props?: PipelineProjectProps) {
super(scope, id, {
source: new CodePipelineSource(),
artifacts: new CodePipelineBuildArtifacts(),
artifacts: new CodePipelineArtifacts(),
...props
});
}
Expand Down
Loading

0 comments on commit 6403b4f

Please sign in to comment.