├── .github └── FUNDING.yml ├── LICENSE ├── buildspec.yml ├── cfn-pipeline.yaml ├── readme.md └── scripts └── codebuild-git-wrapper.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [TimothyJones] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | # patreon: # Replace with a single Patreon username 5 | # open_collective: # Replace with a single Open Collective username 6 | # ko_fi: # Replace with a single Ko-fi username 7 | # tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | # community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | # liberapay: # Replace with a single Liberapay username 10 | # issuehunt: # Replace with a single IssueHunt username 11 | # otechie: # Replace with a single Otechie username 12 | # lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | # custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Timothy Jones 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /buildspec.yml: -------------------------------------------------------------------------------- 1 | version: 0.2 2 | 3 | env: 4 | git-credential-helper: yes 5 | 6 | phases: 7 | build: 8 | commands: 9 | - scripts/codebuild-git-wrapper.sh "$REPO_URL" "$REPO_BRANCH" # These environment variables come from the CFN stack 10 | - git log | head -100 11 | -------------------------------------------------------------------------------- /cfn-pipeline.yaml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: 2010-09-09 2 | Transform: 'AWS::Serverless-2016-10-31' 3 | Parameters: 4 | RepositoryName: 5 | Description: 'CodeCommit repository name' 6 | Type: String 7 | RepositoryCloneUrl: 8 | Description: 'CodeCommit repository clone URL' 9 | Type: String 10 | RepositoryBranch: 11 | Description: 'CodeCommit repository branch (defaults to master)' 12 | Type: String 13 | Default: master 14 | 15 | Resources: 16 | CodePipeline: 17 | Type: 'AWS::CodePipeline::Pipeline' 18 | Properties: 19 | RoleArn: !GetAtt CodePipeLineRole.Arn 20 | ArtifactStore: 21 | Location: !Ref PipelineBucket 22 | Type: S3 23 | Stages: 24 | - Name: Source 25 | Actions: 26 | - Name: SourceAction 27 | ActionTypeId: 28 | Category: Source 29 | Owner: AWS 30 | Version: 1 31 | Provider: CodeCommit 32 | OutputArtifacts: 33 | - Name: Source 34 | Configuration: 35 | BranchName: !Ref RepositoryBranch 36 | RepositoryName: !Ref RepositoryName 37 | - Name: Build 38 | Actions: 39 | - Name: BuildAction 40 | ActionTypeId: 41 | Category: Build 42 | Owner: AWS 43 | Version: 1 44 | Provider: CodeBuild 45 | InputArtifacts: 46 | - Name: Source 47 | OutputArtifacts: 48 | - Name: Build 49 | Configuration: 50 | ProjectName: !Ref CodeBuild 51 | 52 | CodePipeLineRole: 53 | Type: AWS::IAM::Role 54 | Properties: 55 | AssumeRolePolicyDocument: 56 | Version: '2012-10-17' 57 | Statement: 58 | - Effect: Allow 59 | Principal: 60 | Service: 61 | - 'codepipeline.amazonaws.com' 62 | Action: 63 | - 'sts:AssumeRole' 64 | Policies: 65 | - PolicyName: root 66 | PolicyDocument: 67 | Version: '2012-10-17' 68 | Statement: 69 | - Effect: Allow 70 | Action: 71 | - 's3:GetObject' 72 | - 's3:GetObjectVersion' 73 | - 's3:GetBucketVersioning' 74 | - 's3:PutObject' 75 | - 's3:PutObjectAcl' 76 | - 'codecommit:GetBranch' 77 | - 'codecommit:GetCommit' 78 | - 'codecommit:GetUploadArchiveStatus' 79 | - 'codecommit:UploadArchive' 80 | Resource: 81 | - !Sub arn:aws:codecommit:*:*:${RepositoryName} 82 | - !GetAtt PipelineBucket.Arn 83 | - !Join ['', [!GetAtt PipelineBucket.Arn, '/*']] 84 | - Effect: Allow 85 | Action: 86 | - 'codebuild:BatchGetBuilds' 87 | - 'codebuild:StartBuild' 88 | Resource: '*' 89 | CodeBuildRole: 90 | Type: AWS::IAM::Role 91 | Properties: 92 | AssumeRolePolicyDocument: 93 | Version: '2012-10-17' 94 | Statement: 95 | - Effect: Allow 96 | Principal: 97 | Service: 98 | - 'codebuild.amazonaws.com' 99 | Action: 100 | - 'sts:AssumeRole' 101 | Policies: 102 | - PolicyName: root 103 | PolicyDocument: 104 | Version: '2012-10-17' 105 | Statement: 106 | - Effect: Allow 107 | Action: 108 | - 's3:GetObject' 109 | - 's3:GetObjectVersion' 110 | - 's3:GetBucketVersioning' 111 | - 's3:PutObject' 112 | Resource: 113 | - !GetAtt PipelineBucket.Arn 114 | - !Join ['', [!GetAtt PipelineBucket.Arn, '/*']] 115 | - Effect: Allow 116 | Action: 117 | - 'codecommit:GitPull' 118 | Resource: 119 | - !Sub arn:aws:codecommit:*:*:${RepositoryName} 120 | - Effect: Allow 121 | Action: 122 | - 'logs:CreateLogGroup' 123 | - 'logs:CreateLogStream' 124 | - 'logs:PutLogEvents' 125 | Resource: 126 | - '*' 127 | CodeBuild: 128 | Type: 'AWS::CodeBuild::Project' 129 | Properties: 130 | Name: !Sub '${AWS::StackName}-${RepositoryBranch}-CodeBuild' 131 | ServiceRole: !GetAtt CodeBuildRole.Arn 132 | Artifacts: 133 | Type: CODEPIPELINE 134 | Environment: 135 | ComputeType: BUILD_GENERAL1_SMALL 136 | Type: LINUX_CONTAINER 137 | Image: 'aws/codebuild/nodejs:8.11.0' 138 | EnvironmentVariables: 139 | - Name: REPO_URL 140 | Value: !Ref RepositoryCloneUrl 141 | - Name: REPO_BRANCH 142 | Value: !Ref RepositoryBranch 143 | Source: 144 | Type: CODEPIPELINE 145 | PipelineBucket: 146 | Type: 'AWS::S3::Bucket' 147 | Properties: {} 148 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # CodePipeline / CodeBuild / CodeCommit git metadata example 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | 5 | This project illustrates how to get git metadata into CodePipeline by cloning the 6 | repository and winding it back to the right commit. It is the companion code to [this blog post](https://medium.com/@timothyjones_88921/how-to-access-git-metadata-in-codebuild-when-using-codepipeline-codecommit-ceacf2c5c1dc), which explains the strategy in detail. 7 | 8 | You can deploy it with a command like this: 9 | 10 | ``` 11 | aws cloudformation deploy --template-file cfn-pipeline.yaml \ 12 | --stack-name= \ 13 | --parameter-overrides \ 14 | RepositoryName= \ 15 | RepositoryCloneUrl= \ 16 | RepositoryBranch= \ 17 | --capabilities CAPABILITY_IAM 18 | ``` 19 | 20 | Make sure to replace the bracketed values before deployment. 21 | 22 | ## Full instructions 23 | 24 | To see this in action, follow the following steps: 25 | 26 | 1) Clone this repository. 27 | 28 | ``` 29 | git clone https://github.com/TimothyJones/codepipeline-git-metadata-example.git 30 | ``` 31 | 32 | 2) Create an AWS CodeCommit repository, note down the repository name and the clone URL. 33 | 34 | 3) Add your new CodeCommit repo as a remote, and push: 35 | 36 | ``` 37 | git remote add aws 38 | git push -u aws master 39 | ``` 40 | 41 | 3b) If the above push fails, you will probably need to [configure the AWS credential helper](https://docs.aws.amazon.com/codecommit/latest/userguide/setting-up-https-unixes.html) 42 | 43 | 4) Deploy the pipeline: 44 | 45 | ``` 46 | aws cloudformation deploy --template-file cfn-pipeline.yaml \ 47 | --stack-name= \ 48 | --parameter-overrides \ 49 | RepositoryName= \ 50 | RepositoryCloneUrl= \ 51 | --capabilities CAPABILITY_IAM 52 | ``` 53 | -------------------------------------------------------------------------------- /scripts/codebuild-git-wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -eu 2 | 3 | # This is a workaround for a limitation of CodeBuild / CodePipeline, where the git metadata is missing. 4 | # It brings in the git metadata by checking out the repository and winding it to the currently building commit. 5 | # See https://itnext.io/how-to-access-git-metadata-in-codebuild-when-using-codepipeline-codecommit-ceacf2c5c1dc? 6 | # for the rationale and description. 7 | 8 | # (C) Timothy Jones, https://github.com/TimothyJones/codepipeline-git-metadata-example 9 | # MIT License, see https://github.com/TimothyJones/codepipeline-git-metadata-example/blob/master/LICENSE 10 | 11 | # This function prints the usage 12 | function usage { 13 | { 14 | echo "Usage:" 15 | echo " ${BASH_SOURCE[0]} " 16 | echo " REPO_URL - the URL for the CodeCommit repository" 17 | echo " BRANCH - (optional) the branch to check out. Defaults to the default branch." 18 | } >&2 19 | } 20 | 21 | # Confirm that there are at least two arguments 22 | if [ "$#" -lt 1 ]; then 23 | usage 24 | exit 1 25 | fi 26 | 27 | # Confirm that CODEBUILD_RESOLVED_SOURCE_VERSION is set 28 | if [ -z "${CODEBUILD_RESOLVED_SOURCE_VERSION:-}" ]; then 29 | { 30 | echo "Error: CODEBUILD_RESOLVED_SOURCE_VERSION is not set" 31 | } >&2 32 | usage 33 | exit 1 34 | fi 35 | 36 | # Read arguments 37 | REPO_URL="$1" 38 | if [ ! -z "${2:-}" ]; then 39 | BRANCH=$2 40 | fi 41 | 42 | # Remember the working directory 43 | WORKING_DIR="$(pwd)" 44 | 45 | # Check out the repository to a temporary directory 46 | # Note that --quiet doesn't work on the current CodeBuild agents, but 47 | # hopefully it will in the future 48 | TEMP_FOLDER="$(mktemp -d)" 49 | git clone --quiet "$REPO_URL" "$TEMP_FOLDER" 50 | 51 | # Wind the repository back to the specified branch and commit 52 | cd "$TEMP_FOLDER" 53 | git fetch --tags 54 | if [ ! -z "${BRANCH:-}" ]; then 55 | git checkout "$BRANCH" 56 | fi 57 | git reset --hard "$CODEBUILD_RESOLVED_SOURCE_VERSION" 58 | 59 | # Confirm that the git checkout worked 60 | if [ ! -d .git ] ; then 61 | { 62 | echo "Error: .git directory missing. Git checkout probably failed" 63 | } >&2 64 | exit 1 65 | fi 66 | 67 | mv .git "$WORKING_DIR" 68 | --------------------------------------------------------------------------------