diff --git a/README.md b/README.md index eb36be6..a685945 100644 --- a/README.md +++ b/README.md @@ -135,10 +135,11 @@ yes | S3_SAM_ARTIFACTS_BUCKET_NAME | An S3 bucket to store AWS SAM's artifacts. yes | GITHUB_REPOSITORY_URL | A repository URL you wanted build. Use https style path and make sure trailing '.git' is removed. | https://github.com/your-org/your-repo yes | GITHUB_PERSONAL_ACCESS_TOKEN | Used for updating GitHub PR's status and Webhook configuration. Minimum scope are `admin:repo_hook` and `repo:status`. You can create and obtain a new token via [settings page](https://github.com/settings/tokens/new). | your-github-personal-access-token yes | GITHUB_TARGET_RESOURCE | Choose one event to decide when your CodeBuild project runs. Available value is `pr` or `push`. | push -optional | GITHUB_IGNORE_BRANCH_REGEX | Regex string to specify branch name to ignore commit events. This parameter will be enabled only the `GITHUB_TARGET_RESOURCE` value is set to `push`. | wip.* +optional | GITHUB_IGNORE_BRANCH_REGEX | Regex string to specify branch name to ignore commit events. This parameter will be enabled only the `GITHUB_TARGET_RESOURCE` value is `push`. | wip.* yes | AWS_DEFAULT_REGION | The region where you want to provision this tool via CloudFormation. | us-east-1 yes | CODEBUILD_PROJECT_NAME | The AWS CodeBuild project name you've already configured for your GitHub repository. | your-codebuild-project-name yes | CODEBUILD_PROJECT_REGION | The region where you've created a CodeBuild project. You can specify a different region from the region of CloudFormation. | us-east-1 +optional | BUILD_SKIPPED_BY | Build invocation will be skipped if the head commit message includes the value of this parameter. This parameter will be used only the GITHUB_TARGET_RESOURCE value is `push`. | "skip ci" #### Deploy diff --git a/env/example.env b/env/example.env index 286f336..297aee3 100644 --- a/env/example.env +++ b/env/example.env @@ -8,3 +8,4 @@ GITHUB_IGNORE_BRANCH_REGEX=wip.* AWS_DEFAULT_REGION=us-east-1 CODEBUILD_PROJECT_NAME=your-codebuild-project-name CODEBUILD_PROJECT_REGION=us-east-1 +BUILD_SKIPPED_BY="skip ci" diff --git a/sam.yml b/sam.yml index aa32a1c..60adf4a 100644 --- a/sam.yml +++ b/sam.yml @@ -15,6 +15,8 @@ Parameters: Type: String CodeBuildRegion: Type: String + BuildSkippedBy: + Type: String Resources: # AWS SAM doesn't support `Transform` in nested templates, we includes all children into main template @@ -208,6 +210,7 @@ Resources: GITHUB_REPOSITORY_URL: !Ref GitHubRepositoryUrl GITHUB_TARGET_RESOURCE: !Ref GitHubTargetResource GITHUB_IGNORE_BRANCH_REGEX: !Ref GitHubIgnoreBranchRegex + BUILD_SKIPPED_BY: !Ref BuildSkippedBy StatesExecutionRole: Type: "AWS::IAM::Role" Properties: diff --git a/scripts/deploy b/scripts/deploy index 35f1e04..0c6d50a 100755 --- a/scripts/deploy +++ b/scripts/deploy @@ -21,7 +21,8 @@ aws cloudformation deploy \ --parameter-overrides GitHubRepositoryUrl=$GITHUB_REPOSITORY_URL \ GitHubPersonalAccessToken=$GITHUB_PERSONAL_ACCESS_TOKEN \ GitHubTargetResource=$GITHUB_TARGET_RESOURCE \ - GitHubIgnoreBranchRegex=$GITHUB_IGNORE_BRANCH_REGEX \ + GitHubIgnoreBranchRegex="$GITHUB_IGNORE_BRANCH_REGEX" \ CodeBuildProjectName=$CODEBUILD_PROJECT_NAME \ CodeBuildRegion=$CODEBUILD_PROJECT_REGION \ - --region "$AWS_DEFAULT_REGION" \ No newline at end of file + BuildSkippedBy="$BUILD_SKIPPED_BY" \ + --region "$AWS_DEFAULT_REGION" diff --git a/src/functions/github-webhook-handler/index.js b/src/functions/github-webhook-handler/index.js index 9bd0579..99a2682 100644 --- a/src/functions/github-webhook-handler/index.js +++ b/src/functions/github-webhook-handler/index.js @@ -20,8 +20,9 @@ exports.handler = (event, context, callback) => { const eventType = ghEventType(ghEvent), eventAction = ghEvent.action ? ghEvent.action : '', - branchName = ghEvent.ref ? ghEvent.ref : ghEvent.ref.replace('refs/heads','') - if (shouldIgnore(eventType, eventAction, branchName)) { + branchName = ghEvent.ref ? ghEvent.ref : ghEvent.ref.replace('refs/heads',''), + commitMessage = ghEvent.head_commit ? ghEvent.head_commit.message : '' + if (shouldIgnore(eventType, eventAction, branchName, commitMessage)) { callback() } diff --git a/src/functions/github-webhook-handler/lib/should-ignore.js b/src/functions/github-webhook-handler/lib/should-ignore.js index eaf2407..b92b1f0 100644 --- a/src/functions/github-webhook-handler/lib/should-ignore.js +++ b/src/functions/github-webhook-handler/lib/should-ignore.js @@ -1,14 +1,14 @@ 'use strict' // eventType is a string from lib/event-types. -exports.shouldIgnore = (eventType, eventAction, branchName) => { +exports.shouldIgnore = (eventType, eventAction = '', branchName = '', commitMessage = '') => { // Temporarily disabled if (process.env.DO_NOT_RUN+'' === 'true') { console.log('`DO_NOT_RUN` option is enabled. We ignore the webhook event this time.') return true } - let target = process.env.GITHUB_TARGET_RESOURCE + const target = process.env.GITHUB_TARGET_RESOURCE // Ignore if the type of this event is not target if (target !== eventType) { console.log(`${eventType} is not configured as a target. configured target is: ${target}`) @@ -19,14 +19,18 @@ exports.shouldIgnore = (eventType, eventAction, branchName) => { console.log('Closed PR.') return true } + // Ignore if the commit message includes specific text + const ignoreKeyword = process.env.BUILD_SKIPPED_BY + if (eventType === 'push' && commitMessage.indexOf(ignoreKeyword) !== -1) { + console.log(`The push is ignored because the message of the head commit includes the keyword "${ignoreKeyword}".`) + return true + } // Ignore specific branches if (eventType === 'push' && process.env.GITHUB_IGNORE_BRANCH_REGEX.trim() !== '') { let re = new RegExp('^' + process.env.GITHUB_IGNORE_BRANCH_REGEX.trim() + '$', 'g') if (re.test(branchName)) { console.log(`Branch "${branchName}" is ignored by configuration.`) return true - } else { - console.log('NOT MATCHED') } } return false diff --git a/src/functions/github-webhook-handler/lib/should-ignore.test.js b/src/functions/github-webhook-handler/lib/should-ignore.test.js index 16191f7..7d9d5ed 100644 --- a/src/functions/github-webhook-handler/lib/should-ignore.test.js +++ b/src/functions/github-webhook-handler/lib/should-ignore.test.js @@ -27,6 +27,11 @@ describe('should-ignore', () => { process.env.GITHUB_IGNORE_BRANCH_REGEX = 'wip.*' assert.equal(true, shouldIgnore('push', '', 'wip-branch')) }) + it('should ignore the push event if the message of the head commit has the keyword to be ignored', () => { + process.env.GITHUB_TARGET_RESOURCE = 'push' + process.env.BUILD_SKIPPED_BY = 'skip ci' + assert.equal(true, shouldIgnore('push', '', 'master', '[skip ci] This commit should be ignored')) + }) it('should NOT ignore the push event if the branch is NOT ignored by GITHUB_IGNORE_BRANCH_REGEX', () => { process.env.GITHUB_TARGET_RESOURCE = 'push' process.env.GITHUB_IGNORE_BRANCH_REGEX = 'wip.*'