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

feat(aws-codebuild): allow github sourceversion branch #5890

Merged
merged 9 commits into from
Feb 4, 2020
19 changes: 18 additions & 1 deletion packages/@aws-cdk/aws-codebuild/lib/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -654,6 +654,7 @@ export class Project extends ProjectBase {
private readonly source: ISource;
private readonly buildImage: IBuildImage;
private readonly _secondarySources: CfnProject.SourceProperty[];
private readonly _secondarySourceVersions: CfnProject.ProjectSourceVersionProperty[];
skinny85 marked this conversation as resolved.
Show resolved Hide resolved
private readonly _secondaryArtifacts: CfnProject.ArtifactsProperty[];
private _encryptionKey?: kms.IKey;

Expand Down Expand Up @@ -698,6 +699,7 @@ export class Project extends ProjectBase {
}

this._secondarySources = [];
this._secondarySourceVersions = [];
for (const secondarySource of props.secondarySources || []) {
this.addSecondarySource(secondarySource);
}
Expand Down Expand Up @@ -725,8 +727,10 @@ export class Project extends ProjectBase {
name: this.physicalName,
timeoutInMinutes: props.timeout && props.timeout.toMinutes(),
secondarySources: Lazy.anyValue({ produce: () => this.renderSecondarySources() }),
secondarySourceVersions: Lazy.anyValue({ produce: () => this.renderSecondarySourceVersions() }),
secondaryArtifacts: Lazy.anyValue({ produce: () => this.renderSecondaryArtifacts() }),
triggers: sourceConfig.buildTriggers,
sourceVersion: sourceConfig.sourceVersion,
vpcConfig: this.configureVpc(props),
});

Expand Down Expand Up @@ -756,7 +760,14 @@ export class Project extends ProjectBase {
if (!secondarySource.identifier) {
throw new Error('The identifier attribute is mandatory for secondary sources');
}
this._secondarySources.push(secondarySource.bind(this, this).sourceProperty);
const secondarySourceConfig = secondarySource.bind(this, this);
this._secondarySources.push(secondarySourceConfig.sourceProperty);
if (secondarySourceConfig.sourceVersion) {
this._secondarySourceVersions.push({
sourceIdentifier: secondarySource.identifier,
sourceVersion: secondarySourceConfig.sourceVersion,
});
}
}

/**
Expand Down Expand Up @@ -893,6 +904,12 @@ export class Project extends ProjectBase {
: this._secondarySources;
}

private renderSecondarySourceVersions(): CfnProject.ProjectSourceVersionProperty[] | undefined {
return this._secondarySourceVersions.length === 0
? undefined
: this._secondarySourceVersions;
}

private renderSecondaryArtifacts(): CfnProject.ArtifactsProperty[] | undefined {
return this._secondaryArtifacts.length === 0
? undefined
Expand Down
38 changes: 38 additions & 0 deletions packages/@aws-cdk/aws-codebuild/lib/source.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ export interface SourceConfig {
readonly sourceProperty: CfnProject.SourceProperty;

readonly buildTriggers?: CfnProject.ProjectTriggersProperty;

/**
* `AWS::CodeBuild::Project.SourceVersion`
* @see http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codebuild-project.html#cfn-codebuild-project-sourceversion
* @default the latest version
*/
readonly sourceVersion?: string;
}

/**
Expand Down Expand Up @@ -103,6 +110,15 @@ interface GitSourceProps extends SourceProps {
* then the full history is downloaded with each build of the project.
*/
readonly cloneDepth?: number;

/**
* The commit ID, pull request ID, branch name, or tag name that corresponds to
* the version of the source code you want to build
*
* @example 'mybranch'
* @default the default branch's HEAD commit ID is used
*/
readonly branchOrRef?: string;
}

/**
Expand Down Expand Up @@ -479,10 +495,12 @@ export interface CodeCommitSourceProps extends GitSourceProps {
class CodeCommitSource extends GitSource {
public readonly type = CODECOMMIT_SOURCE_TYPE;
private readonly repo: codecommit.IRepository;
private readonly branchOrRef?: string;

constructor(props: CodeCommitSourceProps) {
super(props);
this.repo = props.repository;
this.branchOrRef = props.branchOrRef;
knorms101 marked this conversation as resolved.
Show resolved Hide resolved
}

public bind(_scope: Construct, project: IProject): SourceConfig {
Expand All @@ -498,6 +516,7 @@ class CodeCommitSource extends GitSource {
...superConfig.sourceProperty,
location: this.repo.repositoryCloneUrlHttp,
},
sourceVersion: this.branchOrRef,
};
}
}
Expand All @@ -508,6 +527,13 @@ class CodeCommitSource extends GitSource {
export interface S3SourceProps extends SourceProps {
readonly bucket: s3.IBucket;
readonly path: string;

/**
* The version ID of the object that represents the build input ZIP file to use.
*
* @default latest
*/
readonly version?: string;
}

/**
Expand All @@ -517,11 +543,13 @@ class S3Source extends Source {
public readonly type = S3_SOURCE_TYPE;
private readonly bucket: s3.IBucket;
private readonly path: string;
private readonly version?: string;

constructor(props: S3SourceProps) {
super(props);
this.bucket = props.bucket;
this.path = props.path;
this.version = props.version;
}

public bind(_scope: Construct, project: IProject): SourceConfig {
Expand All @@ -533,6 +561,7 @@ class S3Source extends Source {
...superConfig.sourceProperty,
location: `${this.bucket.bucketName}/${this.path}`,
},
sourceVersion: this.version,
};
}
}
Expand Down Expand Up @@ -562,10 +591,12 @@ export interface GitHubSourceProps extends ThirdPartyGitSourceProps {
class GitHubSource extends ThirdPartyGitSource {
public readonly type = GITHUB_SOURCE_TYPE;
private readonly httpsCloneUrl: string;
private readonly branchOrRef?: string;

constructor(props: GitHubSourceProps) {
super(props);
this.httpsCloneUrl = `https://github.com/${props.owner}/${props.repo}.git`;
this.branchOrRef = props.branchOrRef;
}

public bind(_scope: Construct, project: IProject): SourceConfig {
Expand All @@ -575,6 +606,7 @@ class GitHubSource extends ThirdPartyGitSource {
...superConfig.sourceProperty,
location: this.httpsCloneUrl,
},
sourceVersion: this.branchOrRef,
buildTriggers: superConfig.buildTriggers,
};
}
Expand Down Expand Up @@ -604,11 +636,13 @@ class GitHubEnterpriseSource extends ThirdPartyGitSource {
public readonly type = GITHUB_ENTERPRISE_SOURCE_TYPE;
private readonly httpsCloneUrl: string;
private readonly ignoreSslErrors?: boolean;
private readonly branchOrRef?: string;

constructor(props: GitHubEnterpriseSourceProps) {
super(props);
this.httpsCloneUrl = props.httpsCloneUrl;
this.ignoreSslErrors = props.ignoreSslErrors;
this.branchOrRef = props.branchOrRef;
}

public bind(_scope: Construct, _project: IProject): SourceConfig {
Expand All @@ -619,6 +653,7 @@ class GitHubEnterpriseSource extends ThirdPartyGitSource {
location: this.httpsCloneUrl,
insecureSsl: this.ignoreSslErrors,
},
sourceVersion: this.branchOrRef,
buildTriggers: superConfig.buildTriggers,
};
}
Expand Down Expand Up @@ -649,10 +684,12 @@ export interface BitBucketSourceProps extends ThirdPartyGitSourceProps {
class BitBucketSource extends ThirdPartyGitSource {
public readonly type = BITBUCKET_SOURCE_TYPE;
private readonly httpsCloneUrl: any;
private readonly branchOrRef?: string;

constructor(props: BitBucketSourceProps) {
super(props);
this.httpsCloneUrl = `https://bitbucket.org/${props.owner}/${props.repo}.git`;
this.branchOrRef = props.branchOrRef;
}

public bind(_scope: Construct, _project: IProject): SourceConfig {
Expand All @@ -672,6 +709,7 @@ class BitBucketSource extends ThirdPartyGitSource {
...superConfig.sourceProperty,
location: this.httpsCloneUrl,
},
sourceVersion: this.branchOrRef,
buildTriggers: superConfig.buildTriggers,
};
}
Expand Down
65 changes: 65 additions & 0 deletions packages/@aws-cdk/aws-codebuild/test/test.codebuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,71 @@ export = {
},
},

'secondary source versions': {
'allow secondary source versions'(test: Test) {
const stack = new cdk.Stack();
const bucket = new s3.Bucket(stack, 'MyBucket');
const project = new codebuild.Project(stack, 'MyProject', {
source: codebuild.Source.s3({
bucket,
path: 'some/path',
}),
});

project.addSecondarySource(codebuild.Source.s3({
bucket,
path: 'another/path',
identifier: 'source1',
version: 'someversion'
}));

expect(stack).to(haveResourceLike('AWS::CodeBuild::Project', {
"SecondarySources": [
{
"SourceIdentifier": "source1",
"Type": "S3",
},
],
"SecondarySourceVersions": [
{
"SourceIdentifier": "source1",
"SourceVersion": "someversion"
}
]
}));

test.done();
},

'allow not to specify secondary source versions'(test: Test) {
const stack = new cdk.Stack();
const bucket = new s3.Bucket(stack, 'MyBucket');
const project = new codebuild.Project(stack, 'MyProject', {
source: codebuild.Source.s3({
bucket,
path: 'some/path',
}),
});

project.addSecondarySource(codebuild.Source.s3({
bucket,
path: 'another/path',
identifier: 'source1',
}));

expect(stack).to(haveResourceLike('AWS::CodeBuild::Project', {
"SecondarySources": [
{
"SourceIdentifier": "source1",
"Type": "S3",
},
]
}));

test.done();
},
},

'secondary artifacts': {
'require providing an identifier when creating a Project'(test: Test) {
const stack = new cdk.Stack();
Expand Down
85 changes: 85 additions & 0 deletions packages/@aws-cdk/aws-codebuild/test/test.project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,47 @@ export = {
test.done();
},

'can set a branch as the SourceVersion'(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new codebuild.Project(stack, 'Project', {
source: codebuild.Source.gitHub({
owner: 'testowner',
repo: 'testrepo',
branchOrRef: 'testbranch',
})
});

// THEN
expect(stack).to(haveResource('AWS::CodeBuild::Project', {
SourceVersion: 'testbranch',
}));

test.done();
},

'can set the SourceVersion for a gitHubEnterprise'(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new codebuild.Project(stack, 'Project', {
source: codebuild.Source.gitHubEnterprise({
httpsCloneUrl: 'https://mygithub-enterprise.com/myuser/myrepo',
branchOrRef: 'testbranch',
})
});

// THEN
expect(stack).to(haveResource('AWS::CodeBuild::Project', {
SourceVersion: 'testbranch',
}));

test.done();
},

'can explicitly set reportBuildStatus to false'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down Expand Up @@ -166,6 +207,27 @@ export = {
},
},

'project with bitbucket and SourceVersion'(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new codebuild.Project(stack, 'Project', {
source: codebuild.Source.bitBucket({
owner: 'testowner',
repo: 'testrepo',
branchOrRef: 'testbranch',
})
});

// THEN
expect(stack).to(haveResource('AWS::CodeBuild::Project', {
SourceVersion: 'testbranch',
}));

test.done();
},

'project with s3 cache bucket'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down Expand Up @@ -202,6 +264,29 @@ export = {
test.done();
},

's3 codebuild project with sourceVersion'(test: Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new codebuild.Project(stack, 'Project', {
source: codebuild.Source.s3({
bucket: new s3.Bucket(stack, 'Bucket'),
path: 'path',
version: 's3version'
}),
cache: codebuild.Cache.local(codebuild.LocalCacheMode.CUSTOM, codebuild.LocalCacheMode.DOCKER_LAYER,
codebuild.LocalCacheMode.SOURCE)
});

// THEN
expect(stack).to(haveResource('AWS::CodeBuild::Project', {
SourceVersion: 's3version',
}));

test.done();
},

'project with local cache modes'(test: Test) {
// GIVEN
const stack = new cdk.Stack();
Expand Down