From 5ce1b6485eb4336634f4f14bfe3d0b17b071e83b Mon Sep 17 00:00:00 2001 From: "k.goto" <24818752+go-to-k@users.noreply.github.com> Date: Tue, 14 May 2024 06:38:03 +0900 Subject: [PATCH] feat(codepipeline): `GitPullRequestFilter` for pipeline trigger (#29128) ### Issue # (if applicable) Closes #29126. Related PR: https://github.com/aws/aws-cdk/pull/29127 Perhaps if one merges, the other will cause a conflict. ### Reason for this change We would be good to trigger pipelines by git pull request filters. - CFn and API docs - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codepipeline-pipeline-gitconfiguration.html - https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codepipeline-pipeline-gitpullrequestfilter.html - https://docs.aws.amazon.com/codepipeline/latest/APIReference/API_GitPullRequestFilter.html ### Description of changes Add `gitPullRequestFilter` parameter with new interface into `GitConfiguration` interface. ### Description of how you validated changes Both unit and integ tests. ### Checklist - [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md) ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../index.js | 16 +- ...ipeline-with-pipeline-triggers.assets.json | 4 +- ...eline-with-pipeline-triggers.template.json | 768 ++++++++++- ...efaultTestDeployAssertE3F8DDE6.assets.json | 10 +- ...aultTestDeployAssertE3F8DDE6.template.json | 46 +- .../manifest.json | 100 +- .../tree.json | 1136 ++++++++++++++++- .../integ.pipeline-with-pipeline-triggers.ts | 73 +- .../aws-cdk-lib/aws-codepipeline/README.md | 123 +- .../aws-codepipeline/lib/trigger.ts | 182 ++- .../aws-codepipeline/test/triggers.test.ts | 606 ++++++++- 11 files changed, 3011 insertions(+), 53 deletions(-) rename packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/{asset.3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.bundle => asset.310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.bundle}/index.js (99%) diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/asset.3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.bundle/index.js b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/asset.310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.bundle/index.js similarity index 99% rename from packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/asset.3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.bundle/index.js rename to packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/asset.310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.bundle/index.js index c13d3dc96a272..58396e8540522 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/asset.3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.bundle/index.js +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/asset.310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.bundle/index.js @@ -14732,9 +14732,11 @@ var require_runtimeConfig_shared = __commonJS({ // ../../../node_modules/@smithy/util-defaults-mode-node/dist-cjs/index.js var require_dist_cjs45 = __commonJS({ "../../../node_modules/@smithy/util-defaults-mode-node/dist-cjs/index.js"(exports2, module2) { + var __create2 = Object.create; var __defProp2 = Object.defineProperty; var __getOwnPropDesc2 = Object.getOwnPropertyDescriptor; var __getOwnPropNames2 = Object.getOwnPropertyNames; + var __getProtoOf2 = Object.getPrototypeOf; var __hasOwnProp2 = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp2(target, "name", { value, configurable: true }); var __export2 = (target, all) => { @@ -14749,6 +14751,14 @@ var require_dist_cjs45 = __commonJS({ } return to; }; + var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps2( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp2(target, "default", { value: mod, enumerable: true }) : target, + mod + )); var __toCommonJS2 = (mod) => __copyProps2(__defProp2({}, "__esModule", { value: true }), mod); var src_exports = {}; __export2(src_exports, { @@ -14756,7 +14766,6 @@ var require_dist_cjs45 = __commonJS({ }); module2.exports = __toCommonJS2(src_exports); var import_config_resolver = require_dist_cjs21(); - var import_credential_provider_imds = require_dist_cjs40(); var import_node_config_provider = require_dist_cjs24(); var import_property_provider = require_dist_cjs6(); var AWS_EXECUTION_ENV = "AWS_EXECUTION_ENV"; @@ -14819,8 +14828,9 @@ var require_dist_cjs45 = __commonJS({ } if (!process.env[ENV_IMDS_DISABLED]) { try { - const endpoint = await (0, import_credential_provider_imds.getInstanceMetadataEndpoint)(); - return (await (0, import_credential_provider_imds.httpRequest)({ ...endpoint, path: IMDS_REGION_PATH })).toString(); + const { getInstanceMetadataEndpoint, httpRequest } = await Promise.resolve().then(() => __toESM2(require_dist_cjs40())); + const endpoint = await getInstanceMetadataEndpoint(); + return (await httpRequest({ ...endpoint, path: IMDS_REGION_PATH })).toString(); } catch (e) { } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.assets.json index a450558752a19..eb92d27df5797 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.assets.json @@ -1,7 +1,7 @@ { "version": "36.0.0", "files": { - "cc3950730a8132436f16f7e744268033b6fe8ab56ffa886b0e6ba03f7baf97ac": { + "46609a0e4b8f4edd1db7fc09828756c229845a1f17b53c56562a9f7eb4ea6b30": { "source": { "path": "aws-cdk-codepipeline-with-pipeline-triggers.template.json", "packaging": "file" @@ -9,7 +9,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "cc3950730a8132436f16f7e744268033b6fe8ab56ffa886b0e6ba03f7baf97ac.json", + "objectKey": "46609a0e4b8f4edd1db7fc09828756c229845a1f17b53c56562a9f7eb4ea6b30.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.template.json index a346fb28e3dd2..577f1d2a091d7 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/aws-cdk-codepipeline-with-pipeline-triggers.template.json @@ -476,7 +476,7 @@ }, "Configuration": { "ConnectionArn": "MOCK", - "FullRepositoryId": "go-to-k/cdk-pipelines-demo", + "FullRepositoryId": "go-to-k/cdk-codepipeline-demo-1", "BranchName": "master" }, "Name": "CodeStarConnectionsSourceAction", @@ -751,6 +751,772 @@ } ] } + }, + "MyProject2Role640CD8C0": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "MyProject2RoleDefaultPolicyF6082200": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "MyProject2B52B17CC" + }, + ":*" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "MyProject2B52B17CC" + } + ] + ] + } + ] + }, + { + "Action": [ + "codebuild:BatchPutCodeCoverages", + "codebuild:BatchPutTestCases", + "codebuild:CreateReport", + "codebuild:CreateReportGroup", + "codebuild:UpdateReport" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codebuild:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":report-group/", + { + "Ref": "MyProject2B52B17CC" + }, + "-*" + ] + ] + } + }, + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyProject2RoleDefaultPolicyF6082200", + "Roles": [ + { + "Ref": "MyProject2Role640CD8C0" + } + ] + } + }, + "MyProject2B52B17CC": { + "Type": "AWS::CodeBuild::Project", + "Properties": { + "Artifacts": { + "Type": "CODEPIPELINE" + }, + "Cache": { + "Type": "NO_CACHE" + }, + "EncryptionKey": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + }, + "Environment": { + "ComputeType": "BUILD_GENERAL1_SMALL", + "Image": "aws/codebuild/standard:1.0", + "ImagePullCredentialsType": "CODEBUILD", + "PrivilegedMode": false, + "Type": "LINUX_CONTAINER" + }, + "ServiceRole": { + "Fn::GetAtt": [ + "MyProject2Role640CD8C0", + "Arn" + ] + }, + "Source": { + "Type": "CODEPIPELINE" + } + } + }, + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2": { + "Type": "AWS::KMS::Key", + "Properties": { + "KeyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Pipeline2ArtifactsBucketEncryptionKeyAlias4C3D138C": { + "Type": "AWS::KMS::Alias", + "Properties": { + "AliasName": "alias/codepipeline-aws-cdk-codepipeline-with-pipeline-triggers-pipeline2-a7cdfc85", + "TargetKeyId": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + }, + "Pipeline2ArtifactsBucketBBAC8B82": { + "Type": "AWS::S3::Bucket", + "Properties": { + "BucketEncryption": { + "ServerSideEncryptionConfiguration": [ + { + "ServerSideEncryptionByDefault": { + "KMSMasterKeyID": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + }, + "SSEAlgorithm": "aws:kms" + } + } + ] + }, + "PublicAccessBlockConfiguration": { + "BlockPublicAcls": true, + "BlockPublicPolicy": true, + "IgnorePublicAcls": true, + "RestrictPublicBuckets": true + } + }, + "UpdateReplacePolicy": "Retain", + "DeletionPolicy": "Retain" + }, + "Pipeline2ArtifactsBucketPolicyB3F6A84F": { + "Type": "AWS::S3::BucketPolicy", + "Properties": { + "Bucket": { + "Ref": "Pipeline2ArtifactsBucketBBAC8B82" + }, + "PolicyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "Pipeline2RoleB1668F7C": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codepipeline.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "Pipeline2RoleDefaultPolicy3CA7A97C": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F", + "Arn" + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "Pipeline2RoleDefaultPolicy3CA7A97C", + "Roles": [ + { + "Ref": "Pipeline2RoleB1668F7C" + } + ] + } + }, + "Pipeline27E937D7F": { + "Type": "AWS::CodePipeline::Pipeline", + "Properties": { + "ArtifactStore": { + "EncryptionKey": { + "Id": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + }, + "Type": "KMS" + }, + "Location": { + "Ref": "Pipeline2ArtifactsBucketBBAC8B82" + }, + "Type": "S3" + }, + "Name": "my-pipeline2", + "PipelineType": "V2", + "RoleArn": { + "Fn::GetAtt": [ + "Pipeline2RoleB1668F7C", + "Arn" + ] + }, + "Stages": [ + { + "Actions": [ + { + "ActionTypeId": { + "Category": "Source", + "Owner": "AWS", + "Provider": "CodeStarSourceConnection", + "Version": "1" + }, + "Configuration": { + "ConnectionArn": "MOCK", + "FullRepositoryId": "go-to-k/cdk-codepipeline-demo-2", + "BranchName": "master" + }, + "Name": "CodeStarConnectionsSourceAction2", + "Namespace": "Source_CodeStarConnectionsSourceAction2_NS", + "OutputArtifacts": [ + { + "Name": "Artifact_Source_CodeStarConnectionsSourceAction2" + } + ], + "RoleArn": { + "Fn::GetAtt": [ + "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F", + "Arn" + ] + }, + "RunOrder": 1 + } + ], + "Name": "Source" + }, + { + "Actions": [ + { + "ActionTypeId": { + "Category": "Build", + "Owner": "AWS", + "Provider": "CodeBuild", + "Version": "1" + }, + "Configuration": { + "ProjectName": { + "Ref": "MyProject2B52B17CC" + }, + "EnvironmentVariables": "[{\"name\":\"CommitId\",\"type\":\"PLAINTEXT\",\"value\":\"#{Source_CodeStarConnectionsSourceAction2_NS.CommitId}\"}]" + }, + "InputArtifacts": [ + { + "Name": "Artifact_Source_CodeStarConnectionsSourceAction2" + } + ], + "Name": "CodeBuild2", + "OutputArtifacts": [ + { + "Name": "Artifact_Build_CodeBuild2" + } + ], + "RoleArn": { + "Fn::GetAtt": [ + "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5", + "Arn" + ] + }, + "RunOrder": 1 + } + ], + "Name": "Build" + } + ], + "Triggers": [ + { + "GitConfiguration": { + "PullRequest": [ + { + "Branches": { + "Excludes": [ + "exclude1", + "exclude2" + ], + "Includes": [ + "include1", + "include2" + ] + }, + "Events": [ + "OPEN", + "UPDATED" + ], + "FilePaths": { + "Excludes": [ + "/path/to/exclude1", + "/path/to/exclude2" + ], + "Includes": [ + "/path/to/include1", + "/path/to/include2" + ] + } + } + ], + "SourceActionName": "CodeStarConnectionsSourceAction2" + }, + "ProviderType": "CodeStarSourceConnection" + } + ] + }, + "DependsOn": [ + "Pipeline2RoleDefaultPolicy3CA7A97C", + "Pipeline2RoleB1668F7C" + ] + }, + "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleDefaultPolicy17D58BB8": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "codestar-connections:UseConnection", + "Effect": "Allow", + "Resource": "MOCK" + }, + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + }, + { + "Action": [ + "s3:PutObjectAcl", + "s3:PutObjectVersionAcl" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleDefaultPolicy17D58BB8", + "Roles": [ + { + "Ref": "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F" + } + ] + } + }, + "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "Pipeline2BuildCodeBuild2CodePipelineActionRoleDefaultPolicyC4BEA3E8": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyProject2B52B17CC", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "Pipeline2BuildCodeBuild2CodePipelineActionRoleDefaultPolicyC4BEA3E8", + "Roles": [ + { + "Ref": "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5" + } + ] + } } }, "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.assets.json index 108f9418e9040..f0bf2438e6953 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.assets.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.assets.json @@ -1,20 +1,20 @@ { "version": "36.0.0", "files": { - "3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4": { + "310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17": { "source": { - "path": "asset.3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.bundle", + "path": "asset.310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.bundle", "packaging": "zip" }, "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.zip", + "objectKey": "310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.zip", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } }, - "2d2d44e46f4e0aef0cb5ef2e01530b6d89f5a740da1aada5bcefdc40698646ae": { + "afb3c70e7721b9ac91e2b1f83ab4b4510bdfa7a1f7677d8c217ddd2348f4d224": { "source": { "path": "codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.template.json", "packaging": "file" @@ -22,7 +22,7 @@ "destinations": { "current_account-current_region": { "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", - "objectKey": "2d2d44e46f4e0aef0cb5ef2e01530b6d89f5a740da1aada5bcefdc40698646ae.json", + "objectKey": "afb3c70e7721b9ac91e2b1f83ab4b4510bdfa7a1f7677d8c217ddd2348f4d224.json", "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.template.json index 62d36314ce05a..a23bad1b69491 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.template.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/codepipelinewithpipelinetriggerstestDefaultTestDeployAssertE3F8DDE6.template.json @@ -20,7 +20,7 @@ "outputPaths": [ "pipeline.name" ], - "salt": "1707043774596" + "salt": "1708619218938" }, "UpdateReplacePolicy": "Delete", "DeletionPolicy": "Delete" @@ -51,6 +51,15 @@ "PolicyDocument": { "Version": "2012-10-17", "Statement": [ + { + "Action": [ + "codepipeline:GetPipeline" + ], + "Effect": "Allow", + "Resource": [ + "*" + ] + }, { "Action": [ "codepipeline:GetPipeline" @@ -74,7 +83,7 @@ "S3Bucket": { "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" }, - "S3Key": "3f0f15596be1e3fbbf4a0571522aa1e5312d44abff27360f8d043c1b0704bcf4.zip" + "S3Key": "310f432b946edeef3316f39f32b344b6bdc401a3b438433db42adadab1bf5e17.zip" }, "Timeout": 120, "Handler": "index.handler", @@ -85,6 +94,31 @@ ] } } + }, + "AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2": { + "Type": "Custom::DeployAssert@SdkCallCodePipelinegetPipeline", + "Properties": { + "ServiceToken": { + "Fn::GetAtt": [ + "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F", + "Arn" + ] + }, + "service": "CodePipeline", + "api": "getPipeline", + "expected": "{\"$StringLike\":\"my-pipeline2\"}", + "actualPath": "pipeline.name", + "parameters": { + "name": "\"my-pipeline2\"" + }, + "flattenResponse": "true", + "outputPaths": [ + "pipeline.name" + ], + "salt": "1708619218938" + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" } }, "Outputs": { @@ -95,6 +129,14 @@ "assertion" ] } + }, + "AssertionResultsAwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2": { + "Value": { + "Fn::GetAtt": [ + "AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2", + "assertion" + ] + } } }, "Parameters": { diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/manifest.json index 01309daa296c2..8c2671ef769e2 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/manifest.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/manifest.json @@ -18,7 +18,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/cc3950730a8132436f16f7e744268033b6fe8ab56ffa886b0e6ba03f7baf97ac.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/46609a0e4b8f4edd1db7fc09828756c229845a1f17b53c56562a9f7eb4ea6b30.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -118,6 +118,90 @@ "data": "PipelineBuildCodeBuildCodePipelineActionRoleDefaultPolicyD9C4A2F6" } ], + "/aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyProject2Role640CD8C0" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyProject2RoleDefaultPolicyF6082200" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyProject2B52B17CC" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucketEncryptionKey/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2ArtifactsBucketEncryptionKey9C275DF2" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucketEncryptionKeyAlias/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2ArtifactsBucketEncryptionKeyAlias4C3D138C" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucket/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2ArtifactsBucketBBAC8B82" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucket/Policy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2ArtifactsBucketPolicyB3F6A84F" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2RoleB1668F7C" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2RoleDefaultPolicy3CA7A97C" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline27E937D7F" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleDefaultPolicy17D58BB8" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5" + } + ], + "/aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole/DefaultPolicy/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "Pipeline2BuildCodeBuild2CodePipelineActionRoleDefaultPolicyC4BEA3E8" + } + ], "/aws-cdk-codepipeline-with-pipeline-triggers/BootstrapVersion": [ { "type": "aws:cdk:logicalId", @@ -150,7 +234,7 @@ "validateOnSynth": false, "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", - "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/2d2d44e46f4e0aef0cb5ef2e01530b6d89f5a740da1aada5bcefdc40698646ae.json", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/afb3c70e7721b9ac91e2b1f83ab4b4510bdfa7a1f7677d8c217ddd2348f4d224.json", "requiresBootstrapStackVersion": 6, "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", "additionalDependencies": [ @@ -190,6 +274,18 @@ "data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F" } ], + "/codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/Default/Default": [ + { + "type": "aws:cdk:logicalId", + "data": "AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2" + } + ], + "/codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/AssertionResults": [ + { + "type": "aws:cdk:logicalId", + "data": "AssertionResultsAwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2" + } + ], "/codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/BootstrapVersion": [ { "type": "aws:cdk:logicalId", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/tree.json index 9bd4034087897..752065a296d5e 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/tree.json +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.js.snapshot/tree.json @@ -670,7 +670,7 @@ }, "configuration": { "ConnectionArn": "MOCK", - "FullRepositoryId": "go-to-k/cdk-pipelines-demo", + "FullRepositoryId": "go-to-k/cdk-codepipeline-demo-1", "BranchName": "master" }, "runOrder": 1, @@ -1074,6 +1074,1086 @@ "version": "10.3.0" } }, + "MyProject2": { + "id": "MyProject2", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2", + "children": { + "Role": { + "id": "Role", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role/ImportRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codebuild.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "logs:CreateLogGroup", + "logs:CreateLogStream", + "logs:PutLogEvents" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "MyProject2B52B17CC" + }, + ":*" + ] + ] + }, + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":logs:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":log-group:/aws/codebuild/", + { + "Ref": "MyProject2B52B17CC" + } + ] + ] + } + ] + }, + { + "Action": [ + "codebuild:BatchPutCodeCoverages", + "codebuild:BatchPutTestCases", + "codebuild:CreateReport", + "codebuild:CreateReportGroup", + "codebuild:UpdateReport" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":codebuild:", + { + "Ref": "AWS::Region" + }, + ":", + { + "Ref": "AWS::AccountId" + }, + ":report-group/", + { + "Ref": "MyProject2B52B17CC" + }, + "-*" + ] + ] + } + }, + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "MyProject2RoleDefaultPolicyF6082200", + "roles": [ + { + "Ref": "MyProject2Role640CD8C0" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/MyProject2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodeBuild::Project", + "aws:cdk:cloudformation:props": { + "artifacts": { + "type": "CODEPIPELINE" + }, + "cache": { + "type": "NO_CACHE" + }, + "encryptionKey": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + }, + "environment": { + "type": "LINUX_CONTAINER", + "image": "aws/codebuild/standard:1.0", + "imagePullCredentialsType": "CODEBUILD", + "privilegedMode": false, + "computeType": "BUILD_GENERAL1_SMALL" + }, + "serviceRole": { + "Fn::GetAtt": [ + "MyProject2Role640CD8C0", + "Arn" + ] + }, + "source": { + "type": "CODEPIPELINE" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Pipeline2": { + "id": "Pipeline2", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2", + "children": { + "ArtifactsBucketEncryptionKey": { + "id": "ArtifactsBucketEncryptionKey", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucketEncryptionKey", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucketEncryptionKey/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Key", + "aws:cdk:cloudformation:props": { + "keyPolicy": { + "Statement": [ + { + "Action": "kms:*", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + }, + "Resource": "*" + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "ArtifactsBucketEncryptionKeyAlias": { + "id": "ArtifactsBucketEncryptionKeyAlias", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucketEncryptionKeyAlias", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucketEncryptionKeyAlias/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::KMS::Alias", + "aws:cdk:cloudformation:props": { + "aliasName": "alias/codepipeline-aws-cdk-codepipeline-with-pipeline-triggers-pipeline2-a7cdfc85", + "targetKeyId": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "ArtifactsBucket": { + "id": "ArtifactsBucket", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucket", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucket/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::Bucket", + "aws:cdk:cloudformation:props": { + "bucketEncryption": { + "serverSideEncryptionConfiguration": [ + { + "serverSideEncryptionByDefault": { + "sseAlgorithm": "aws:kms", + "kmsMasterKeyId": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + } + } + ] + }, + "publicAccessBlockConfiguration": { + "blockPublicAcls": true, + "blockPublicPolicy": true, + "ignorePublicAcls": true, + "restrictPublicBuckets": true + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Policy": { + "id": "Policy", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucket/Policy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/ArtifactsBucket/Policy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::S3::BucketPolicy", + "aws:cdk:cloudformation:props": { + "bucket": { + "Ref": "Pipeline2ArtifactsBucketBBAC8B82" + }, + "policyDocument": { + "Statement": [ + { + "Action": "s3:*", + "Condition": { + "Bool": { + "aws:SecureTransport": "false" + } + }, + "Effect": "Deny", + "Principal": { + "AWS": "*" + }, + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Role": { + "id": "Role", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role", + "children": { + "ImportRole": { + "id": "ImportRole", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role/ImportRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "codepipeline.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Role/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + }, + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5", + "Arn" + ] + }, + { + "Fn::GetAtt": [ + "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F", + "Arn" + ] + } + ] + } + ], + "Version": "2012-10-17" + }, + "policyName": "Pipeline2RoleDefaultPolicy3CA7A97C", + "roles": [ + { + "Ref": "Pipeline2RoleB1668F7C" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CodePipeline::Pipeline", + "aws:cdk:cloudformation:props": { + "artifactStore": { + "type": "S3", + "location": { + "Ref": "Pipeline2ArtifactsBucketBBAC8B82" + }, + "encryptionKey": { + "type": "KMS", + "id": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + } + }, + "name": "my-pipeline2", + "pipelineType": "V2", + "roleArn": { + "Fn::GetAtt": [ + "Pipeline2RoleB1668F7C", + "Arn" + ] + }, + "stages": [ + { + "name": "Source", + "actions": [ + { + "name": "CodeStarConnectionsSourceAction2", + "outputArtifacts": [ + { + "name": "Artifact_Source_CodeStarConnectionsSourceAction2" + } + ], + "actionTypeId": { + "category": "Source", + "version": "1", + "owner": "AWS", + "provider": "CodeStarSourceConnection" + }, + "configuration": { + "ConnectionArn": "MOCK", + "FullRepositoryId": "go-to-k/cdk-codepipeline-demo-2", + "BranchName": "master" + }, + "runOrder": 1, + "roleArn": { + "Fn::GetAtt": [ + "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F", + "Arn" + ] + }, + "namespace": "Source_CodeStarConnectionsSourceAction2_NS" + } + ] + }, + { + "name": "Build", + "actions": [ + { + "name": "CodeBuild2", + "inputArtifacts": [ + { + "name": "Artifact_Source_CodeStarConnectionsSourceAction2" + } + ], + "outputArtifacts": [ + { + "name": "Artifact_Build_CodeBuild2" + } + ], + "actionTypeId": { + "category": "Build", + "version": "1", + "owner": "AWS", + "provider": "CodeBuild" + }, + "configuration": { + "ProjectName": { + "Ref": "MyProject2B52B17CC" + }, + "EnvironmentVariables": "[{\"name\":\"CommitId\",\"type\":\"PLAINTEXT\",\"value\":\"#{Source_CodeStarConnectionsSourceAction2_NS.CommitId}\"}]" + }, + "runOrder": 1, + "roleArn": { + "Fn::GetAtt": [ + "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5", + "Arn" + ] + } + } + ] + } + ], + "triggers": [ + { + "gitConfiguration": { + "pullRequest": [ + { + "branches": { + "excludes": [ + "exclude1", + "exclude2" + ], + "includes": [ + "include1", + "include2" + ] + }, + "filePaths": { + "excludes": [ + "/path/to/exclude1", + "/path/to/exclude2" + ], + "includes": [ + "/path/to/include1", + "/path/to/include2" + ] + }, + "events": [ + "OPEN", + "UPDATED" + ] + } + ], + "sourceActionName": "CodeStarConnectionsSourceAction2" + }, + "providerType": "CodeStarSourceConnection" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Source": { + "id": "Source", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source", + "children": { + "CodeStarConnectionsSourceAction2": { + "id": "CodeStarConnectionsSourceAction2", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2", + "children": { + "CodePipelineActionRole": { + "id": "CodePipelineActionRole", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole", + "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Source/CodeStarConnectionsSourceAction2/CodePipelineActionRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": "codestar-connections:UseConnection", + "Effect": "Allow", + "Resource": "MOCK" + }, + { + "Action": [ + "s3:Abort*", + "s3:DeleteObject*", + "s3:GetBucket*", + "s3:GetObject*", + "s3:List*", + "s3:PutObject", + "s3:PutObjectLegalHold", + "s3:PutObjectRetention", + "s3:PutObjectTagging", + "s3:PutObjectVersionTagging" + ], + "Effect": "Allow", + "Resource": [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + ] + }, + { + "Action": [ + "kms:Decrypt", + "kms:DescribeKey", + "kms:Encrypt", + "kms:GenerateDataKey*", + "kms:ReEncrypt*" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketEncryptionKey9C275DF2", + "Arn" + ] + } + }, + { + "Action": [ + "s3:PutObjectAcl", + "s3:PutObjectVersionAcl" + ], + "Effect": "Allow", + "Resource": { + "Fn::Join": [ + "", + [ + { + "Fn::GetAtt": [ + "Pipeline2ArtifactsBucketBBAC8B82", + "Arn" + ] + }, + "/*" + ] + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleDefaultPolicy17D58BB8", + "roles": [ + { + "Ref": "Pipeline2SourceCodeStarConnectionsSourceAction2CodePipelineActionRoleD7F9366F" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Build": { + "id": "Build", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build", + "children": { + "CodeBuild2": { + "id": "CodeBuild2", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2", + "children": { + "CodePipelineActionRole": { + "id": "CodePipelineActionRole", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole", + "children": { + "ImportCodePipelineActionRole": { + "id": "ImportCodePipelineActionRole", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole/ImportCodePipelineActionRole", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "AWS": { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::", + { + "Ref": "AWS::AccountId" + }, + ":root" + ] + ] + } + } + } + ], + "Version": "2012-10-17" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DefaultPolicy": { + "id": "DefaultPolicy", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole/DefaultPolicy", + "children": { + "Resource": { + "id": "Resource", + "path": "aws-cdk-codepipeline-with-pipeline-triggers/Pipeline2/Build/CodeBuild2/CodePipelineActionRole/DefaultPolicy/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Policy", + "aws:cdk:cloudformation:props": { + "policyDocument": { + "Statement": [ + { + "Action": [ + "codebuild:BatchGetBuilds", + "codebuild:StartBuild", + "codebuild:StopBuild" + ], + "Effect": "Allow", + "Resource": { + "Fn::GetAtt": [ + "MyProject2B52B17CC", + "Arn" + ] + } + } + ], + "Version": "2012-10-17" + }, + "policyName": "Pipeline2BuildCodeBuild2CodePipelineActionRoleDefaultPolicyC4BEA3E8", + "roles": [ + { + "Ref": "Pipeline2BuildCodeBuild2CodePipelineActionRoleEAEC3BA5" + } + ] + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "aws-cdk-codepipeline-with-pipeline-triggers/BootstrapVersion", @@ -1204,6 +2284,60 @@ "version": "10.3.0" } }, + "AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2": { + "id": "AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2", + "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2", + "children": { + "SdkProvider": { + "id": "SdkProvider", + "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/SdkProvider", + "children": { + "AssertionsProvider": { + "id": "AssertionsProvider", + "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/SdkProvider/AssertionsProvider", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.AssertionsProvider", + "version": "0.0.0" + } + }, + "Default": { + "id": "Default", + "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/Default", + "children": { + "Default": { + "id": "Default", + "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/Default/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "AssertionResults": { + "id": "AssertionResults", + "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/AwsApiCallCodePipelinegetPipeline1c275ca65933c3cecd335e67fe9182e2/AssertionResults", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.AwsApiCall", + "version": "0.0.0" + } + }, "BootstrapVersion": { "id": "BootstrapVersion", "path": "codepipeline-with-pipeline-triggers-test/DefaultTest/DeployAssert/BootstrapVersion", diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.ts index 840be49ac4294..bcb5253361bc5 100644 --- a/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.ts +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-codepipeline-actions/test/integ.pipeline-with-pipeline-triggers.ts @@ -14,15 +14,16 @@ if (connectionArn === 'MOCK') { cdk.Annotations.of(stack).addWarningV2('integ:connection-arn', 'You must specify a valid connection ARN in the CONNECTION_ARN environment variable'); } -const sourceOutput = new codepipeline.Artifact(); -const sourceAction = new cpactions.CodeStarConnectionsSourceAction({ +const sourceOutput1 = new codepipeline.Artifact(); +const sourceAction1 = new cpactions.CodeStarConnectionsSourceAction({ actionName: 'CodeStarConnectionsSourceAction', - output: sourceOutput, + output: sourceOutput1, connectionArn, owner: 'go-to-k', - repo: 'cdk-pipelines-demo', + repo: 'cdk-codepipeline-demo-1', }); +// for push filter with tags new codepipeline.Pipeline(stack, 'Pipeline', { pipelineName: 'my-pipeline', pipelineType: codepipeline.PipelineType.V2, @@ -30,7 +31,7 @@ new codepipeline.Pipeline(stack, 'Pipeline', { stages: [ { stageName: 'Source', - actions: [sourceAction], + actions: [sourceAction1], }, { stageName: 'Build', @@ -38,10 +39,10 @@ new codepipeline.Pipeline(stack, 'Pipeline', { new cpactions.CodeBuildAction({ actionName: 'CodeBuild', project: new codebuild.PipelineProject(stack, 'MyProject'), - input: sourceOutput, + input: sourceOutput1, outputs: [new codepipeline.Artifact()], environmentVariables: { - CommitId: { value: sourceAction.variables.commitId }, + CommitId: { value: sourceAction1.variables.commitId }, }, }), ], @@ -50,7 +51,7 @@ new codepipeline.Pipeline(stack, 'Pipeline', { triggers: [{ providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, gitConfiguration: { - sourceAction, + sourceAction: sourceAction1, pushFilter: [{ tagsExcludes: ['exclude1', 'exclude2'], tagsIncludes: ['include1', 'include2'], @@ -59,12 +60,64 @@ new codepipeline.Pipeline(stack, 'Pipeline', { }], }); +const sourceOutput2 = new codepipeline.Artifact(); +const sourceAction2 = new cpactions.CodeStarConnectionsSourceAction({ + actionName: 'CodeStarConnectionsSourceAction2', + output: sourceOutput2, + connectionArn, + owner: 'go-to-k', + repo: 'cdk-codepipeline-demo-2', +}); + +// for pull request filter with branches and file paths +new codepipeline.Pipeline(stack, 'Pipeline2', { + pipelineName: 'my-pipeline2', + pipelineType: codepipeline.PipelineType.V2, + crossAccountKeys: true, + stages: [ + { + stageName: 'Source', + actions: [sourceAction2], + }, + { + stageName: 'Build', + actions: [ + new cpactions.CodeBuildAction({ + actionName: 'CodeBuild2', + project: new codebuild.PipelineProject(stack, 'MyProject2'), + input: sourceOutput2, + outputs: [new codepipeline.Artifact()], + environmentVariables: { + CommitId: { value: sourceAction2.variables.commitId }, + }, + }), + ], + }, + ], + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction: sourceAction2, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: ['/path/to/exclude1', '/path/to/exclude2'], + filePathsIncludes: ['/path/to/include1', '/path/to/include2'], + events: [codepipeline.GitPullRequestEvent.OPEN, codepipeline.GitPullRequestEvent.UPDATED], + }], + }, + }], +}); + const integrationTest = new IntegTest(app, 'codepipeline-with-pipeline-triggers-test', { testCases: [stack], diffAssets: true, }); -const awsApiCall = integrationTest.assertions.awsApiCall('CodePipeline', 'getPipeline', { name: 'my-pipeline' }); -awsApiCall.assertAtPath('pipeline.name', ExpectedResult.stringLikeRegexp('my-pipeline')); +const awsApiCall1 = integrationTest.assertions.awsApiCall('CodePipeline', 'getPipeline', { name: 'my-pipeline' }); +awsApiCall1.assertAtPath('pipeline.name', ExpectedResult.stringLikeRegexp('my-pipeline')); + +const awsApiCall2 = integrationTest.assertions.awsApiCall('CodePipeline', 'getPipeline', { name: 'my-pipeline2' }); +awsApiCall2.assertAtPath('pipeline.name', ExpectedResult.stringLikeRegexp('my-pipeline2')); app.synth(); diff --git a/packages/aws-cdk-lib/aws-codepipeline/README.md b/packages/aws-cdk-lib/aws-codepipeline/README.md index f08a8306c7be0..09a0b90bc1b6a 100644 --- a/packages/aws-cdk-lib/aws-codepipeline/README.md +++ b/packages/aws-cdk-lib/aws-codepipeline/README.md @@ -579,12 +579,17 @@ const rule = pipeline.notifyOnExecutionStateChange('NotifyOnExecutionStateChange ## Trigger -To trigger a pipeline with Git tags, specify the `triggers` property. When a Git tag is pushed, -your pipeline starts. You can filter with glob patterns. The `tagsExcludes` takes priority over -the `tagsIncludes`. - +To trigger a pipeline with Git tags or branches, specify the `triggers` property. The triggers can only be used with pipeline type V2. +### Push filter + +Pipelines can be started based on push events. You can specify the `pushFilter` property to +filter the push events. The `pushFilter` can specify Git tags. + +In the case of Git tags, your pipeline starts when a Git tag is pushed. +You can filter with glob patterns. The `tagsExcludes` takes priority over the `tagsIncludes`. + ```ts declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction; declare const buildAction: codepipeline_actions.CodeBuildAction; @@ -614,7 +619,115 @@ new codepipeline.Pipeline(this, 'Pipeline', { }); ``` -Or append a trigger to an existing pipeline: +### Pull request filter + +Pipelines can be started based on pull request events. You can specify the `pullRequestFilter` property to +filter the pull request events. The `pullRequestFilter` can specify branches, file paths, and event types. + +In the case of branches, your pipeline starts when a pull request event occurs on the specified branches. +You can filter with glob patterns. The `branchesExcludes` takes priority over the `branchesIncludes`. + +```ts +declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction; +declare const buildAction: codepipeline_actions.CodeBuildAction; + +new codepipeline.Pipeline(this, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + stages: [ + { + stageName: 'Source', + actions: [sourceAction], + }, + { + stageName: 'Build', + actions: [buildAction], + }, + ], + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include*'], + }], + }, + }], +}); +``` + +File paths can also be specified along with the branches to start the pipeline. +You can filter with glob patterns. The `filePathsExcludes` takes priority over the `filePathsIncludes`. + +```ts +declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction; +declare const buildAction: codepipeline_actions.CodeBuildAction; + +new codepipeline.Pipeline(this, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + stages: [ + { + stageName: 'Source', + actions: [sourceAction], + }, + { + stageName: 'Build', + actions: [buildAction], + }, + ], + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: ['/path/to/exclude1', '/path/to/exclude2'], + filePathsIncludes: ['/path/to/include1', '/path/to/include1'], + }], + }, + }], +}); +``` + +To filter types of pull request events for triggers, you can specify the `events` property. + +```ts +declare const sourceAction: codepipeline_actions.CodeStarConnectionsSourceAction; +declare const buildAction: codepipeline_actions.CodeBuildAction; + +new codepipeline.Pipeline(this, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + stages: [ + { + stageName: 'Source', + actions: [sourceAction], + }, + { + stageName: 'Build', + actions: [buildAction], + }, + ], + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + events: [ + codepipeline.GitPullRequestEvent.OPEN, + codepipeline.GitPullRequestEvent.CLOSED, + ], + }], + }, + }], +}); +``` + +### Append a trigger to an existing pipeline + +You can append a trigger to an existing pipeline: ```ts declare const pipeline: codepipeline.Pipeline; diff --git a/packages/aws-cdk-lib/aws-codepipeline/lib/trigger.ts b/packages/aws-cdk-lib/aws-codepipeline/lib/trigger.ts index 53909a4192b85..950eb2b3b04f2 100644 --- a/packages/aws-cdk-lib/aws-codepipeline/lib/trigger.ts +++ b/packages/aws-cdk-lib/aws-codepipeline/lib/trigger.ts @@ -32,6 +32,91 @@ export interface GitPushFilter { readonly tagsIncludes?: string[]; } +/** + * Git pull request filter for trigger. + */ +export interface GitPullRequestFilter { + /** + * The list of patterns of Git branches that, when pull request events occurs, are + * to be excluded from starting the pipeline. + * + * You can filter with glob patterns. The `branchesExcludes` takes priority + * over the `branchesIncludes`. + * + * Maximum length of this array is 8. + * + * @default - no branches. + */ + readonly branchesExcludes?: string[]; + + /** + * The list of patterns of Git branches that, when pull request events occurs, are + * to be included as criteria that starts the pipeline. + * + * You can filter with glob patterns. The `branchesExcludes` takes priority + * over the `branchesIncludes`. + * + * Maximum length of this array is 8. + * + * @default - no branches. + */ + readonly branchesIncludes?: string[]; + + /** + * The list of patterns of Git repository file paths that, when pull request events occurs, + * are to be excluded from starting the pipeline. + * + * You can filter with glob patterns. The `filePathsExcludes` takes priority + * over the `filePathsIncludes`. + * + * Maximum length of this array is 8. + * + * @default - no filePaths. + */ + readonly filePathsExcludes?: string[]; + + /** + * The list of patterns of Git repository file paths that, when pull request events occurs, + * are to be included as criteria that starts the pipeline. + * + * You can filter with glob patterns. The `filePathsExcludes` takes priority + * over the `filePathsIncludes`. + * + * Maximum length of this array is 8. + * + * @default - no filePaths. + */ + readonly filePathsIncludes?: string[]; + + /** + * The field that specifies which pull request events to filter on (opened, updated, closed) + * for the trigger configuration. + * + * @default - all events. + */ + readonly events?: GitPullRequestEvent[]; +} + +/** + * Event for trigger with pull request filter. + */ +export enum GitPullRequestEvent { + /** + * OPEN + */ + OPEN = 'OPEN', + + /** + * UPDATED + */ + UPDATED = 'UPDATED', + + /** + * CLOSED + */ + CLOSED = 'CLOSED', +} + /** * Git configuration for trigger. */ @@ -58,6 +143,16 @@ export interface GitConfiguration { * @default - no filter. */ readonly pushFilter?: GitPushFilter[]; + + /** + * The field where the repository event that will start the pipeline + * is specified as pull requests. + * + * The length must be less than or equal to 3. + * + * @default - no filter. + */ + readonly pullRequestFilter?: GitPullRequestFilter[]; } /** @@ -105,22 +200,49 @@ export class Trigger { private validate() { if (this.props.gitConfiguration) { - const sourceAction = this.props.gitConfiguration.sourceAction; + const { sourceAction, pushFilter, pullRequestFilter } = this.props.gitConfiguration; + if (sourceAction.actionProperties.provider !== 'CodeStarSourceConnection') { throw new Error(`provider for actionProperties in sourceAction with name '${sourceAction.actionProperties.actionName}' must be 'CodeStarSourceConnection', got '${sourceAction.actionProperties.provider}'`); } - const pushFilter = this.props.gitConfiguration.pushFilter; + if (pushFilter?.length && pullRequestFilter?.length) { + throw new Error(`cannot specify both pushFilter and pullRequestFilter for the trigger with sourceAction with name '${sourceAction.actionProperties.actionName}'`); + } + if (!pushFilter?.length && !pullRequestFilter?.length) { + throw new Error(`must specify either pushFilter or pullRequestFilter for the trigger with sourceAction with name '${sourceAction.actionProperties.actionName}'`); + } + if (pushFilter !== undefined && pushFilter.length > 3) { throw new Error(`length of pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' must be less than or equal to 3, got ${pushFilter.length}`); } - pushFilter?.forEach(filter => { if (filter.tagsExcludes && filter.tagsExcludes.length > 8) { - throw new Error(`maximum length of tagsExcludes for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsExcludes.length}`); + throw new Error(`maximum length of tagsExcludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsExcludes.length}`); } if (filter.tagsIncludes && filter.tagsIncludes.length > 8) { - throw new Error(`maximum length of tagsIncludes for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsIncludes.length}`); + throw new Error(`maximum length of tagsIncludes in pushFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.tagsIncludes.length}`); + } + }); + + if (pullRequestFilter !== undefined && pullRequestFilter.length > 3) { + throw new Error(`length of pullRequestFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' must be less than or equal to 3, got ${pullRequestFilter.length}`); + } + pullRequestFilter?.forEach(filter => { + if (!filter.branchesExcludes && !filter.branchesIncludes) { + throw new Error(`must specify branches in pullRequestFilter for sourceAction with name '${sourceAction.actionProperties.actionName}'`); + } + if (filter.branchesExcludes && filter.branchesExcludes.length > 8) { + throw new Error(`maximum length of branchesExcludes in pullRequestFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.branchesExcludes.length}`); + } + if (filter.branchesIncludes && filter.branchesIncludes.length > 8) { + throw new Error(`maximum length of branchesIncludes in pullRequestFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.branchesIncludes.length}`); + } + if (filter.filePathsExcludes && filter.filePathsExcludes.length > 8) { + throw new Error(`maximum length of filePathsExcludes in pullRequestFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.filePathsExcludes.length}`); + } + if (filter.filePathsIncludes && filter.filePathsIncludes.length > 8) { + throw new Error(`maximum length of filePathsIncludes in pullRequestFilter for sourceAction with name '${sourceAction.actionProperties.actionName}' is 8, got ${filter.filePathsIncludes.length}`); } }); } @@ -134,21 +256,16 @@ export class Trigger { public _render(): CfnPipeline.PipelineTriggerDeclarationProperty { let gitConfiguration: CfnPipeline.GitConfigurationProperty | undefined; if (this.props.gitConfiguration) { - const sourceAction = this.props.gitConfiguration.sourceAction; - const pushFilter = this.props.gitConfiguration.pushFilter; + const { sourceAction, pushFilter, pullRequestFilter } = this.props.gitConfiguration; - const push: CfnPipeline.GitPushFilterProperty[] | undefined = pushFilter?.map(filter => { - const tags: CfnPipeline.GitTagFilterCriteriaProperty | undefined = { - // set to undefined if empty array because CloudFormation does not accept empty array - excludes: filter.tagsExcludes?.length ? filter.tagsExcludes : undefined, - includes: filter.tagsIncludes?.length ? filter.tagsIncludes : undefined, - }; - return { tags }; - }); + const push = this.renderPushFilter(pushFilter); + const pullRequest = this.renderPullRequestFilter(pullRequestFilter); gitConfiguration = { // set to undefined if empty array because CloudFormation does not accept empty array push: push?.length ? push : undefined, + // set to undefined if empty array because CloudFormation does not accept empty array + pullRequest: pullRequest?.length ? pullRequest : undefined, sourceActionName: sourceAction.actionProperties.actionName, }; } @@ -158,4 +275,39 @@ export class Trigger { providerType: this.props.providerType, }; } + + private renderPushFilter(pushFilter?: GitPushFilter[]): CfnPipeline.GitPushFilterProperty[] | undefined { + return pushFilter?.map(filter => { + const tags: CfnPipeline.GitTagFilterCriteriaProperty | undefined = { + // set to undefined if empty array because CloudFormation does not accept empty array + excludes: filter.tagsExcludes?.length ? filter.tagsExcludes : undefined, + includes: filter.tagsIncludes?.length ? filter.tagsIncludes : undefined, + }; + return { tags }; + }); + } + + private renderPullRequestFilter(pullRequest?: GitPullRequestFilter[]): CfnPipeline.GitPullRequestFilterProperty[] | undefined { + return pullRequest?.map(filter => { + const branches: CfnPipeline.GitBranchFilterCriteriaProperty | undefined = + filter.branchesExcludes?.length || filter.branchesIncludes?.length ? { + // set to undefined if empty array because CloudFormation does not accept empty array + excludes: filter.branchesExcludes?.length ? filter.branchesExcludes : undefined, + includes: filter.branchesIncludes?.length ? filter.branchesIncludes : undefined, + } : undefined; + const filePaths: CfnPipeline.GitFilePathFilterCriteriaProperty | undefined = + filter.filePathsExcludes?.length || filter.filePathsIncludes?.length ? { + // set to undefined if empty array because CloudFormation does not accept empty array + excludes: filter.filePathsExcludes?.length ? filter.filePathsExcludes : undefined, + includes: filter.filePathsIncludes?.length ? filter.filePathsIncludes : undefined, + } : undefined; + // set to all events if empty array or undefined because CloudFormation does not accept empty array and undefined + const events: string[] = filter.events?.length ? Array.from(new Set(filter.events)) : [ + GitPullRequestEvent.OPEN, + GitPullRequestEvent.UPDATED, + GitPullRequestEvent.CLOSED, + ]; + return { branches, filePaths, events }; + }); + } } \ No newline at end of file diff --git a/packages/aws-cdk-lib/aws-codepipeline/test/triggers.test.ts b/packages/aws-cdk-lib/aws-codepipeline/test/triggers.test.ts index 6c9048ddede4d..0e186ea40b41a 100644 --- a/packages/aws-cdk-lib/aws-codepipeline/test/triggers.test.ts +++ b/packages/aws-cdk-lib/aws-codepipeline/test/triggers.test.ts @@ -28,7 +28,7 @@ describe('triggers', () => { }); }); - test('can specify triggers', () => { + test('can specify triggers with tags in pushFilter', () => { const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { pipelineType: codepipeline.PipelineType.V2, triggers: [{ @@ -62,6 +62,120 @@ describe('triggers', () => { }); }); + test('can specify triggers with branches in pullRequestFilter', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('can specify triggers with branches and file paths in pullRequestFilter', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: ['exclude1', 'exclude2'], + filePathsIncludes: ['include1', 'include2'], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + FilePaths: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('can specify triggers with branches and events in pullRequestFilter', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + events: [ + codepipeline.GitPullRequestEvent.OPEN, + codepipeline.GitPullRequestEvent.UPDATED, + codepipeline.GitPullRequestEvent.CLOSED, + ], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + Events: ['OPEN', 'UPDATED', 'CLOSED'], + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + test('can specify multiple triggers', () => { const sourceArtifact2 = new codepipeline.Artifact(); const sourceAction2 = new CodeStarConnectionsSourceAction({ @@ -164,7 +278,7 @@ describe('triggers', () => { }); }); - test('empty tagsExcludes for trigger is set to undefined', () => { + test('empty tagsExcludes in pushFilter for trigger is set to undefined', () => { const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { pipelineType: codepipeline.PipelineType.V2, triggers: [{ @@ -198,7 +312,7 @@ describe('triggers', () => { }); }); - test('empty tagsIncludes for trigger is set to undefined', () => { + test('empty tagsIncludes in pushFilter for trigger is set to undefined', () => { const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { pipelineType: codepipeline.PipelineType.V2, triggers: [{ @@ -232,7 +346,226 @@ describe('triggers', () => { }); }); - test('throw if length of excludes is greater than 8', () => { + test('empty branchesExcludes in pullRequestFilter for trigger is set to undefined', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: [], + branchesIncludes: ['include1', 'include2'], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: Match.absent(), + Includes: ['include1', 'include2'], + }, + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('empty branchesIncludes in pullRequestFilter for trigger is set to undefined', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['excluded1', 'excluded2'], + branchesIncludes: [], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['excluded1', 'excluded2'], + Includes: Match.absent(), + }, + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('empty filePathsExcludes in pullRequestFilter for trigger is set to undefined', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: [], + filePathsIncludes: ['include1', 'include2'], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + FilePaths: { + Excludes: Match.absent(), + Includes: ['include1', 'include2'], + }, + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('empty filePathsIncludes in pullRequestFilter for trigger is set to undefined', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: ['exclude1', 'exclude2'], + filePathsIncludes: [], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + FilePaths: { + Excludes: ['exclude1', 'exclude2'], + Includes: Match.absent(), + }, + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('undefined events in pullRequestFilter for trigger is set to all events', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + Events: ['OPEN', 'UPDATED', 'CLOSED'], + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('empty events in pullRequestFilter for trigger is set to all events', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + events: [], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + Events: ['OPEN', 'UPDATED', 'CLOSED'], + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + + test('throw if length of tagsExcludes in pushFilter is greater than 8', () => { expect(() => { new codepipeline.Pipeline(stack, 'Pipeline', { pipelineType: codepipeline.PipelineType.V2, @@ -247,10 +580,10 @@ describe('triggers', () => { }, }], }); - }).toThrow(/maximum length of tagsExcludes for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }).toThrow(/maximum length of tagsExcludes in pushFilter for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); }); - test('throw if length of excludes is greater than 8', () => { + test('throw if length of tagsIncludes in pushFilter is greater than 8', () => { expect(() => { new codepipeline.Pipeline(stack, 'Pipeline', { pipelineType: codepipeline.PipelineType.V2, @@ -265,7 +598,138 @@ describe('triggers', () => { }, }], }); - }).toThrow(/maximum length of tagsIncludes for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }).toThrow(/maximum length of tagsIncludes in pushFilter for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }); + + test('throw if length of branchesExcludes in pullRequestFilter is greater than 8', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2', 'exclude3', 'exclude4', 'exclude5', 'exclude6', 'exclude7', 'exclude8', 'exclude9'], + branchesIncludes: ['include1', 'include2'], + }], + }, + }], + }); + }).toThrow(/maximum length of branchesExcludes in pullRequestFilter for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }); + + test('throw if length of branchesIncludes in pullRequestFilter is greater than 8', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2', 'include3', 'include4', 'include5', 'include6', 'include7', 'include8', 'include9'], + }], + }, + }], + }); + }).toThrow(/maximum length of branchesIncludes in pullRequestFilter for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }); + + test('throw if length of filePathsExcludes in pullRequestFilter is greater than 8', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: ['exclude1', 'exclude2', 'exclude3', 'exclude4', 'exclude5', 'exclude6', 'exclude7', 'exclude8', 'exclude9'], + filePathsIncludes: ['include1', 'include2'], + }], + }, + }], + }); + }).toThrow(/maximum length of filePathsExcludes in pullRequestFilter for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }); + + test('throw if length of filePathsIncludes in pullRequestFilter is greater than 8', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + filePathsExcludes: ['exclude1', 'exclude2'], + filePathsIncludes: ['include1', 'include2', 'include3', 'include4', 'include5', 'include6', 'include7', 'include8', 'include9'], + }], + }, + }], + }); + }).toThrow(/maximum length of filePathsIncludes in pullRequestFilter for sourceAction with name 'CodeStarConnectionsSourceAction' is 8, got 9/); + }); + + test('throw if branches is not specified in pullRequestFilter', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{}], + }, + }], + }); + }).toThrow(/must specify branches in pullRequestFilter for sourceAction with name 'CodeStarConnectionsSourceAction'/); + }); + + test('can eliminate duplicates events in pullRequestFilter', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [{ + branchesExcludes: ['exclude1', 'exclude2'], + branchesIncludes: ['include1', 'include2'], + events: [ + codepipeline.GitPullRequestEvent.OPEN, + codepipeline.GitPullRequestEvent.OPEN, + codepipeline.GitPullRequestEvent.CLOSED, + ], + }], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: [{ + Branches: { + Excludes: ['exclude1', 'exclude2'], + Includes: ['include1', 'include2'], + }, + Events: ['OPEN', 'CLOSED'], + }], + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); }); test('empty pushFilter for trigger is set to undefined', () => { @@ -276,6 +740,11 @@ describe('triggers', () => { gitConfiguration: { sourceAction, pushFilter: [], + pullRequestFilter: [ + { + branchesExcludes: ['exclude1'], + }, + ], }, }], }); @@ -294,6 +763,37 @@ describe('triggers', () => { }); }); + test('empty pullRequestFilter for trigger is set to undefined', () => { + const pipeline = new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pushFilter: [ + { + tagsExcludes: ['exclude1'], + }, + ], + pullRequestFilter: [], + }, + }], + }); + + testPipelineSetup(pipeline, [sourceAction], [buildAction]); + + Template.fromStack(stack).hasResourceProperties('AWS::CodePipeline::Pipeline', { + PipelineType: 'V2', + Triggers: [{ + GitConfiguration: { + SourceActionName: 'CodeStarConnectionsSourceAction', + PullRequest: Match.absent(), + }, + ProviderType: 'CodeStarSourceConnection', + }], + }); + }); + test('throw if length of pushFilter is greater than 3', () => { expect(() => { new codepipeline.Pipeline(stack, 'Pipeline', { @@ -326,6 +826,94 @@ describe('triggers', () => { }).toThrow(/length of pushFilter for sourceAction with name 'CodeStarConnectionsSourceAction' must be less than or equal to 3, got 4/);; }); + test('throw if length of pullRequestFilter is greater than 3', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pullRequestFilter: [ + { + branchesExcludes: ['exclude1'], + branchesIncludes: ['include1'], + }, + { + branchesExcludes: ['exclude2'], + branchesIncludes: ['include2'], + }, + { + branchesExcludes: ['exclude3'], + branchesIncludes: ['include3'], + }, + { + branchesExcludes: ['exclude4'], + branchesIncludes: ['include4'], + }, + ], + }, + }], + }); + }).toThrow(/length of pullRequestFilter for sourceAction with name 'CodeStarConnectionsSourceAction' must be less than or equal to 3, got 4/);; + }); + + test('throw if both pushFilter and pullRequestFilter are specified', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pushFilter: [ + { + tagsExcludes: ['exclude1'], + tagsIncludes: ['include1'], + }, + ], + pullRequestFilter: [ + { + branchesExcludes: ['exclude1'], + branchesIncludes: ['include1'], + }, + ], + }, + }], + }); + }).toThrow(/cannot specify both pushFilter and pullRequestFilter for the trigger with sourceAction with name 'CodeStarConnectionsSourceAction'/);; + }); + + test('throw if neither pushFilter nor pullRequestFilter are specified', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + }, + }], + }); + }).toThrow(/must specify either pushFilter or pullRequestFilter for the trigger with sourceAction with name 'CodeStarConnectionsSourceAction'/);; + }); + + test('throw if both pushFilter and pullRequestFilter are empty arrays', () => { + expect(() => { + new codepipeline.Pipeline(stack, 'Pipeline', { + pipelineType: codepipeline.PipelineType.V2, + triggers: [{ + providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, + gitConfiguration: { + sourceAction, + pushFilter: [], + pullRequestFilter: [], + }, + }], + }); + }).toThrow(/must specify either pushFilter or pullRequestFilter for the trigger with sourceAction with name 'CodeStarConnectionsSourceAction'/);; + }); + test('throw if provider of sourceAction is not \'CodeStarSourceConnection\'', () => { const fakeAction = new FakeSourceAction({ actionName: 'FakeSource', @@ -367,6 +955,10 @@ describe('triggers', () => { providerType: codepipeline.ProviderType.CODE_STAR_SOURCE_CONNECTION, gitConfiguration: { sourceAction, + pushFilter: [{ + tagsExcludes: ['exclude1', 'exclude2'], + tagsIncludes: ['include1', 'include2'], + }], }, }); }).toThrow(/Trigger with duplicate source action 'CodeStarConnectionsSourceAction' added to the Pipeline/);