From 103c1449683ffc131b696faff8b16f0935a3c3f4 Mon Sep 17 00:00:00 2001 From: Adam Ruka Date: Mon, 1 Jun 2020 19:08:00 -0700 Subject: [PATCH] fix(codepipeline): allow multiple CodeCommit source actions using events (#8018) There are use-cases when you want to add the same CodeCommit repository to a CodePipeline multiple times, with different branches. This wouldn't work when using CloudWatch Events to trigger the pipeline, as the ID of the generated Event only used the pipeline ID for uniqueness. Change it to also use the branch name when generating the Event ID (which cannot be empty, as it turns out, so validate that as well). Fixes #7802 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../lib/codecommit/source-action.ts | 8 ++- .../test.codecommit-source-action.ts | 60 +++++++++++++++++++ 2 files changed, 66 insertions(+), 2 deletions(-) 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 caaa5ee3ed174..2fa7a67b29b93 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 @@ -87,7 +87,10 @@ export class CodeCommitSourceAction extends Action { private readonly props: CodeCommitSourceActionProps; constructor(props: CodeCommitSourceActionProps) { - const branch = props.branch || 'master'; + const branch = props.branch ?? 'master'; + if (!branch) { + throw new Error("'branch' parameter cannot be an empty string"); + } super({ ...props, @@ -119,7 +122,8 @@ export class CodeCommitSourceAction extends Action { const createEvent = this.props.trigger === undefined || this.props.trigger === CodeCommitTrigger.EVENTS; if (createEvent) { - this.props.repository.onCommit(stage.pipeline.node.uniqueId + 'EventRule', { + const branchIdDisambiguator = this.branch === 'master' ? '' : `-${this.branch}-`; + this.props.repository.onCommit(`${stage.pipeline.node.uniqueId}${branchIdDisambiguator}EventRule`, { target: new targets.CodePipeline(stage.pipeline), branches: [this.branch], }); 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 33f0d72bca24d..0650c50f2b596 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 @@ -110,6 +110,66 @@ export = { test.done(); }, + 'cannot be created with an empty branch'(test: Test) { + const stack = new Stack(); + const repo = new codecommit.Repository(stack, 'MyRepo', { + repositoryName: 'my-repo', + }); + + test.throws(() => { + new cpactions.CodeCommitSourceAction({ + actionName: 'Source2', + repository: repo, + output: new codepipeline.Artifact(), + branch: '', + }); + }, /'branch' parameter cannot be an empty string/); + + test.done(); + }, + + 'allows using the same repository multiple times with different branches when trigger=EVENTS'(test: Test) { + const stack = new Stack(); + + const repo = new codecommit.Repository(stack, 'MyRepo', { + repositoryName: 'my-repo', + }); + const sourceOutput1 = new codepipeline.Artifact(); + const sourceOutput2 = new codepipeline.Artifact(); + new codepipeline.Pipeline(stack, 'MyPipeline', { + stages: [ + { + stageName: 'Source', + actions: [ + new cpactions.CodeCommitSourceAction({ + actionName: 'Source1', + repository: repo, + output: sourceOutput1, + }), + new cpactions.CodeCommitSourceAction({ + actionName: 'Source2', + repository: repo, + output: sourceOutput2, + branch: 'develop', + }), + ], + }, + { + stageName: 'Build', + actions: [ + new cpactions.CodeBuildAction({ + actionName: 'Build', + project: new codebuild.PipelineProject(stack, 'MyProject'), + input: sourceOutput1, + }), + ], + }, + ], + }); + + test.done(); + }, + 'exposes variables for other actions to consume'(test: Test) { const stack = new Stack();