diff --git a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts index 2fa7a67b29b93..8f33d16ac8c41 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/lib/codecommit/source-action.ts @@ -2,7 +2,7 @@ import * as codecommit from '@aws-cdk/aws-codecommit'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; import * as targets from '@aws-cdk/aws-events-targets'; import * as iam from '@aws-cdk/aws-iam'; -import { Construct } from '@aws-cdk/core'; +import { Construct, Token } from '@aws-cdk/core'; import { Action } from '../action'; import { sourceArtifactBounds } from '../common'; @@ -122,8 +122,8 @@ export class CodeCommitSourceAction extends Action { const createEvent = this.props.trigger === undefined || this.props.trigger === CodeCommitTrigger.EVENTS; if (createEvent) { - const branchIdDisambiguator = this.branch === 'master' ? '' : `-${this.branch}-`; - this.props.repository.onCommit(`${stage.pipeline.node.uniqueId}${branchIdDisambiguator}EventRule`, { + const eventId = this.generateEventId(stage); + this.props.repository.onCommit(eventId, { target: new targets.CodePipeline(stage.pipeline), branches: [this.branch], }); @@ -153,4 +153,24 @@ export class CodeCommitSourceAction extends Action { }, }; } + + private generateEventId(stage: codepipeline.IStage): string { + const baseId = stage.pipeline.node.uniqueId; + if (Token.isUnresolved(this.branch)) { + let candidate = ''; + let counter = 0; + do { + candidate = this.eventIdFromPrefix(`${baseId}${counter}`); + counter += 1; + } while (this.props.repository.node.tryFindChild(candidate) !== undefined); + return candidate; + } else { + const branchIdDisambiguator = this.branch === 'master' ? '' : '-${this.branch}-'; + return this.eventIdFromPrefix(`${baseId}${branchIdDisambiguator}`); + } + } + + private eventIdFromPrefix(eventIdPrefix: string) { + return `${eventIdPrefix}EventRule`; + } } diff --git a/packages/@aws-cdk/aws-codepipeline-actions/test/codecommit/test.codecommit-source-action.ts b/packages/@aws-cdk/aws-codepipeline-actions/test/codecommit/test.codecommit-source-action.ts index e62e301168fa1..fda7c79dc1800 100644 --- a/packages/@aws-cdk/aws-codepipeline-actions/test/codecommit/test.codecommit-source-action.ts +++ b/packages/@aws-cdk/aws-codepipeline-actions/test/codecommit/test.codecommit-source-action.ts @@ -2,7 +2,7 @@ import { countResources, expect, haveResourceLike, not } from '@aws-cdk/assert'; import * as codebuild from '@aws-cdk/aws-codebuild'; import * as codecommit from '@aws-cdk/aws-codecommit'; import * as codepipeline from '@aws-cdk/aws-codepipeline'; -import { Stack } from '@aws-cdk/core'; +import { Stack, Lazy } from '@aws-cdk/core'; import { Test } from 'nodeunit'; import * as cpactions from '../../lib'; @@ -224,6 +224,49 @@ export = { test.done(); }, + + 'allows using a Token for the branch name'(test: Test) { + const stack = new Stack(); + + const sourceOutput = new codepipeline.Artifact(); + new codepipeline.Pipeline(stack, 'P', { + stages: [ + { + stageName: 'Source', + actions: [ + new cpactions.CodeCommitSourceAction({ + actionName: 'CodeCommit', + repository: new codecommit.Repository(stack, 'R', { + repositoryName: 'repository', + }), + branch: Lazy.stringValue({ produce: () => 'my-branch' }), + output: sourceOutput, + }), + ], + }, + { + stageName: 'Build', + actions: [ + new cpactions.CodeBuildAction({ + actionName: 'Build', + project: new codebuild.PipelineProject(stack, 'CodeBuild'), + input: sourceOutput, + }), + ], + }, + ], + }); + + expect(stack).to(haveResourceLike('AWS::Events::Rule', { + EventPattern: { + detail: { + referenceName: ['my-branch'], + }, + }, + })); + + test.done(); + }, }, };