diff --git a/packages/@aws-cdk/aws-codebuild/README.md b/packages/@aws-cdk/aws-codebuild/README.md index b0deca2a1033a..18a2c024f5006 100644 --- a/packages/@aws-cdk/aws-codebuild/README.md +++ b/packages/@aws-cdk/aws-codebuild/README.md @@ -213,6 +213,37 @@ The following example shows how to define an image from a private docker registr [Docker Registry example](./test/integ.docker-registry.lit.ts) +## Credentials + +CodeBuild allows you to store credentials used when communicating with various sources, +like GitHub: + +```typescript +new codebuild.GitHubSourceCredentials(this, 'CodeBuildGitHubCreds', { + accessToken: cdk.SecretValue.secretsManager('my-token'), +}); +// GitHub Enterprise is almost the same, +// except the class is called GitHubEnterpriseSourceCredentials +``` + +and BitBucket: + +```typescript +new codebuild.BitBucketSourceCredentials(this, 'CodeBuildBitBucketCreds', { + username: cdk.SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'username' }), + password: cdk.SecretValue.secretsManager('my-bitbucket-creds', { jsonField: 'password' }), +}); +``` + +**Note**: the credentials are global to a given account in a given region - +they are not defined per CodeBuild project. +CodeBuild only allows storing a single credential of a given type +(GitHub, GitHub Enterprise or BitBucket) +in a given account in a given region - +any attempt to save more than one will result in an error. +You can use the [`list-source-credentials` AWS CLI operation](https://docs.aws.amazon.com/cli/latest/reference/codebuild/list-source-credentials.html) +to inspect what credentials are stored in your account. + ## Events CodeBuild projects can be used either as a source for events or be triggered diff --git a/packages/@aws-cdk/aws-codebuild/lib/index.ts b/packages/@aws-cdk/aws-codebuild/lib/index.ts index f1409a3c456d9..7b1685ca66e41 100644 --- a/packages/@aws-cdk/aws-codebuild/lib/index.ts +++ b/packages/@aws-cdk/aws-codebuild/lib/index.ts @@ -2,6 +2,7 @@ export * from './events'; export * from './pipeline-project'; export * from './project'; export * from './source'; +export * from './source-credentials'; export * from './artifacts'; export * from './cache'; export * from './build-spec'; diff --git a/packages/@aws-cdk/aws-codebuild/lib/source-credentials.ts b/packages/@aws-cdk/aws-codebuild/lib/source-credentials.ts new file mode 100644 index 0000000000000..e2b180ec7036f --- /dev/null +++ b/packages/@aws-cdk/aws-codebuild/lib/source-credentials.ts @@ -0,0 +1,98 @@ +import { Construct, Resource, SecretValue } from '@aws-cdk/core'; +import { CfnSourceCredential } from './codebuild.generated'; + +/** + * Creation properties for {@link GitHubSourceCredentials}. + */ +export interface GitHubSourceCredentialsProps { + /** + * The personal access token to use when contacting the GitHub API. + */ + readonly accessToken: SecretValue; +} + +/** + * The source credentials used when contacting the GitHub API. + * + * **Note**: CodeBuild only allows a single credential for GitHub + * to be saved in a given AWS account in a given region - + * any attempt to add more than one will result in an error. + * + * @resource AWS::CodeBuild::SourceCredential + */ +export class GitHubSourceCredentials extends Resource { + constructor(scope: Construct, id: string, props: GitHubSourceCredentialsProps) { + super(scope, id); + + new CfnSourceCredential(scope, 'Resource', { + serverType: 'GITHUB', + authType: 'PERSONAL_ACCESS_TOKEN', + token: props.accessToken.toString(), + }); + } +} + +/** + * Creation properties for {@link GitHubEnterpriseSourceCredentials}. + */ +export interface GitHubEnterpriseSourceCredentialsProps { + /** + * The personal access token to use when contacting the + * instance of the GitHub Enterprise API. + */ + readonly accessToken: SecretValue; +} + +/** + * The source credentials used when contacting the GitHub Enterprise API. + * + * **Note**: CodeBuild only allows a single credential for GitHub Enterprise + * to be saved in a given AWS account in a given region - + * any attempt to add more than one will result in an error. + * + * @resource AWS::CodeBuild::SourceCredential + */ +export class GitHubEnterpriseSourceCredentials extends Resource { + constructor(scope: Construct, id: string, props: GitHubEnterpriseSourceCredentialsProps) { + super(scope, id); + + new CfnSourceCredential(scope, 'Resource', { + serverType: 'GITHUB_ENTERPRISE', + authType: 'PERSONAL_ACCESS_TOKEN', + token: props.accessToken.toString(), + }); + } +} + +/** + * Construction properties of {@link BitBucketSourceCredentials}. + */ +export interface BitBucketSourceCredentialsProps { + /** Your BitBucket username. */ + readonly username: SecretValue; + + /** Your BitBucket application password. */ + readonly password: SecretValue; +} + +/** + * The source credentials used when contacting the BitBucket API. + * + * **Note**: CodeBuild only allows a single credential for BitBucket + * to be saved in a given AWS account in a given region - + * any attempt to add more than one will result in an error. + * + * @resource AWS::CodeBuild::SourceCredential + */ +export class BitBucketSourceCredentials extends Resource { + constructor(scope: Construct, id: string, props: BitBucketSourceCredentialsProps) { + super(scope, id); + + new CfnSourceCredential(this, 'Resource', { + serverType: 'BITBUCKET', + authType: 'BASIC_AUTH', + username: props.username.toString(), + token: props.password.toString(), + }); + } +} diff --git a/packages/@aws-cdk/aws-codebuild/package.json b/packages/@aws-cdk/aws-codebuild/package.json index 44f820fcc6052..532f1fc4c3cc9 100644 --- a/packages/@aws-cdk/aws-codebuild/package.json +++ b/packages/@aws-cdk/aws-codebuild/package.json @@ -203,7 +203,10 @@ "docs-public-apis:@aws-cdk/aws-codebuild.S3SourceProps.path", "docs-public-apis:@aws-cdk/aws-codebuild.SourceConfig.sourceProperty", "docs-public-apis:@aws-cdk/aws-codebuild.SourceConfig.buildTriggers", - "props-default-doc:@aws-cdk/aws-codebuild.SourceConfig.buildTriggers" + "props-default-doc:@aws-cdk/aws-codebuild.SourceConfig.buildTriggers", + "props-physical-name:@aws-cdk/aws-codebuild.BitBucketSourceCredentialsProps", + "props-physical-name:@aws-cdk/aws-codebuild.GitHubSourceCredentialsProps", + "props-physical-name:@aws-cdk/aws-codebuild.GitHubEnterpriseSourceCredentialsProps" ] }, "stability": "stable" diff --git a/packages/@aws-cdk/aws-codebuild/test/test.project.ts b/packages/@aws-cdk/aws-codebuild/test/test.project.ts index 7aa22faf2d3f6..580cf94c33426 100644 --- a/packages/@aws-cdk/aws-codebuild/test/test.project.ts +++ b/packages/@aws-cdk/aws-codebuild/test/test.project.ts @@ -124,26 +124,6 @@ export = { 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(); @@ -205,27 +185,110 @@ export = { test.done(); }, + + 'can provide credentials to use with the source'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.GitHubSourceCredentials(stack, 'GitHubSourceCredentials', { + accessToken: cdk.SecretValue.plainText('my-access-token'), + }); + + // THEN + expect(stack).to(haveResource('AWS::CodeBuild::SourceCredential', { + "ServerType": "GITHUB", + "AuthType": "PERSONAL_ACCESS_TOKEN", + "Token": "my-access-token", + })); + + test.done(); + }, }, - 'project with bitbucket and SourceVersion'(test: Test) { - // GIVEN - const stack = new cdk.Stack(); + 'GitHub Enterprise source': { + 'can use branchOrRef to set the source version'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); - // WHEN - new codebuild.Project(stack, 'Project', { - source: codebuild.Source.bitBucket({ - owner: 'testowner', - repo: 'testrepo', - branchOrRef: 'testbranch', - }) - }); + // 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', - })); + // THEN + expect(stack).to(haveResource('AWS::CodeBuild::Project', { + SourceVersion: 'testbranch', + })); - test.done(); + test.done(); + }, + + 'can provide credentials to use with the source'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.GitHubEnterpriseSourceCredentials(stack, 'GitHubEnterpriseSourceCredentials', { + accessToken: cdk.SecretValue.plainText('my-access-token'), + }); + + // THEN + expect(stack).to(haveResource('AWS::CodeBuild::SourceCredential', { + "ServerType": "GITHUB_ENTERPRISE", + "AuthType": "PERSONAL_ACCESS_TOKEN", + "Token": "my-access-token", + })); + + test.done(); + }, + }, + + 'BitBucket source': { + 'can use branchOrRef to set the source version'(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(); + }, + + 'can provide credentials to use with the source'(test: Test) { + // GIVEN + const stack = new cdk.Stack(); + + // WHEN + new codebuild.BitBucketSourceCredentials(stack, 'BitBucketSourceCredentials', { + username: cdk.SecretValue.plainText('my-username'), + password: cdk.SecretValue.plainText('password'), + }); + + // THEN + expect(stack).to(haveResource('AWS::CodeBuild::SourceCredential', { + "ServerType": "BITBUCKET", + "AuthType": "BASIC_AUTH", + "Username": "my-username", + "Token": "password", + })); + + test.done(); + }, }, 'project with s3 cache bucket'(test: Test) { @@ -433,4 +496,4 @@ export = { test.done(); } -}; \ No newline at end of file +};