在CodeCommit中创建拉取请求时如何触发AWS Codebuild?

时间:2018-07-15 08:59:54

标签: aws-codepipeline aws-codebuild

我们的ci工作流是这个

  • 在预提交中运行eslint
  • 推送到功能分支
  • 在代码提交中打开拉取请求
  • 触发aws代码构建运行测试
  • 如果所有测试均通过,则合并
  • 触发aws代码部署以部署

现在,我注意到codebuild将在推送时触发。我如何才能使其在合并请求时触发?

2 个答案:

答案 0 :(得分:2)

好吧,第一个回复已在此线程上发布了一年多,而当时可能是正确的答案。但是今天,它不再正确了。

CodeCommit与CloudWatch Events集成。它可以在以下情况下发出事件信号:

  • 创建,更新或关闭请求。
  • 有人对拉取请求发表评论。
  • 评论和回复已添加到提交中。

然后,您可以在CloudWatch中创建一个规则,以在每个新事件时进行评估。如果规则正确,则可以开始执行管道。

这是我使用CodeCommit,CodeBuild和CodePipeline的(简化的)开发工作流程:

  1. 在本地存储库上创建功能分支;
  2. 在提交时,运行lint和单元测试;
  3. 准备好部署功能后,我创建一个拉取请求;
  4. 拉动请求批准并合并后,CodeCommit将事件发送到CloudWatch;
  5. CloudWatch评估规则以检查更改是否在master *分支上;
  6. 如果规则评估为true,则CloudWatch将启动管道。

这是我用来创建和配置CodeCommit存储库,CloudWatch Event,CodeBuild和CodePipeline的CloudFormation模板。您可以找到完整的堆栈here

{
    "AWSTemplateFormatVersion": "2010-09-09",
        "Description": "Cloud Formation Template for Pipeline/Build/Deploy StaticWebSite on S3",

        "Parameters" : {

            "S3BucketForWebSite" : {
                "Type" : "String",
                "Description" : "The S3 address of Stack Resources and Files"
            }
        },

        "Resources": {

            "S3BucketForArtifacts" : {
                "Type" : "AWS::S3::Bucket",
                "Properties" : {
                  "AccessControl" : "Private"
                }
            },

            "CodeRepository" : {
                "Type" : "AWS::CodeCommit::Repository",
                "Properties" : {
                    "RepositoryName" : { "Fn::Sub": [ "${Stack}-Repo", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                    "RepositoryDescription" : "Repository for S3 Static Web Site"
                }
            },

            "BuildRole" : {
                "Type": "AWS::IAM::Role",
                "Properties": {
                    "RoleName": { "Fn::Sub": [ "${Stack}-CodeBuildExecRole", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                    "AssumeRolePolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [{ "Effect": "Allow", "Principal": {"Service": ["codebuild.amazonaws.com"]}, "Action": ["sts:AssumeRole"] }]
                    },
                    "Path": "/",
                    "Policies": [ {
                        "PolicyName": "root",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Sid": "WriteOnWebSiteBucket",
                                    "Action": ["s3:*"],
                                    "Resource": [
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}", { "BucketName": {"Ref" : "S3BucketForWebSite" }} ]},
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}/*", { "BucketName": {"Ref" : "S3BucketForWebSite" }} ]}
                                    ],
                                    "Effect": "Allow"
                                },
                                {
                                    "Sid": "CreateLogGroups",
                                    "Effect": "Allow",
                                    "Action": ["logs:CreateLogGroup"],
                                    "Resource": ["*"]
                                },
                                {
                                    "Sid": "CreateStreamAndPutLogs",
                                    "Effect": "Allow",
                                    "Action": ["logs:CreateLogStream", "logs:PutLogEvents"],
                                    "Resource": ["arn:aws:logs:*"]
                                },
                                {
                                    "Sid": "CheckBuketsInS3",
                                    "Effect": "Allow",
                                    "Action": ["s3:ListAllMyBuckets", "s3:HeadBucket"],
                                    "Resource": ["*"]
                                },
                                {
                                    "Sid": "GetAndPutObjectsInS3ArtifactStore",
                                    "Effect": "Allow",
                                    "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:GetObjectVersion", "s3:GetBucketAcl", "s3:PutBucketAcl", "s3:PutObjectAcl", "s3:GetObjectVersion"],
                                    "Resource": [
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}", { "BucketName": {"Ref" : "S3BucketForArtifacts" }} ]},
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}/*", { "BucketName": {"Ref" : "S3BucketForArtifacts" }} ]}
                                    ]
                                }
                            ]
                        }
                    } ]
                }
            },

            "CodeBuild" : {
                "Type" : "AWS::CodeBuild::Project",
                "Properties" : {
                    "Artifacts" : {
                            "Type": "CODEPIPELINE",
                            "Name": { "Fn::Sub": [ "${Stack}-Build", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                            "Packaging": "NONE"
                        },
                    "BadgeEnabled" : false,
                    "Cache" : {"Type": "NO_CACHE"},
                    "Description" : { "Fn::Sub": [ "StaticWebSite Build for ${Stack}", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                    "Environment" : {
                        "Type": "LINUX_CONTAINER",
                        "Image": "aws/codebuild/nodejs:10.1.0",
                        "ComputeType": "BUILD_GENERAL1_SMALL",
                        "EnvironmentVariables": [],
                        "PrivilegedMode": false
                    },
                    "Name" : {"Ref" : "AWS::StackName" },
                    "ServiceRole" : { "Fn::GetAtt" : ["BuildRole", "Arn"] },
                    "Source" : {
                        "Type": "CODEPIPELINE",
                        "InsecureSsl": false
                    },
                    "TimeoutInMinutes" : 60
                }
            },

            "PipelineRole": {
               "Type": "AWS::IAM::Role",
               "Properties": {
                    "RoleName": { "Fn::Sub": [ "${Stack}-CodePipeLineExecRole", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                    "AssumeRolePolicyDocument": {
                        "Version": "2012-10-17",
                        "Statement": [{ "Effect": "Allow", "Principal": {"Service": ["codepipeline.amazonaws.com"]}, "Action": ["sts:AssumeRole"] }]
                    },
                    "Path": "/",
                    "Policies": [ {
                        "PolicyName": "root",
                        "PolicyDocument": {
                            "Version": "2012-10-17",
                            "Statement": [
                                {
                                    "Sid": "WriteOnWebSiteBucket",
                                    "Action": ["s3:*"],
                                    "Resource": [
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}", { "BucketName": {"Ref" : "S3BucketForWebSite" }} ]},
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}/*", { "BucketName": {"Ref" : "S3BucketForWebSite" }} ]}
                                    ],
                                    "Effect": "Allow"
                                },
                                {
                                    "Sid": "InterfaceWithBucketsInS3",
                                    "Action": ["s3:GetObject", "s3:GetObjectVersion", "s3:GetBucketVersioning"],
                                    "Resource": "*",
                                    "Effect": "Allow"
                                },
                                {
                                    "Sid": "InterfaceWithArtifactStoreInS3",
                                    "Effect": "Allow",
                                    "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject", "s3:GetObjectVersion", "s3:GetBucketAcl", "s3:PutBucketAcl", "s3:PutObjectAcl", "s3:GetObjectVersion"],
                                    "Resource": [
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}", { "BucketName": {"Ref" : "S3BucketForArtifacts" }} ]},
                                        { "Fn::Sub": [ "arn:aws:s3:::${BucketName}/*", { "BucketName": {"Ref" : "S3BucketForArtifacts" }} ]}
                                    ]
                                },
                                {
                                    "Sid": "InterfaceWithCodeCommit",
                                    "Action": ["codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetUploadArchiveStatus", "codecommit:UploadArchive"],
                                    "Resource": "*",
                                    "Effect": "Allow"
                                },
                                {
                                    "Sid": "InterfaceWithCodeBuild",
                                    "Action": ["codebuild:BatchGetBuilds", "codebuild:StartBuild"],
                                    "Resource": "*",
                                    "Effect": "Allow"
                                }
                            ]
                        }            
                    } ]
               }
            },

            "CodePipeline" : {
                "Type" : "AWS::CodePipeline::Pipeline",
                "Properties" : {
                  "ArtifactStore" : {
                    "Location" : {"Ref": "S3BucketForArtifacts"},
                    "Type" : "S3"
                  },
                  "RestartExecutionOnUpdate" : false,
                  "RoleArn" : { "Fn::GetAtt" : ["PipelineRole", "Arn"] },
                  "Stages" : [
                    {
                        "Name": "Source",
                        "Actions": [
                            {
                                "Name": "Source",
                                "ActionTypeId": {"Category": "Source", "Owner": "AWS", "Provider": "CodeCommit", "Version": "1"},
                                "RunOrder": 1,
                                "Configuration": { "BranchName": "master", "PollForSourceChanges": "false", "RepositoryName": { "Fn::Sub": [ "${Stack}-Repo", { "Stack": {"Ref" : "AWS::StackName" }} ]}},
                                "OutputArtifacts": [ { "Name" : {"Ref" : "AWS::StackName"} } ],
                                "InputArtifacts": []
                            }
                        ]
                    },

                    {
                        "Name": "Build",
                        "Actions": [
                            {
                                "Name": "CodeBuild",
                                "ActionTypeId": { "Category": "Build", "Owner": "AWS", "Provider": "CodeBuild", "Version": "1" },
                                "RunOrder": 1,
                                "Configuration": { "ProjectName": {"Ref" : "AWS::StackName" } },
                                "InputArtifacts": [ { "Name" : {"Ref" : "AWS::StackName"} } ],
                                "OutputArtifacts": [ { "Name": { "Fn::Sub": [ "${Stack}-builded", { "Stack": {"Ref" : "AWS::StackName" }} ]} } ]
                            }
                        ]
                    }

                ]
                }
            },

            "CloudWathEventRole": {

                "Type": "AWS::IAM::Role",
                "Properties": {
                     "RoleName": { "Fn::Sub": [ "${Stack}-CloudWatchEventRole", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                     "AssumeRolePolicyDocument": {
                         "Version": "2012-10-17",
                         "Statement": [{ "Effect": "Allow", "Principal": {"Service": ["events.amazonaws.com"]}, "Action": ["sts:AssumeRole"] }]
                     },
                     "Path": "/",
                     "Policies": [ {
                         "PolicyName": "root",
                         "PolicyDocument": {
                             "Version": "2012-10-17",
                             "Statement": [
                                 {
                                     "Action": ["codepipeline:StartPipelineExecution"],
                                     "Resource": { "Fn::Sub": [ "arn:aws:codepipeline:${Region}:${Account}:${PipelineName}", { "Region": { "Ref" : "AWS::Region" }, "Account": { "Ref" : "AWS::AccountId" }, "PipelineName": {"Ref" : "CodePipeline" }} ]},
                                     "Effect": "Allow"
                                 }
                             ]
                         }            
                     } ]
                }

            },

            "CloudWatchEventRule" : {
                "Type" : "AWS::Events::Rule",
                "Properties" : {

                    "Name" : { "Fn::Sub": [ "${Stack}-Repo-Changes", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                    "Description" : "Check CodeCommit Repo Changes",

                    "EventPattern" : {
                        "detail-type": ["CodeCommit Repository State Change"],
                        "source": ["aws.codecommit"],
                        "resources": [{ "Fn::GetAtt" : [ "CodeRepository", "Arn" ] }],
                        "detail": { "referenceType": ["branch"], "referenceName": ["master"]}
                    },

                    "Targets" : [ {
                            "Id" : "codepipeline",
                            "Arn" : { "Fn::Sub": [ "arn:aws:codepipeline:${Region}:${Account}:${PipelineName}", { "Region": { "Ref" : "AWS::Region" }, "Account": { "Ref" : "AWS::AccountId" }, "PipelineName": {"Ref" : "CodePipeline" }} ]},
                            "RoleArn" : { "Fn::GetAtt" : ["CloudWathEventRole", "Arn"] }
                    } ]

                }
            }

        },

        "Outputs": {
            "RepoName" : {
                "Value" : { "Fn::Sub": [ "${Stack}-Repo", { "Stack": {"Ref" : "AWS::StackName" }} ]},
                "Description" : "CodeCommit Repository Name",
                "Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-RepoName" }}
            },
            "RepoArn" : {
                "Value" : { "Fn::GetAtt" : [ "CodeRepository", "Arn" ] },
                "Description" : "CodeCommit Repository Arn",
                "Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-RepoArn" }}
            },
            "RepoCloneSSHUrl" : {
                "Value" : { "Fn::GetAtt" : [ "CodeRepository", "CloneUrlSsh" ] },
                "Description" : "CodeCommit Repository SSH Url to be cloned",
                "Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-RepoCloneSSHUrl" }}
            },
            "RepoCloneHttpUrl" : {
                "Value" : { "Fn::GetAtt" : [ "CodeRepository", "CloneUrlHttp" ] },
                "Description" : "CodeCommit Repository Http Url to be cloned",
                "Export" : {"Name" : {"Fn::Sub": "${AWS::StackName}-RepoCloneHttpUrl" }}
            }

        }
    }

答案 1 :(得分:1)

不幸的是,CodeBuild本身还不支持CodeCommit拉取请求。我们知道用例,尽管我无法提供确切的官方支持时间表。

同时,您可以考虑创建CodeCommit notifications,并与AWS Lambda函数配对以为每个拉取请求运行CodeBuild。