diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..b512c09 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +node_modules \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..b5cd53a --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1,31 @@ +module.exports = { + "extends": ["eslint:recommended"], + "plugins": [], + "parserOptions": {}, + "env": { + "browser": false, + "es6": true, + "node": true, + "mocha": true + }, + "globals": {}, + "rules":{ + "indent": [ + "error", + 4 + ], + "linebreak-style": [ + "error", + "unix" + ], + "quotes": [ + "error", + "single" + ], + "semi": [ + "error", + "never" + ], + "no-console":0 + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de20f2e --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# Node/NPM/YARN +## Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +## Dependency directories +node_modules +## Optional npm cache directory +.npm +## dotenv environment variables file +.env +## Optional eslint cache +.eslintcache + +# AWS SAM +## Transformed templates' directory +.sam/* +!.gitkeep + +# Application parameters +env/* +!env/example.env + +# IDE +.vscode diff --git a/.sam/.gitkeep b/.sam/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/.yarnclean b/.yarnclean new file mode 100644 index 0000000..25bdd14 --- /dev/null +++ b/.yarnclean @@ -0,0 +1,42 @@ +# test directories +__tests__ +test +tests +powered-test + +# asset directories +docs +doc +website +images +assets + +# examples +example +examples + +# code coverage directories +coverage +.nyc_output + +# build scripts +Makefile +Gulpfile.js +Gruntfile.js + +# configs +.tern-project +.gitattributes +.editorconfig +.*ignore +.eslintrc +.jshintrc +.flowconfig +.documentup.json +.yarn-metadata.json +.*.yml +*.yml + +# misc +*.gz +*.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..cb228b6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2017 toricls + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b9631f3 --- /dev/null +++ b/Makefile @@ -0,0 +1,83 @@ +################################################################## +# +# Makefile for building tabiiku-batch and packaging docker image. +# +# General usage: +# - make help +# - make build +# - make test ENV_FILE_PATH=env/example.env +# - make package ENV_FILE_PATH=env/example.env +# - make deploy ENV_FILE_PATH=env/example.env +# - make destroy ENV_FILE_PATH=env/example.env +# - make clean +# +################################################################## +include $(ENV_FILE_PATH) +export $$(shell sed 's/=.*//' $(ENV_FILE_PATH)) + +.PHONY: help build test package deploy destroy clean +.DEFAULT_GOAL := help + +build: dependency-dev ## Install all dependencies including development packages + +test: validate-envvars validate dependency-dev lint-code unit-test ## Validating and linting CloudFormation templates and Lambda functions + +validate-envvars: # Test if required environment variables exist +ifeq ($(GITHUB_REPOSITORY_URL),) + $(error missing the 'GITHUB_REPOSITORY_URL' environment variable, or 'ENV_FILE_PATH' does not exist) +endif +ifeq ($(GITHUB_PERSONAL_ACCESS_TOKEN),) + $(error missing the 'GITHUB_PERSONAL_ACCESS_TOKEN' environment variable, or 'ENV_FILE_PATH' does not exist) +endif +ifeq ($(GITHUB_TARGET_RESOURCE),) + $(error missing the 'GITHUB_TARGET_RESOURCE' environment variable, or 'ENV_FILE_PATH' does not exist) +endif +ifeq ($(AWS_DEFAULT_REGION),) + $(error missing the 'AWS_DEFAULT_REGION' environment variable, or 'ENV_FILE_PATH' does not exist) +endif +ifeq ($(CODEBUILD_PROJECT_NAME),) + $(error missing the 'CODEBUILD_PROJECT_NAME' environment variable, or 'ENV_FILE_PATH' does not exist) +endif +ifeq ($(CODEBUILD_PROJECT_REGION),) + $(error missing the 'CODEBUILD_PROJECT_REGION' environment variable, or 'ENV_FILE_PATH' does not exist) +endif + +validate: + @./scripts/validate $(ENV_FILE_PATH) + +dependency: + @./scripts/dependency production + +dependency-dev: + @./scripts/dependency + +lint-code: + @./scripts/lint + +unit-test: + @./scripts/test + +package: validate-envvars validate clean dependency package-sam ## Install all dependencies and package stuffs + +package-sam: +ifeq ($(S3_SAM_ARTIFACTS_BUCKET_NAME),) + $(error missing the 'S3_SAM_ARTIFACTS_BUCKET_NAME' environment variable, or 'ENV_FILE_PATH' does not exist) +endif + @./scripts/package $(S3_SAM_ARTIFACTS_BUCKET_NAME) $(CODEBUILD_PROJECT_NAME) + +deploy: package deploy-sam ## Deploy all CloudFormation templates and Lambda functions + +deploy-sam: +ifeq ($(S3_SAM_ARTIFACTS_BUCKET_NAME),) + $(error missing the 'S3_SAM_ARTIFACTS_BUCKET_NAME' environment variable, or 'ENV_FILE_PATH' does not exist) +endif + @./scripts/deploy $(ENV_FILE_PATH) + +clean: ## Remove local generated files and dependencies + @./scripts/clean + +destroy: ## Remove provisioned resources on AWS + @./scripts/destroy $(ENV_FILE_PATH) + +help: + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-10s\033[0m %s\n", $$1, $$2}' \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..0638e47 --- /dev/null +++ b/README.md @@ -0,0 +1,193 @@ +# github-codebuild-integration + +[![GitHub release](http://img.shields.io/github/release/toricls/github-codebuild-integration.svg?style=flat-square)][release] +[![MIT License](http://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)][license] + +[release]: https://github.com/toricls/github-codebuild-integration/releases +[license]: https://github.com/toricls/github-codebuild-integration/blob/master/LICENSE + +github-codebuild-integration is a CI dispatching/status handling tool to integrate AWS CodeBuild with GitHub Push/Pull-Request events, created with love of Serverless Architecture. + +## Overview + +Yay, Serverless! + +TODO: Put a diagram or something here. + +## Features + +- Invoking a pre-configured AWS CodeBuild project by hooking Push or Pull Reqeust events. +- Setting GitHub's CI status based on status/result of builds on AWS CodeBuild. + +### AWS account / github-codebuild-integration / GitHub repository + +github-codebuild-integration allows you to provision multiple installations in one AWS account as follows: + +Resources | Relation +---------- | ---------- +AWS account : github-codebuild-integration installations | 1 : n +github-codebuild-integration installation : GitHub repository | 1 : 1 +GitHub repository : AWS CodeBuild project | 1 : 1 (will be extended to 1 : n in the future) + +As mentioned above, github-codebuild-integration can be installed as many as you want to integrate with your GitHub repositories. If you want to build 3 repositories, you may provision 3 of github-codebuild-integration installation for instance. + +## Background + +GitHub has a feature to show each commit's status like 'success', 'failure', 'pending' on their Commit/PR pages, and based on that status, we can protect any branches from CI failed branch to be merged. + +GitHub accepts status creation via their APIs and many third-party CI services implement functionalities to integrate with that APIs to show their job status on GitHub. + +On the other hand, AWS CodeBuild doesn't have such a feature to save its build project status to GitHub for now. github-codebuild-integration is a missing piece of AWS CodeBuild to make things better. + +## Requirements & Installation + +### Prerequisites + +github-codebuild-integration requires the following to be installed on your AWS account. + +### Required Tools + +We provide Makefile to you to manage github-codebuild-integration's lifecycle. + +- GNU Make (if you are using macOS, `brew install make` is handy) + +Provided commands use the following tools: + +- Node.js v6.10 or later +- Yarn v0.27.5 or later +- AWS-CLI 1.11.132 or later +- curl + +### Required Accounts & Resources + +- AWS Account +- `AdministratorAccess` to your AWS Account (to use AWS CloudFormation in the installation command) +- GitHub Account + +And the listed resources below are created in the process of installation, which means they are required as available AWS services in a region where you want to run github-codebuild-integration. + +- Amazon S3 +- Amazon SNS +- AWS Lambda +- AWS Step Functions +- AWS CodeBuild +- AWS IAM +- AWS CloudFormation + +### Installation + +_**NOTE: Make sure your [AWS credentials have been loaded](http://docs.aws.amazon.com/cli/latest/userguide/cli-chap-getting-started.html) before proceeding the following steps.**_ + +### AWS Account-wide Resource + +We have to create an S3 Bucket to store github-codebuild-integration's artifacts to provision it. + +``` +$ aws s3api create-bucket \ + --bucket {YOUR_S3_BUCKET_NAME} \ + --create-bucket-configuration LocationConstraint=$AWS_DEFAULT_REGION +``` + +_**NOTE: If you plan installing github-codebuild-integration into multiple AWS regions, you may create an S3 bucket for each AWS region.**_ + +### Per-Project Resources + +#### Configure for your GitHub repository + +Copy example configuration file and edit it to configure paramters for your GitHub repository. + +``` +$ export YOUR_PROJECT_NAME=xxxxxxxxxxxxxxxxx +$ cp env/example.env env/$YOUR_PROJECT_NAME.env +$ editor env/$YOUR_PROJECT_NAME.env +``` + +Next table describes about all available parameters of github-codebuild-integration. + +Required | Parameter Name | What is this | Example +------------ | ------------ | ------------- | ------------- +yes | S3_SAM_ARTIFACTS_BUCKET_NAME | An S3 bucket to store AWS SAM's artifacts. Set the name of the S3 bucket you created on previous step. | your.sam.artifacts.bucket +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.* +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 + +#### Install + +Package all artifacts and deploy to your AWS account. + +``` +$ make deploy ENV_FILE=env/$YOUR_PROJECT_NAME.env +``` + +## Uninstall + +You can delete most of generated resources by executing: + +``` +$ make destroy ENV_FILE=env/YOUR-PROJECT-NAME.env +``` + +_**NOTE: CloudFormation doesn't delete CloudWatch's Log Groups. You may want to remove it manually on the AWS Management Console or via the AWS CLI. Also you may want to remove the S3 Bucket(s) you created.**_ + +## FAQ + +### Installation & Uninstallation + +Q. My IAM role is too weak to install your tool, I guess. + +A. Ask your administrator and show him/her the following: +- [Required Accounts & Resources][required-accounts--resources] section +- This tool uses CloudFormation with `--capabilities "CAPABILITY_IAM"` option + +[required-accounts--resources]: https://github.com/toricls/github-codebuild-integration/blob/master/README.md#required-accounts--resources + +Q: I want to remove all resources of github-codebuild-integration from my AWS account. + +A: Read the [Uninstall][uninstall] section above :X + +[uninstall]: https://github.com/toricls/github-codebuild-integration/blob/master/README.md#uninstall + +### Changing Configurations + +Q: I changed my repository name after github-codebuild-integration install. + +A: Change the value of `GITHUB_REPOSITORY_URL` in your env file, then deploy again. + +Q: I want to stop CI invoking for a bit. + +A: Open `GitHubWebhookHandler` function (the function name on the Lambda Management Console may something like `YOUR-PROJECT-NAME-GitHubWebhookHandler-XXXXXXXXXXX`), then set `true` to the environment variable `DO_NOT_RUN`. +Don't forget to back that value to `false` after your quick work. + +### Feature Request + +Q: I want to skip CI by adding a tag like `[skip ci]` in commit messages. + +A: It is planned, but not now. + +Q: I need more than one AWS CodeBuild project for my GitHub repository. + +A: I totally agree with you! It will be supported in the future. I think the feature will be implemented with a mapping configuration for 'branch name reg-expressions' and 'AWS CodeBuild projects'. But PRs are always welcome :smiley: + +Q. Can you change the icon which shown at PR page's CI status? + +A. GitHub shows the avatar of the user who owns the personal access token you provided. You can change the icon by using something like [Machine users](https://developer.github.com/v3/guides/managing-deploy-keys/#machine-users) to create a personal access token for github-codebuild-integration. + +## Contribution + +1. Fork ([https://github.com/toricls/github-codebuild-integration/fork](https://github.com/toricls/github-codebuild-integration/fork)) +1. Create a feature branch +1. Commit your changes +1. Rebase your local changes against the master branch +1. Create a new Pull Request + +## Licence + +[MIT](LICENCE) + +## Author + +[toricls](https://github.com/toricls) diff --git a/buildspec.yml b/buildspec.yml new file mode 100644 index 0000000..9e6e889 --- /dev/null +++ b/buildspec.yml @@ -0,0 +1,38 @@ +version: 0.1 + +# This buildspec.yml requires a AWS CodeBuild project as follows: +# - Environment: +# - Operating system: Ubuntu +# - Runtime: Node.js +# - Version: aws/codebuild/nodejs:6.3.1 +# - Service role: +# - it requires 'cloudformation:ValidateTemplate' in addition to a generated role. +# e.g. +# { +# "Version": "2012-10-17", +# "Statement": [ +# { +# "Sid": "0", +# "Effect": "Allow", +# "Action": [ +# "cloudformation:ValidateTemplate" +# ], +# "Resource": [ +# "*" +# ] +# } +# ] +# } +# + +phases: + install: + commands: + # Node, NPM, AWS-CLI are preinstalled on this CodeBuild image. + - sudo apt-get update -y && sudo apt-get install -y make apt-transport-https + - curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - + - echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list + - sudo apt-get update -y && sudo apt-get install -y yarn + build: + commands: + - make test ENV_FILE_PATH=env/example.env diff --git a/env/example.env b/env/example.env new file mode 100644 index 0000000..286f336 --- /dev/null +++ b/env/example.env @@ -0,0 +1,10 @@ +# COPY THIS FILE AND RENAME/EDIT FOR YOUR PROJECT :) +# +S3_SAM_ARTIFACTS_BUCKET_NAME=your.sam.artifacts.bucket +GITHUB_REPOSITORY_URL=https://github.com/your-org/your-repo +GITHUB_PERSONAL_ACCESS_TOKEN=your-github-personal-access-token +GITHUB_TARGET_RESOURCE=push +GITHUB_IGNORE_BRANCH_REGEX=wip.* +AWS_DEFAULT_REGION=us-east-1 +CODEBUILD_PROJECT_NAME=your-codebuild-project-name +CODEBUILD_PROJECT_REGION=us-east-1 diff --git a/package.json b/package.json new file mode 100644 index 0000000..7aad74c --- /dev/null +++ b/package.json @@ -0,0 +1,31 @@ +{ + "name": "github-codebuild-integration", + "version": "0.1.0", + "description": "", + "scripts": { + "test": "mocha $(find src -name '*.test.js')", + "lint": "eslint --ext .js src test" + }, + "engines": { + "node": ">=6.1" + }, + "repository": { + "type": "git", + "url": "https://github.com/toricls/github-codebuild-integration.git" + }, + "keywords": [ + "github", + "aws codebuild", + "amazon sns" + ], + "author": "toricls", + "license": "MIT", + "bugs": { + "url": "https://github.com/toricls/github-codebuild-integration/issues" + }, + "homepage": "https://github.com/toricls/github-codebuild-integration", + "devDependencies": { + "eslint": "^4.5.0", + "mocha": "^3.5.0" + } +} diff --git a/sam.yml b/sam.yml new file mode 100644 index 0000000..aa32a1c --- /dev/null +++ b/sam.yml @@ -0,0 +1,283 @@ +AWSTemplateFormatVersion: '2010-09-09' +Transform: AWS::Serverless-2016-10-31 +Description: Creates resources for github-codebuild-integration +Parameters: + # see env/example.env about parameters + GitHubRepositoryUrl: + Type: String + GitHubPersonalAccessToken: + Type: String + GitHubTargetResource: + Type: String + GitHubIgnoreBranchRegex: + Type: String + CodeBuildProjectName: + Type: String + CodeBuildRegion: + Type: String + +Resources: + # AWS SAM doesn't support `Transform` in nested templates, we includes all children into main template + # see https://github.com/awslabs/serverless-application-model/issues/90 + ########################## + # SNSStack + ########################## + GitHubEventSNSTopic: + Type: "AWS::SNS::Topic" + ########################## + # IAMStack + ########################## + GitHubIAMUser: + Type: "AWS::IAM::User" + Properties: + Policies: + - PolicyName: !Sub "${CodeBuildProjectName}-github-sns-role" + PolicyDocument: + Statement: + - Effect: Allow + Action: "sns:Publish" + Resource: !Ref GitHubEventSNSTopic + GitHubIAMUserAccessKey: + Type: "AWS::IAM::AccessKey" + Properties: + UserName: !Ref GitHubIAMUser + ########################## + # GitHubWebhookStack + ########################## + GitHubWebhookCustomResourceRole: + Type: "AWS::IAM::Role" + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: "sts:AssumeRole" + Policies: + - PolicyName: !Sub "${CodeBuildProjectName}-github-webhook-lambda-execution-role" + PolicyDocument: + Statement: + - Effect: Allow + Action: + - "logs:CreateLogGroup" + - "logs:CreateLogStream" + - "logs:PutLogEvents" + Resource: "arn:aws:logs:*:*:*" + GitHubWebhookCustomResource: + Type: "AWS::Serverless::Function" + Properties: + Handler: index.handler + Role: !GetAtt GitHubWebhookCustomResourceRole.Arn + CodeUri: ./src/functions/github-webhook-resource + Runtime: nodejs6.10 + Timeout: 30 + Environment: + Variables: + GITHUB_TOKEN: !Ref GitHubPersonalAccessToken + GITHUB_REPOSITORY_URL: !Ref GitHubRepositoryUrl + GITHUB_TARGET_RESOURCE: !Ref GitHubTargetResource + SNS_ACCESS_KEY_ID: !Ref GitHubIAMUserAccessKey + SNS_SECRET_ACCESS_KEY: !GetAtt GitHubIAMUserAccessKey.SecretAccessKey + SNS_REGION: !Ref "AWS::Region" + SNS_TOPIC: !Ref GitHubEventSNSTopic + GitHubWebhook: + Type: "Custom::GitHubWebhook" + Properties: + ServiceToken: !GetAtt GitHubWebhookCustomResource.Arn + # Define all variables to re-create via `make deploy` when parameters have changed + GITHUB_TOKEN: !Ref GitHubPersonalAccessToken + GITHUB_REPOSITORY_URL: !Ref GitHubRepositoryUrl + GITHUB_TARGET_RESOURCE: !Ref GitHubTargetResource + SNS_ACCESS_KEY_ID: !Ref GitHubIAMUserAccessKey + SNS_SECRET_ACCESS_KEY: !GetAtt GitHubIAMUserAccessKey.SecretAccessKey + SNS_REGION: !Ref "AWS::Region" + SNS_TOPIC: !Ref GitHubEventSNSTopic + ########################## + # LambdaStack + ########################## + LambdaExecutionRole: + Type: "AWS::IAM::Role" + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: "sts:AssumeRole" + Policies: + - PolicyName: !Sub "${CodeBuildProjectName}-lambda-execution-role" + PolicyDocument: + Statement: + - Effect: Allow + Action: + - "logs:CreateLogGroup" + - "logs:CreateLogStream" + - "logs:PutLogEvents" + Resource: "arn:aws:logs:*:*:*" + - Effect: Allow + Action: + - "codebuild:StartBuild" + - "codebuild:BatchGetBuilds" + Resource: !Sub "arn:aws:codebuild:${AWS::Region}:${AWS::AccountId}:project/${CodeBuildProjectName}" + BuildDispatcher: + Type: "AWS::Serverless::Function" + Properties: + Role: !GetAtt LambdaExecutionRole.Arn + Handler: index.handler + Runtime: nodejs6.10 + CodeUri: ./src/functions/build-dispatcher + Timeout: 10 + MemorySize: 128 + Environment: + Variables: + CODEBUILD_PROJECT_REGION: !Ref CodeBuildRegion + CODEBUILD_PROJECT_NAME: !Ref CodeBuildProjectName + GITHUB_TOKEN: !Ref GitHubPersonalAccessToken + GITHUB_REPOSITORY_URL: !Ref GitHubRepositoryUrl + BuildResultExporter: + Type: "AWS::Serverless::Function" + Properties: + Role: !GetAtt LambdaExecutionRole.Arn + Handler: index.handler + Runtime: nodejs6.10 + CodeUri: ./src/functions/build-result-exporter + Timeout: 10 + MemorySize: 128 + BuildResultNotifier: + Type: "AWS::Serverless::Function" + Properties: + Role: !GetAtt LambdaExecutionRole.Arn + Handler: index.handler + Runtime: nodejs6.10 + CodeUri: ./src/functions/build-result-notifier + Timeout: 10 + MemorySize: 128 + Environment: + Variables: + CODEBUILD_PROJECT_REGION: !Ref CodeBuildRegion + GITHUB_TOKEN: !Ref GitHubPersonalAccessToken + GITHUB_REPOSITORY_URL: !Ref GitHubRepositoryUrl + ########################## + # StepFunctionsStack + ########################## + SFLambdaExecutionRole: + Type: "AWS::IAM::Role" + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Principal: + Service: lambda.amazonaws.com + Action: "sts:AssumeRole" + Policies: + - PolicyName: !Sub "${CodeBuildProjectName}-sf-lambda-execution-role" + PolicyDocument: + Statement: + - Effect: Allow + Action: + - "logs:CreateLogGroup" + - "logs:CreateLogStream" + - "logs:PutLogEvents" + Resource: "arn:aws:logs:*:*:*" + - Effect: Allow + Action: "states:StartExecution" + Resource: !Ref BuildStateMachine + GitHubWebhookHandler: + Type: "AWS::Serverless::Function" + Properties: + Role: !GetAtt SFLambdaExecutionRole.Arn + Handler: index.handler + Runtime: nodejs6.10 + CodeUri: ./src/functions/github-webhook-handler + Timeout: 10 + MemorySize: 128 + Events: + WebhookReceive: + Type: SNS + Properties: + Topic: !Ref GitHubEventSNSTopic + Environment: + Variables: + DO_NOT_RUN: false + STEP_FUNCTIONS_ARN: !Ref BuildStateMachine + CODEBUILD_PROJECT_REGION: !Ref CodeBuildRegion + GITHUB_TOKEN: !Ref GitHubPersonalAccessToken + GITHUB_REPOSITORY_URL: !Ref GitHubRepositoryUrl + GITHUB_TARGET_RESOURCE: !Ref GitHubTargetResource + GITHUB_IGNORE_BRANCH_REGEX: !Ref GitHubIgnoreBranchRegex + StatesExecutionRole: + Type: "AWS::IAM::Role" + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Principal: + Service: + - !Sub states.${AWS::Region}.amazonaws.com + Action: "sts:AssumeRole" + Path: "/" + Policies: + - PolicyName: StatesExecutionPolicy + PolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: Allow + Action: + - "lambda:InvokeFunction" + Resource: "*" + BuildStateMachine: + Type: "AWS::StepFunctions::StateMachine" + Properties: + DefinitionString: !Sub + |- + { + "StartAt": "Dispatch Build", + "States": { + "Dispatch Build": { + "Type": "Task", + "Resource": "${BuildDispatcher.Arn}", + "Next": "Wait 10 Seconds" + }, + "Wait 10 Seconds": { + "Type": "Wait", + "Seconds": 10, + "Next": "Export Build Result" + }, + "Export Build Result": { + "Type": "Task", + "Resource": "${BuildResultExporter.Arn}", + "Next": "Test If Build Finished" + }, + "Test If Build Finished": { + "Type": "Choice", + "Choices": [ + { + "Variable": "$.buildComplete", + "BooleanEquals": true, + "Next": "Notify Build Result" + } + ], + "Default": "Wait 10 Seconds" + }, + "Notify Build Result": { + "Type": "Task", + "Resource": "${BuildResultNotifier.Arn}", + "End": true + } + } + } + RoleArn: !GetAtt StatesExecutionRole.Arn + +Outputs: + GitHubEventSNSTopic: + Value: !Ref GitHubEventSNSTopic + GitHubIAMUserAccessKeyID: + Value: !Ref GitHubIAMUserAccessKey + GitHubIAMUserSecretAccessKey: + Value: !GetAtt GitHubIAMUserAccessKey.SecretAccessKey + GitHubWebhookID: + Value: !GetAtt GitHubWebhook.HookId diff --git a/scripts/clean b/scripts/clean new file mode 100755 index 0000000..e00cb45 --- /dev/null +++ b/scripts/clean @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/clean +=================================================== +EOF + +echo "Cleaning AWS SAM's local store" +rm -f ./.sam/*.yml + +for dir in ./src/functions/*; do + echo "Cleaning dependencies for $dir" + pushd $dir > /dev/null + yarn clean + popd > /dev/null +done diff --git a/scripts/dependency b/scripts/dependency new file mode 100755 index 0000000..b042038 --- /dev/null +++ b/scripts/dependency @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/dependency +=================================================== +EOF + +echo "Installing global dependencies" +yarn install + +ENVIRONMENT=$1 +YARN_OPTS= + +if [ "x$ENVIRONMENT" == "xproduction" ]; then + YARN_OPTS=" --production --prefer-offline" + echo "Configured as production mode." +fi + +echo "Installing functions' dependencies" + +for dir in ./src/functions/*; do + echo "Installing dependencies for $dir" + pushd $dir > /dev/null + yarn install $YARN_OPTS + popd > /dev/null +done diff --git a/scripts/deploy b/scripts/deploy new file mode 100755 index 0000000..35f1e04 --- /dev/null +++ b/scripts/deploy @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/deploy +=================================================== +EOF + +ENV_FILE_PATH=$1 +source $ENV_FILE_PATH +TEMPLATE=".sam/packaged-$CODEBUILD_PROJECT_NAME.yml" +CFN_STACK_NAME="$CODEBUILD_PROJECT_NAME" + +# deploy +aws cloudformation deploy \ + --template-file "$TEMPLATE" \ + --stack-name "$CFN_STACK_NAME" \ + --capabilities "CAPABILITY_IAM" \ + --parameter-overrides GitHubRepositoryUrl=$GITHUB_REPOSITORY_URL \ + GitHubPersonalAccessToken=$GITHUB_PERSONAL_ACCESS_TOKEN \ + GitHubTargetResource=$GITHUB_TARGET_RESOURCE \ + GitHubIgnoreBranchRegex=$GITHUB_IGNORE_BRANCH_REGEX \ + CodeBuildProjectName=$CODEBUILD_PROJECT_NAME \ + CodeBuildRegion=$CODEBUILD_PROJECT_REGION \ + --region "$AWS_DEFAULT_REGION" \ No newline at end of file diff --git a/scripts/destroy b/scripts/destroy new file mode 100755 index 0000000..b6ce12a --- /dev/null +++ b/scripts/destroy @@ -0,0 +1,18 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/destroy +=================================================== +EOF + +ENV_FILE_PATH=$1 +source $ENV_FILE_PATH +CFN_STACK_NAME="$CODEBUILD_PROJECT_NAME" + +# delete stack +aws cloudformation delete-stack --stack-name "$CFN_STACK_NAME" --region "$AWS_DEFAULT_REGION" +echo 'Waiting for stack delete to complete' +aws cloudformation wait stack-delete-complete --stack-name "$CFN_STACK_NAME" --region "$AWS_DEFAULT_REGION" diff --git a/scripts/lint b/scripts/lint new file mode 100755 index 0000000..fa15b17 --- /dev/null +++ b/scripts/lint @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/lint +=================================================== +EOF + +yarn run lint diff --git a/scripts/package b/scripts/package new file mode 100755 index 0000000..34864cc --- /dev/null +++ b/scripts/package @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/package +=================================================== +EOF + +S3_SAM_ARTIFACTS_BUCKET_NAME="$1" +CODEBUILD_PROJECT_NAME="$2" + +MAIN_TEMPLATE="sam.yml" +OUT=".sam/packaged-$CODEBUILD_PROJECT_NAME.yml" +S3_PREFIX="$CODEBUILD_PROJECT_NAME/$(date '+%Y%m%d-%H%M%S')" + +# package +aws cloudformation package \ + --template-file "$MAIN_TEMPLATE" \ + --s3-bucket "$S3_SAM_ARTIFACTS_BUCKET_NAME" \ + --s3-prefix "$S3_PREFIX" \ + --output-template-file "$OUT" diff --git a/scripts/test b/scripts/test new file mode 100755 index 0000000..307b6a1 --- /dev/null +++ b/scripts/test @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/test +=================================================== +EOF + +yarn run test diff --git a/scripts/validate b/scripts/validate new file mode 100755 index 0000000..6ac545a --- /dev/null +++ b/scripts/validate @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +set -e + +cat << EOF +=================================================== + scripts/validate +=================================================== +EOF + +ENV_FILE_PATH=$1 +source $ENV_FILE_PATH + +# Validate main template +echo "Validating AWS SAM template" +aws cloudformation validate-template --template-body file://sam.yml --region $AWS_DEFAULT_REGION + +# Validate configurations in $ENV_FILE_PATH +## GITHUB_TARGET_RESOURCE +echo "Validating the value of target GitHub event (GITHUB_TARGET_RESOURCE)" +matched=0 +if [ "x$GITHUB_TARGET_RESOURCE" == "xpr" ]; then + matched=$((matched+1)) +fi +if [ "x$GITHUB_TARGET_RESOURCE" == "xpush" ]; then + matched=$((matched+1)) +fi +if [ $matched -ne 1 ]; then + echo "ERROR: '$GITHUB_TARGET_RESOURCE' is not available as GITHUB_TARGET_RESOURCE value. Use one of following: push, pr" 1>&2 + exit 1 +fi + +if [ "x$ENV_FILE_PATH" == "xenv/example.env" ]; then + echo "Skipping rest because this context may run by CI process" + exit 0 +fi + +## GITHUB_PERSONAL_ACCESS_TOKEN +echo "Validating the value of GitHub personal access token (GITHUB_PERSONAL_ACCESS_TOKEN)" +response=$( curl -s -I https://api.github.com/rate_limit -H "Authorization: token $GITHUB_PERSONAL_ACCESS_TOKEN" ) +expected_scopes='X-OAuth-Scopes: admin:repo_hook, repo:status' +retrieved_scopes=$( echo "$response" | grep 'X-OAuth-Scopes: ' ) +if echo "$response" | grep -Fq "$expected_scopes"; then + echo "Retrieved scopes: $retrieved_scopes" +else + echo "ERROR: The GitHub personal access token you provided does not meet the requirement of github-codebuild-integration" 1>&2 + echo "ERROR: Retrieved scopes: $retrieved_scopes" + echo "ERROR: Expected scopes: $expected_scopes" + exit 2 +fi +## CODEBUILD_PROJECT_NAME +echo "Validating the existence of the AWS CodeBuild project (CODEBUILD_PROJECT_NAME, CODEBUILD_PROJECT_REGION)" +fetched_project_name=$( aws codebuild batch-get-projects --names "$CODEBUILD_PROJECT_NAME" --region "$CODEBUILD_PROJECT_REGION" --query 'projects[0].name' --output text ) +if [ "x$fetched_project_name" != "x$CODEBUILD_PROJECT_NAME" ]; then + echo "ERROR: There is not AWS CodeBuild project which named as '$CODEBUILD_PROJECT_NAME' in the region '$CODEBUILD_PROJECT_REGION'." 1>&2 + echo "ERROR: You should create your own AWS CodeBuild project with that name before installing github-codebuild-integration" 1>&2 + exit 3 +fi diff --git a/src/functions/build-dispatcher/.yarnclean b/src/functions/build-dispatcher/.yarnclean new file mode 100644 index 0000000..25bdd14 --- /dev/null +++ b/src/functions/build-dispatcher/.yarnclean @@ -0,0 +1,42 @@ +# test directories +__tests__ +test +tests +powered-test + +# asset directories +docs +doc +website +images +assets + +# examples +example +examples + +# code coverage directories +coverage +.nyc_output + +# build scripts +Makefile +Gulpfile.js +Gruntfile.js + +# configs +.tern-project +.gitattributes +.editorconfig +.*ignore +.eslintrc +.jshintrc +.flowconfig +.documentup.json +.yarn-metadata.json +.*.yml +*.yml + +# misc +*.gz +*.md diff --git a/src/functions/build-dispatcher/index.js b/src/functions/build-dispatcher/index.js new file mode 100644 index 0000000..103b01f --- /dev/null +++ b/src/functions/build-dispatcher/index.js @@ -0,0 +1,63 @@ +'use strict' + +// TODO: too dirty + +const AWS = require('aws-sdk'), + codebuild = new AWS.CodeBuild() + +const GitHubApi = require('github'), + github = new GitHubApi({version: '3.0.0'}) + +const ghUrl = require('parse-github-url'), + repo = ghUrl(process.env.GITHUB_REPOSITORY_URL) + +const region = process.env.CODEBUILD_PROJECT_REGION + +github.authenticate({type:'oauth', token: process.env.GITHUB_TOKEN}) + +exports.handler = (event, context, callback) => { + context.callbackWaitsForEmptyEventLoop = false + console.log('Received event:', JSON.stringify(event, null, 2)) + const sha = event.pull_request ? event.pull_request.head.sha : event.head_commit.id + const params = { + projectName: process.env.CODEBUILD_PROJECT_NAME, + sourceVersion: sha + } + codebuild.startBuild(params, (err, data) => { + // Create GitHub status + if (err) { + // If CodeBuild cannot start a build, save GitHub status as 'error' + console.log(err, err.stack) + github.repos.createStatus({ + owner: repo.owner, + repo: repo.name, + sha: sha, + state: 'error', + target_url: `https://${region}.console.aws.amazon.com/codebuild/home?region=${region}#/builds`, + context: 'codebuild', + description: 'AWS CodeBuild has failed to start your tests' + }).then(() => { + callback(err) + }).catch((err) => { + callback(err) + }) + } else { + let build = data.build + github.repos.createStatus({ + owner: repo.owner, + repo: repo.name, + sha: sha, + state: 'pending', + target_url: `https://${region}.console.aws.amazon.com/codebuild/home?region=${region}#/builds/${data.build.id}/view/new`, + context: 'codebuild', + description: 'AWS CodeBuild is running your tests' + }).then((data) => { + console.log(data) + callback(null, build) + }).catch((err) => { + console.log(err, err.stack) + callback(err) + }) + } + }) +} diff --git a/src/functions/build-dispatcher/package.json b/src/functions/build-dispatcher/package.json new file mode 100644 index 0000000..85fd4ec --- /dev/null +++ b/src/functions/build-dispatcher/package.json @@ -0,0 +1,16 @@ +{ + "name": "build-dispatcher", + "description": "", + "engines": { + "node": ">=6.1" + }, + "author": "toricls", + "license": "MIT", + "dependencies": { + "github": "^9.3.1", + "parse-github-url": "^1.0.0" + }, + "devDependencies": { + "aws-sdk": "^2.102.0" + } +} diff --git a/src/functions/build-dispatcher/yarn.lock b/src/functions/build-dispatcher/yarn.lock new file mode 100644 index 0000000..2ba156a --- /dev/null +++ b/src/functions/build-dispatcher/yarn.lock @@ -0,0 +1,159 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +agent-base@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" + dependencies: + extend "~3.0.0" + semver "~5.0.1" + +aws-sdk@^2.102.0: + version "2.102.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.102.0.tgz#70e52a8eff63de4c68e1d08c5c37db5561324340" + dependencies: + buffer "4.9.1" + crypto-browserify "1.0.9" + events "^1.1.1" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.0.1" + xml2js "0.4.17" + xmlbuilder "4.2.1" + +base64-js@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + +buffer@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +crypto-browserify@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" + +debug@2, debug@^2.2.0: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +events@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +extend@3, extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +follow-redirects@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919" + dependencies: + debug "^2.2.0" + stream-consume "^0.1.0" + +github@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/github/-/github-9.3.1.tgz#6a3c5a9cc2a1cd0b5d097a47baefb9d11caef89e" + dependencies: + follow-redirects "0.0.7" + https-proxy-agent "^1.0.0" + mime "^1.2.11" + netrc "^0.1.4" + +https-proxy-agent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + dependencies: + agent-base "2" + debug "2" + extend "3" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + +lodash@^4.0.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +mime@^1.2.11: + version "1.3.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +netrc@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" + +parse-github-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.0.tgz#d0c50b592d5a252c61a8540a421dfe8e571cf45a" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver@~5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + +stream-consume@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +xml2js@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + dependencies: + sax ">=0.6.0" + xmlbuilder "^4.1.0" + +xmlbuilder@4.2.1, xmlbuilder@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" diff --git a/src/functions/build-result-exporter/.yarnclean b/src/functions/build-result-exporter/.yarnclean new file mode 100644 index 0000000..25bdd14 --- /dev/null +++ b/src/functions/build-result-exporter/.yarnclean @@ -0,0 +1,42 @@ +# test directories +__tests__ +test +tests +powered-test + +# asset directories +docs +doc +website +images +assets + +# examples +example +examples + +# code coverage directories +coverage +.nyc_output + +# build scripts +Makefile +Gulpfile.js +Gruntfile.js + +# configs +.tern-project +.gitattributes +.editorconfig +.*ignore +.eslintrc +.jshintrc +.flowconfig +.documentup.json +.yarn-metadata.json +.*.yml +*.yml + +# misc +*.gz +*.md diff --git a/src/functions/build-result-exporter/index.js b/src/functions/build-result-exporter/index.js new file mode 100644 index 0000000..ff6bb79 --- /dev/null +++ b/src/functions/build-result-exporter/index.js @@ -0,0 +1,22 @@ +'use strict' + +const AWS = require('aws-sdk'), + codebuild = new AWS.CodeBuild() + +exports.handler = (event, context, callback) => { + context.callbackWaitsForEmptyEventLoop = false + //console.log('Received event:', JSON.stringify(event, null, 2)) + const params = { + ids: [event.id] + } + codebuild.batchGetBuilds(params, function(err, data) { + if (err) { + console.log(err, err.stack) + context.fail(err) + callback(err) + } else { + //console.log('Build: ', JSON.stringify(data.builds, null, 2)) + callback(null, data.builds[0]) + } + }) +} diff --git a/src/functions/build-result-exporter/package.json b/src/functions/build-result-exporter/package.json new file mode 100644 index 0000000..6e728e0 --- /dev/null +++ b/src/functions/build-result-exporter/package.json @@ -0,0 +1,12 @@ +{ + "name": "build-result-exporter", + "description": "", + "engines": { + "node": ">=6.1" + }, + "author": "toricls", + "license": "MIT", + "devDependencies": { + "aws-sdk": "^2.102.0" + } +} diff --git a/src/functions/build-result-exporter/yarn.lock b/src/functions/build-result-exporter/yarn.lock new file mode 100644 index 0000000..5767744 --- /dev/null +++ b/src/functions/build-result-exporter/yarn.lock @@ -0,0 +1,94 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +aws-sdk@^2.102.0: + version "2.102.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.102.0.tgz#70e52a8eff63de4c68e1d08c5c37db5561324340" + dependencies: + buffer "4.9.1" + crypto-browserify "1.0.9" + events "^1.1.1" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.0.1" + xml2js "0.4.17" + xmlbuilder "4.2.1" + +base64-js@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + +buffer@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +crypto-browserify@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" + +events@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + +lodash@^4.0.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +xml2js@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + dependencies: + sax ">=0.6.0" + xmlbuilder "^4.1.0" + +xmlbuilder@4.2.1, xmlbuilder@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" diff --git a/src/functions/build-result-notifier/.yarnclean b/src/functions/build-result-notifier/.yarnclean new file mode 100644 index 0000000..25bdd14 --- /dev/null +++ b/src/functions/build-result-notifier/.yarnclean @@ -0,0 +1,42 @@ +# test directories +__tests__ +test +tests +powered-test + +# asset directories +docs +doc +website +images +assets + +# examples +example +examples + +# code coverage directories +coverage +.nyc_output + +# build scripts +Makefile +Gulpfile.js +Gruntfile.js + +# configs +.tern-project +.gitattributes +.editorconfig +.*ignore +.eslintrc +.jshintrc +.flowconfig +.documentup.json +.yarn-metadata.json +.*.yml +*.yml + +# misc +*.gz +*.md diff --git a/src/functions/build-result-notifier/index.js b/src/functions/build-result-notifier/index.js new file mode 100644 index 0000000..18c3ae3 --- /dev/null +++ b/src/functions/build-result-notifier/index.js @@ -0,0 +1,36 @@ +'use strict' + +const GitHubApi = require('github'), + github = new GitHubApi({version: '3.0.0'}) +const ghUrl = require('parse-github-url'), + repo = ghUrl(process.env.GITHUB_REPOSITORY_URL) +const region = process.env.CODEBUILD_PROJECT_REGION +const codeBuildStatusToGitHubStatus = require('./lib/codebuild-status-to-github-status').codeBuildStatusToGitHubStatus + +github.authenticate({type:'oauth', token: process.env.GITHUB_TOKEN}) + +exports.handler = (event, context, callback) => { + context.callbackWaitsForEmptyEventLoop = false + //console.log('Received event:', JSON.stringify(event, null, 2)) + console.log(`Build status: ${event.buildStatus}, Commit hash: ${event.sourceVersion}`) + + const status = codeBuildStatusToGitHubStatus(event.buildStatus) + if (status.state === '') { + callback(status.errorMessage) + } + + github.repos.createStatus({ + owner: repo.owner, + repo: repo.name, + sha: event.sourceVersion, + state: status.state, + target_url: `https://${region}.console.aws.amazon.com/codebuild/home?region=${region}#/builds/${event.id}/view/new`, + context: 'codebuild', + description: status.msg + }).then((data) => { + callback(null, data) + }).catch((err) => { + console.log(err, err.stack) + callback(err) + }) +} diff --git a/src/functions/build-result-notifier/lib/codebuild-status-to-github-status.js b/src/functions/build-result-notifier/lib/codebuild-status-to-github-status.js new file mode 100644 index 0000000..4998795 --- /dev/null +++ b/src/functions/build-result-notifier/lib/codebuild-status-to-github-status.js @@ -0,0 +1,35 @@ +'use strict' + +exports.codeBuildStatusToGitHubStatus = (codeBuildStatus) => { + let state = '' + var msg = '' + var errMsg = '' + switch(codeBuildStatus) { + case 'SUCCEEDED': + state = 'success' + msg = 'Your tests passed on AWS CodeBuild!' + break + case 'FAILED': + state = 'failure' + msg = 'Your tests failed on AWS CodeBuild' + break + case 'IN_PROGRESS': + state = 'pending' + msg = 'AWS CodeBuild is running your tests...' + break + case 'FAULT': + case 'STOPPED': + case 'TIMED_OUT': + state = 'error' + msg = 'Something wrong happened on AWS CodeBuild' + break + default: + errMsg = `Unknown CodeBuilg buildStatus: ${codeBuildStatus}` + console.log(errMsg) + } + return { + state: state, + message: msg, + errorMessage: errMsg + } +} \ No newline at end of file diff --git a/src/functions/build-result-notifier/lib/codebuild-status-to-github-status.test.js b/src/functions/build-result-notifier/lib/codebuild-status-to-github-status.test.js new file mode 100644 index 0000000..2d82b1a --- /dev/null +++ b/src/functions/build-result-notifier/lib/codebuild-status-to-github-status.test.js @@ -0,0 +1,40 @@ +'use strict' + +let assert = require('assert') + +let codeBuildStatusToGitHubStatus = require('./codebuild-status-to-github-status').codeBuildStatusToGitHubStatus + +describe('should-ignore', () => { + describe('shouldIgnore', () => { + it('should return success status if CodeBuild has done without any problem', () => { + var result = codeBuildStatusToGitHubStatus('SUCCEEDED') + assert.equal('success', result.state) + }) + it('should return failure status if CodeBuild has been marked as failed', () => { + var result = codeBuildStatusToGitHubStatus('FAILED') + assert.equal('failure', result.state) + }) + it('should return pending status if CodeBuild is running', () => { + var result = codeBuildStatusToGitHubStatus('IN_PROGRESS') + assert.equal('pending', result.state) + }) + it('should return error status if something wrong has happen on CodeBuild', () => { + var result = codeBuildStatusToGitHubStatus('FAULT') + assert.equal('error', result.state) + }) + it('should return error status if CodeBuild has stopped', () => { + var result = codeBuildStatusToGitHubStatus('STOPPED') + assert.equal('error', result.state) + }) + it('should return error status if CodeBuild has timed out', () => { + var result = codeBuildStatusToGitHubStatus('TIMED_OUT') + assert.equal('error', result.state) + }) + it('should return error message if the CodeBuild status is unknown', () => { + var result = codeBuildStatusToGitHubStatus('UNKNOWN_VALUE') + assert.equal('', result.state) + assert.equal('', result.message) + assert.equal('Unknown CodeBuilg buildStatus: UNKNOWN_VALUE', result.errorMessage) + }) + }) +}) diff --git a/src/functions/build-result-notifier/package.json b/src/functions/build-result-notifier/package.json new file mode 100644 index 0000000..b14ec00 --- /dev/null +++ b/src/functions/build-result-notifier/package.json @@ -0,0 +1,16 @@ +{ + "name": "build-result-notifier", + "description": "", + "engines": { + "node": ">=6.1" + }, + "author": "toricls", + "license": "MIT", + "dependencies": { + "github": "^9.3.1", + "parse-github-url": "^1.0.0" + }, + "devDependencies": { + "aws-sdk": "^2.102.0" + } +} diff --git a/src/functions/build-result-notifier/yarn.lock b/src/functions/build-result-notifier/yarn.lock new file mode 100644 index 0000000..2ba156a --- /dev/null +++ b/src/functions/build-result-notifier/yarn.lock @@ -0,0 +1,159 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +agent-base@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" + dependencies: + extend "~3.0.0" + semver "~5.0.1" + +aws-sdk@^2.102.0: + version "2.102.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.102.0.tgz#70e52a8eff63de4c68e1d08c5c37db5561324340" + dependencies: + buffer "4.9.1" + crypto-browserify "1.0.9" + events "^1.1.1" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.0.1" + xml2js "0.4.17" + xmlbuilder "4.2.1" + +base64-js@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + +buffer@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +crypto-browserify@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" + +debug@2, debug@^2.2.0: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +events@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +extend@3, extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +follow-redirects@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919" + dependencies: + debug "^2.2.0" + stream-consume "^0.1.0" + +github@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/github/-/github-9.3.1.tgz#6a3c5a9cc2a1cd0b5d097a47baefb9d11caef89e" + dependencies: + follow-redirects "0.0.7" + https-proxy-agent "^1.0.0" + mime "^1.2.11" + netrc "^0.1.4" + +https-proxy-agent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + dependencies: + agent-base "2" + debug "2" + extend "3" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + +lodash@^4.0.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +mime@^1.2.11: + version "1.3.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +netrc@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" + +parse-github-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.0.tgz#d0c50b592d5a252c61a8540a421dfe8e571cf45a" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver@~5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + +stream-consume@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +xml2js@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + dependencies: + sax ">=0.6.0" + xmlbuilder "^4.1.0" + +xmlbuilder@4.2.1, xmlbuilder@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" diff --git a/src/functions/github-webhook-handler/.yarnclean b/src/functions/github-webhook-handler/.yarnclean new file mode 100644 index 0000000..25bdd14 --- /dev/null +++ b/src/functions/github-webhook-handler/.yarnclean @@ -0,0 +1,42 @@ +# test directories +__tests__ +test +tests +powered-test + +# asset directories +docs +doc +website +images +assets + +# examples +example +examples + +# code coverage directories +coverage +.nyc_output + +# build scripts +Makefile +Gulpfile.js +Gruntfile.js + +# configs +.tern-project +.gitattributes +.editorconfig +.*ignore +.eslintrc +.jshintrc +.flowconfig +.documentup.json +.yarn-metadata.json +.*.yml +*.yml + +# misc +*.gz +*.md diff --git a/src/functions/github-webhook-handler/index.js b/src/functions/github-webhook-handler/index.js new file mode 100644 index 0000000..9bd0579 --- /dev/null +++ b/src/functions/github-webhook-handler/index.js @@ -0,0 +1,63 @@ +'use strict' + +const AWS = require('aws-sdk'), + stepfunctions = new AWS.StepFunctions() +const GitHubApi = require('github'), + github = new GitHubApi({version: '3.0.0'}) +const ghUrl = require('parse-github-url'), + repo = ghUrl(process.env.GITHUB_REPOSITORY_URL) +const region = process.env.CODEBUILD_PROJECT_REGION +const ghEventType = require('./lib/event-types').ghEventType, + shouldIgnore = require('./lib/should-ignore').shouldIgnore + +github.authenticate({type:'oauth', token: process.env.GITHUB_TOKEN}) + +exports.handler = (event, context, callback) => { + context.callbackWaitsForEmptyEventLoop = false + //console.log('Received event:', JSON.stringify(event, null, 2)); + const message = event.Records[0].Sns.Message, + ghEvent = JSON.parse(message) + + const eventType = ghEventType(ghEvent), + eventAction = ghEvent.action ? ghEvent.action : '', + branchName = ghEvent.ref ? ghEvent.ref : ghEvent.ref.replace('refs/heads','') + if (shouldIgnore(eventType, eventAction, branchName)) { + callback() + } + + // Create GitHub pending status + const sha = ghEvent.pull_request ? ghEvent.pull_request.head.sha : ghEvent.head_commit.id + const p = new Promise((resolve) => { + github.repos.createStatus({ + owner: repo.owner, + repo: repo.name, + sha: sha, + state: 'pending', + target_url: `https://${region}.console.aws.amazon.com/codebuild/home?region=${region}#/builds`, + context: 'codebuild', + description: 'AWS CodeBuild is preparing your tests...' + }).then((data) => { + console.log(data) + resolve('status created') + }).catch((err) => { + console.log(err) + resolve('status creation failed') + }) + }) + + // Execute Step Functions + p.then(() => { + const params = { + stateMachineArn: process.env.STEP_FUNCTIONS_ARN, + input: JSON.stringify(ghEvent) + } + stepfunctions.startExecution(params, function(err, data) { + if (err) { + console.log(err, err.stack) + callback(err) + } else { + callback(null, data) + } + }) + }) +} diff --git a/src/functions/github-webhook-handler/lib/event-types.js b/src/functions/github-webhook-handler/lib/event-types.js new file mode 100644 index 0000000..7cd7edc --- /dev/null +++ b/src/functions/github-webhook-handler/lib/event-types.js @@ -0,0 +1,8 @@ +'use strict' + +// ghEvent is a JSON object from GitHub webhook. +exports.ghEventType = (ghEvent) => { + if ('pull_request' in ghEvent) return 'pr' + if ('commits' in ghEvent) return 'push' + console.log('Unknown event found in: ', JSON.stringify(ghEvent, null, 2)) +} diff --git a/src/functions/github-webhook-handler/lib/event-types.test.js b/src/functions/github-webhook-handler/lib/event-types.test.js new file mode 100644 index 0000000..b1a3ece --- /dev/null +++ b/src/functions/github-webhook-handler/lib/event-types.test.js @@ -0,0 +1,19 @@ +'use strict' + +let assert = require('assert') + +let pushedEvent = JSON.parse(require('../../../../test/fixtures/pushed').Records[0].Sns.Message) +let prCreatedEvent = JSON.parse(require('../../../../test/fixtures/pr-created').Records[0].Sns.Message) + +let ghEventType = require('./event-types').ghEventType + +describe('event-types', function() { + describe('ghEventType', function() { + it('should return "push" when the event is pushed event', function() { + assert.equal('push', ghEventType(pushedEvent)) + }) + it('should return "pr" when the event is pr-created event', function() { + assert.equal('pr', ghEventType(prCreatedEvent)) + }) + }) +}) diff --git a/src/functions/github-webhook-handler/lib/should-ignore.js b/src/functions/github-webhook-handler/lib/should-ignore.js new file mode 100644 index 0000000..eaf2407 --- /dev/null +++ b/src/functions/github-webhook-handler/lib/should-ignore.js @@ -0,0 +1,33 @@ +'use strict' + +// eventType is a string from lib/event-types. +exports.shouldIgnore = (eventType, eventAction, branchName) => { + // 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 + // 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}`) + return true + } + // Ignore if it is a PR closing event + if (eventType === 'pr' && eventAction === 'closed') { + console.log('Closed PR.') + 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 new file mode 100644 index 0000000..16191f7 --- /dev/null +++ b/src/functions/github-webhook-handler/lib/should-ignore.test.js @@ -0,0 +1,41 @@ +'use strict' + +let assert = require('assert') + +let shouldIgnore = require('./should-ignore').shouldIgnore + +describe('should-ignore', () => { + describe('shouldIgnore', () => { + it('should ignore the event if DO_NOT_RUN is enabled', () => { + process.env.DO_NOT_RUN = true + assert.equal(true, shouldIgnore()) + }) + it('should ignore the push event if GITHUB_TARGET_RESOURCE is pr', () => { + process.env.GITHUB_TARGET_RESOURCE = 'pr' + assert.equal(true, shouldIgnore('push')) + }) + it('should ignore the pr event if GITHUB_TARGET_RESOURCE is push', () => { + process.env.GITHUB_TARGET_RESOURCE = 'push' + assert.equal(true, shouldIgnore('pr')) + }) + it('should ignore the pr event if it is a closed event', () => { + process.env.GITHUB_TARGET_RESOURCE = 'pr' + assert.equal(true, shouldIgnore('pr', 'closed')) + }) + it('should ignore the push event if the branch is ignored by GITHUB_IGNORE_BRANCH_REGEX', () => { + process.env.GITHUB_TARGET_RESOURCE = 'push' + process.env.GITHUB_IGNORE_BRANCH_REGEX = 'wip.*' + assert.equal(true, shouldIgnore('push', '', 'wip-branch')) + }) + 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.*' + assert.equal(false, shouldIgnore('push', '', 'master')) + }) + afterEach(() => { + delete process.env.DO_NOT_RUN + delete process.env.GITHUB_TARGET_RESOURCE + delete process.env.GITHUB_IGNORE_BRANCH_REGEX + }) + }) +}) diff --git a/src/functions/github-webhook-handler/package.json b/src/functions/github-webhook-handler/package.json new file mode 100644 index 0000000..68f86a7 --- /dev/null +++ b/src/functions/github-webhook-handler/package.json @@ -0,0 +1,16 @@ +{ + "name": "github-webhook-handler", + "description": "", + "engines": { + "node": ">=6.1" + }, + "author": "toricls", + "license": "MIT", + "dependencies": { + "github": "^9.3.1", + "parse-github-url": "^1.0.0" + }, + "devDependencies": { + "aws-sdk": "^2.102.0" + } +} diff --git a/src/functions/github-webhook-handler/yarn.lock b/src/functions/github-webhook-handler/yarn.lock new file mode 100644 index 0000000..2ba156a --- /dev/null +++ b/src/functions/github-webhook-handler/yarn.lock @@ -0,0 +1,159 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +agent-base@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" + dependencies: + extend "~3.0.0" + semver "~5.0.1" + +aws-sdk@^2.102.0: + version "2.102.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.102.0.tgz#70e52a8eff63de4c68e1d08c5c37db5561324340" + dependencies: + buffer "4.9.1" + crypto-browserify "1.0.9" + events "^1.1.1" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.0.1" + xml2js "0.4.17" + xmlbuilder "4.2.1" + +base64-js@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + +buffer@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +crypto-browserify@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" + +debug@2, debug@^2.2.0: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +events@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +extend@3, extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +follow-redirects@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919" + dependencies: + debug "^2.2.0" + stream-consume "^0.1.0" + +github@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/github/-/github-9.3.1.tgz#6a3c5a9cc2a1cd0b5d097a47baefb9d11caef89e" + dependencies: + follow-redirects "0.0.7" + https-proxy-agent "^1.0.0" + mime "^1.2.11" + netrc "^0.1.4" + +https-proxy-agent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + dependencies: + agent-base "2" + debug "2" + extend "3" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + +lodash@^4.0.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +mime@^1.2.11: + version "1.3.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +netrc@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" + +parse-github-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.0.tgz#d0c50b592d5a252c61a8540a421dfe8e571cf45a" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver@~5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + +stream-consume@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +xml2js@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + dependencies: + sax ">=0.6.0" + xmlbuilder "^4.1.0" + +xmlbuilder@4.2.1, xmlbuilder@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" diff --git a/src/functions/github-webhook-resource/.yarnclean b/src/functions/github-webhook-resource/.yarnclean new file mode 100644 index 0000000..25bdd14 --- /dev/null +++ b/src/functions/github-webhook-resource/.yarnclean @@ -0,0 +1,42 @@ +# test directories +__tests__ +test +tests +powered-test + +# asset directories +docs +doc +website +images +assets + +# examples +example +examples + +# code coverage directories +coverage +.nyc_output + +# build scripts +Makefile +Gulpfile.js +Gruntfile.js + +# configs +.tern-project +.gitattributes +.editorconfig +.*ignore +.eslintrc +.jshintrc +.flowconfig +.documentup.json +.yarn-metadata.json +.*.yml +*.yml + +# misc +*.gz +*.md diff --git a/src/functions/github-webhook-resource/index.js b/src/functions/github-webhook-resource/index.js new file mode 100644 index 0000000..1ac6e15 --- /dev/null +++ b/src/functions/github-webhook-resource/index.js @@ -0,0 +1,103 @@ +'use strict' + +const GitHubApi = require('github'), + github = new GitHubApi({version: '3.0.0'}) +const response = require('cfn-response') +const ghUrl = require('parse-github-url'), + repo = ghUrl(process.env.GITHUB_REPOSITORY_URL) + +github.authenticate({type:'oauth', token: process.env.GITHUB_TOKEN}) + +function getTargetEvents() { + // Convert github-codebuild-integration style to GitHub event style + const target = process.env.GITHUB_TARGET_RESOURCE + let result = [] + switch(target) { + case 'pr': + result.push('pull_request') + break + case 'push': + result.push('push') + break + } + if (result.length == 0) { + return ['push'] + } + return result +} + +function hookParameters(requestType, id) { + switch (requestType) { + case 'Create': + return { + owner: repo.owner, + repo: repo.name, + name: 'amazonsns', + config: { + 'aws_key': process.env.SNS_ACCESS_KEY_ID, + 'aws_secret': process.env.SNS_SECRET_ACCESS_KEY, + 'sns_topic': process.env.SNS_TOPIC, + 'sns_region': process.env.SNS_REGION + }, + events: getTargetEvents() + } + case 'Update': + return { + owner: repo.owner, + repo: repo.name, + id: id, + name: 'amazonsns', + config: { + 'aws_key': process.env.SNS_ACCESS_KEY_ID, + 'aws_secret': process.env.SNS_SECRET_ACCESS_KEY, + 'sns_topic': process.env.SNS_TOPIC, + 'sns_region': process.env.SNS_REGION + }, + events: getTargetEvents() + } + case 'Delete': + return { + owner: repo.owner, + repo: repo.name, + id: id + } + } +} + +exports.handler = (event, context) => { + console.log('Received event:', JSON.stringify(event, null, 2)) + Promise.resolve().then(() => { + const params = hookParameters(event.RequestType, event.PhysicalResourceId) + console.log('Sending params to GitHub:', JSON.stringify(params, null, 2)) + switch (event.RequestType) { + case 'Create': + return new Promise((resolve, reject) => { + github.repos.createHook(params, (err, result) => { + err ? reject(err) : resolve(result) + }) + }) + case 'Update': + return new Promise((resolve, reject) => { + github.repos.editHook(params, (err, result) => { + err ? reject(err) : resolve(result) + }) + }) + case 'Delete': + return new Promise((resolve, reject) => { + github.repos.deleteHook(params, (err, result) => { + err ? reject(err) : resolve(result) + }) + }) + default: + throw new Error(`Unkown RequestType: '${event.RequestType}'`) + } + }).then((res) => { + const physicalResourceId = res.data.id ? res.data.id : 'unknown-hook-id' + if (!res.data.id) console.log('Received data from GitHub:', JSON.stringify(res, null, 2)) + const responseData = { HookId: physicalResourceId } + response.send(event, context, response.SUCCESS, responseData, physicalResourceId+'') // physicalResourceId should be string + }).catch((err) => { + const responseData = { Error: err.toString() } + response.send(event, context, response.FAILED, responseData) + }) +} diff --git a/src/functions/github-webhook-resource/package.json b/src/functions/github-webhook-resource/package.json new file mode 100644 index 0000000..0c19bf5 --- /dev/null +++ b/src/functions/github-webhook-resource/package.json @@ -0,0 +1,17 @@ +{ + "name": "build-dispatcher", + "description": "", + "engines": { + "node": ">=6.1" + }, + "author": "toricls", + "license": "MIT", + "dependencies": { + "cfn-response": "^1.0.1", + "github": "^9.3.1", + "parse-github-url": "^1.0.0" + }, + "devDependencies": { + "aws-sdk": "^2.102.0" + } +} diff --git a/src/functions/github-webhook-resource/yarn.lock b/src/functions/github-webhook-resource/yarn.lock new file mode 100644 index 0000000..1c44e72 --- /dev/null +++ b/src/functions/github-webhook-resource/yarn.lock @@ -0,0 +1,163 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +agent-base@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-2.1.1.tgz#d6de10d5af6132d5bd692427d46fc538539094c7" + dependencies: + extend "~3.0.0" + semver "~5.0.1" + +aws-sdk@^2.102.0: + version "2.102.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.102.0.tgz#70e52a8eff63de4c68e1d08c5c37db5561324340" + dependencies: + buffer "4.9.1" + crypto-browserify "1.0.9" + events "^1.1.1" + jmespath "0.15.0" + querystring "0.2.0" + sax "1.2.1" + url "0.10.3" + uuid "3.0.1" + xml2js "0.4.17" + xmlbuilder "4.2.1" + +base64-js@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.1.tgz#a91947da1f4a516ea38e5b4ec0ec3773675e0886" + +buffer@4.9.1: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +cfn-response@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cfn-response/-/cfn-response-1.0.1.tgz#a8ec03950c0683c51495e8ca680d9dc0b884b137" + +crypto-browserify@1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-1.0.9.tgz#cc5449685dfb85eb11c9828acc7cb87ab5bbfcc0" + +debug@2, debug@^2.2.0: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +events@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +extend@3, extend@~3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +follow-redirects@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-0.0.7.tgz#34b90bab2a911aa347571da90f22bd36ecd8a919" + dependencies: + debug "^2.2.0" + stream-consume "^0.1.0" + +github@^9.3.1: + version "9.3.1" + resolved "https://registry.yarnpkg.com/github/-/github-9.3.1.tgz#6a3c5a9cc2a1cd0b5d097a47baefb9d11caef89e" + dependencies: + follow-redirects "0.0.7" + https-proxy-agent "^1.0.0" + mime "^1.2.11" + netrc "^0.1.4" + +https-proxy-agent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6" + dependencies: + agent-base "2" + debug "2" + extend "3" + +ieee754@^1.1.4: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +isarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +jmespath@0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/jmespath/-/jmespath-0.15.0.tgz#a3f222a9aae9f966f5d27c796510e28091764217" + +lodash@^4.0.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +mime@^1.2.11: + version "1.3.6" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +netrc@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/netrc/-/netrc-0.1.4.tgz#6be94fcaca8d77ade0a9670dc460914c94472444" + +parse-github-url@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.0.tgz#d0c50b592d5a252c61a8540a421dfe8e571cf45a" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +sax@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.1.tgz#7b8e656190b228e81a66aea748480d828cd2d37a" + +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +semver@~5.0.1: + version "5.0.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.0.3.tgz#77466de589cd5d3c95f138aa78bc569a3cb5d27a" + +stream-consume@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/stream-consume/-/stream-consume-0.1.0.tgz#a41ead1a6d6081ceb79f65b061901b6d8f3d1d0f" + +url@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.10.3.tgz#021e4d9c7705f21bbf37d03ceb58767402774c64" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +uuid@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +xml2js@0.4.17: + version "0.4.17" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.17.tgz#17be93eaae3f3b779359c795b419705a8817e868" + dependencies: + sax ">=0.6.0" + xmlbuilder "^4.1.0" + +xmlbuilder@4.2.1, xmlbuilder@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-4.2.1.tgz#aa58a3041a066f90eaa16c2f5389ff19f3f461a5" + dependencies: + lodash "^4.0.0" diff --git a/test/fixtures/pr-closed.json b/test/fixtures/pr-closed.json new file mode 100644 index 0000000..f379333 --- /dev/null +++ b/test/fixtures/pr-closed.json @@ -0,0 +1,7 @@ +{ + "Records": [{ + "Sns": { + "Message": "{\"action\":\"closed\",\"number\":2,\"pull_request\":{\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\",\"id\":10,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\",\"diff_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.diff\",\"patch_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.patch\",\"issue_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\",\"number\":2,\"state\":\"closed\",\"locked\":false,\"title\":\"PR title\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"body!\",\"created_at\":\"2017-08-22T04:41:59Z\",\"updated_at\":\"2017-08-22T04:54:15Z\",\"closed_at\":\"2017-08-22T04:54:15Z\",\"merged_at\":null,\"merge_commit_sha\":\"ed30d493c996b174fea2c7cfa0a8d30dd2f802fe\",\"assignee\":null,\"assignees\":[],\"requested_reviewers\":[],\"milestone\":null,\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\",\"review_comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\",\"review_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"head\":{\"label\":\"gci-test-data:gci-test-data-patch-2\",\"ref\":\"gci-test-data-patch-2\",\"sha\":\"755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:42:00Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"}},\"base\":{\"label\":\"gci-test-data:master\",\"ref\":\"master\",\"sha\":\"f324e3b955492dfc7f0bcb4ec2c4ec5a83b8b54f\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:42:00Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"}},\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\"},\"html\":{\"href\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\"},\"issue\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\"},\"comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\"},\"review_comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\"},\"review_comment\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\"},\"commits\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\"},\"statuses\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\"}},\"merged\":false,\"mergeable\":true,\"rebaseable\":true,\"mergeable_state\":\"clean\",\"merged_by\":null,\"comments\":0,\"review_comments\":0,\"maintainer_can_modify\":false,\"commits\":1,\"additions\":1,\"deletions\":0,\"changed_files\":1},\"repository\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:42:00Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"},\"sender\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false}}" + } + }] +} diff --git a/test/fixtures/pr-created.json b/test/fixtures/pr-created.json new file mode 100644 index 0000000..5242c46 --- /dev/null +++ b/test/fixtures/pr-created.json @@ -0,0 +1,7 @@ +{ + "Records": [{ + "Sns": { + "Message": "{\"action\":\"opened\",\"number\":2,\"pull_request\":{\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\",\"id\":10,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\",\"diff_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.diff\",\"patch_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.patch\",\"issue_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\",\"number\":2,\"state\":\"open\",\"locked\":false,\"title\":\"PR title\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"body!\",\"created_at\":\"2017-08-22T04:41:59Z\",\"updated_at\":\"2017-08-22T04:41:59Z\",\"closed_at\":null,\"merged_at\":null,\"merge_commit_sha\":null,\"assignee\":null,\"assignees\":[],\"requested_reviewers\":[],\"milestone\":null,\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\",\"review_comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\",\"review_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"head\":{\"label\":\"gci-test-data:gci-test-data-patch-2\",\"ref\":\"gci-test-data-patch-2\",\"sha\":\"755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:40:39Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"}},\"base\":{\"label\":\"gci-test-data:master\",\"ref\":\"master\",\"sha\":\"f324e3b955492dfc7f0bcb4ec2c4ec5a83b8b54f\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:40:39Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"}},\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\"},\"html\":{\"href\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\"},\"issue\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\"},\"comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\"},\"review_comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\"},\"review_comment\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\"},\"commits\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\"},\"statuses\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\"}},\"merged\":false,\"mergeable\":null,\"rebaseable\":null,\"mergeable_state\":\"unknown\",\"merged_by\":null,\"comments\":0,\"review_comments\":0,\"maintainer_can_modify\":false,\"commits\":1,\"additions\":1,\"deletions\":0,\"changed_files\":1},\"repository\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:40:39Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"},\"sender\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false}}" + } + }] +} diff --git a/test/fixtures/pr-merged.json b/test/fixtures/pr-merged.json new file mode 100644 index 0000000..a56c600 --- /dev/null +++ b/test/fixtures/pr-merged.json @@ -0,0 +1,7 @@ +{ + "Records": [{ + "Sns": { + "Message": "{\"action\":\"closed\",\"number\":1,\"pull_request\":{\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/1\",\"id\":136881585,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/1\",\"diff_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/1.diff\",\"patch_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/1.patch\",\"issue_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/1\",\"number\":1,\"state\":\"closed\",\"locked\":false,\"title\":\"PR-title\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"\",\"created_at\":\"2017-08-22T02:53:19Z\",\"updated_at\":\"2017-08-22T04:39:29Z\",\"closed_at\":\"2017-08-22T04:39:29Z\",\"merged_at\":\"2017-08-22T04:39:29Z\",\"merge_commit_sha\":\"f324e3b955492dfc7f0bcb4ec2c4ec5a83b8b54f\",\"assignee\":null,\"assignees\":[],\"requested_reviewers\":[],\"milestone\":null,\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/1/commits\",\"review_comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/1/comments\",\"review_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/1/comments\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/56ce2674f0afd0a66b773a2063078864c5f9f24c\",\"head\":{\"label\":\"gci-test-data:gci-test-data-patch-1\",\"ref\":\"gci-test-data-patch-1\",\"sha\":\"56ce2674f0afd0a66b773a2063078864c5f9f24c\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:39:29Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"}},\"base\":{\"label\":\"gci-test-data:master\",\"ref\":\"master\",\"sha\":\"b21880e350cb19d67a3e5efb60cdb64e38e1f1eb\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:39:29Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"}},\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/1\"},\"html\":{\"href\":\"https://github.com/gci-test-data/gci-test-repo/pull/1\"},\"issue\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/1\"},\"comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/1/comments\"},\"review_comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/1/comments\"},\"review_comment\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\"},\"commits\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/1/commits\"},\"statuses\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/56ce2674f0afd0a66b773a2063078864c5f9f24c\"}},\"merged\":true,\"mergeable\":null,\"rebaseable\":null,\"mergeable_state\":\"unknown\",\"merged_by\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"comments\":0,\"review_comments\":0,\"maintainer_can_modify\":false,\"commits\":1,\"additions\":3,\"deletions\":0,\"changed_files\":1},\"repository\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:39:29Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":1,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\"},\"sender\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false}}" + } + }] +} diff --git a/test/fixtures/pr-reopened.json b/test/fixtures/pr-reopened.json new file mode 100644 index 0000000..ad96adc --- /dev/null +++ b/test/fixtures/pr-reopened.json @@ -0,0 +1,7 @@ +{ + "Records": [{ + "Sns": { + "Message": "{\"action\":\"reopened\",\"number\":2,\"pull_request\":{\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\",\"id\":10,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\",\"diff_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.diff\",\"patch_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.patch\",\"issue_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\",\"number\":2,\"state\":\"open\",\"locked\":false,\"title\":\"PR title\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"body!\",\"created_at\":\"2017-08-22T04:41:59Z\",\"updated_at\":\"2017-08-22T04:56:07Z\",\"closed_at\":null,\"merged_at\":null,\"merge_commit_sha\":\"ed30d493c996b174fea2c7cfa0a8d30dd2f802fe\",\"assignee\":null,\"assignees\":[],\"requested_reviewers\":[],\"milestone\":null,\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\",\"review_comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\",\"review_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"head\":{\"label\":\"gci-test-data:gci-test-data-patch-2\",\"ref\":\"gci-test-data-patch-2\",\"sha\":\"755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:42:00Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":2,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"}},\"base\":{\"label\":\"gci-test-data:master\",\"ref\":\"master\",\"sha\":\"f324e3b955492dfc7f0bcb4ec2c4ec5a83b8b54f\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:42:00Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":2,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"}},\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\"},\"html\":{\"href\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\"},\"issue\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\"},\"comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\"},\"review_comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\"},\"review_comment\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\"},\"commits\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\"},\"statuses\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\"}},\"merged\":false,\"mergeable\":null,\"rebaseable\":null,\"mergeable_state\":\"unknown\",\"merged_by\":null,\"comments\":0,\"review_comments\":0,\"maintainer_can_modify\":false,\"commits\":1,\"additions\":1,\"deletions\":0,\"changed_files\":1},\"repository\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T04:42:00Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":2,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"},\"sender\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false}}" + } + }] +} diff --git a/test/fixtures/pr-synchronized.json b/test/fixtures/pr-synchronized.json new file mode 100644 index 0000000..01b1f85 --- /dev/null +++ b/test/fixtures/pr-synchronized.json @@ -0,0 +1,7 @@ +{ + "Records": [{ + "Sns": { + "Message": "{\"action\":\"synchronize\",\"number\":2,\"pull_request\":{\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\",\"id\":10,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\",\"diff_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.diff\",\"patch_url\":\"https://github.com/gci-test-data/gci-test-repo/pull/2.patch\",\"issue_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\",\"number\":2,\"state\":\"open\",\"locked\":false,\"title\":\"PR title\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"body\":\"body!\",\"created_at\":\"2017-08-22T04:41:59Z\",\"updated_at\":\"2017-08-22T05:43:24Z\",\"closed_at\":null,\"merged_at\":null,\"merge_commit_sha\":\"2cc9de5bacb88dbe61a081d08797c92e7260ea7c\",\"assignee\":null,\"assignees\":[],\"requested_reviewers\":[],\"milestone\":null,\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\",\"review_comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\",\"review_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/b2c6cb1348b05e8262ec5dd755660bd80eb7c3e2\",\"head\":{\"label\":\"gci-test-data:gci-test-data-patch-2\",\"ref\":\"gci-test-data-patch-2\",\"sha\":\"b2c6cb1348b05e8262ec5dd755660bd80eb7c3e2\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T05:43:24Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":2,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"}},\"base\":{\"label\":\"gci-test-data:master\",\"ref\":\"master\",\"sha\":\"f324e3b955492dfc7f0bcb4ec2c4ec5a83b8b54f\",\"user\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"repo\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T05:43:24Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":2,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"}},\"_links\":{\"self\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2\"},\"html\":{\"href\":\"https://github.com/gci-test-data/gci-test-repo/pull/2\"},\"issue\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2\"},\"comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/2/comments\"},\"review_comments\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/comments\"},\"review_comment\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/comments{/number}\"},\"commits\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls/2/commits\"},\"statuses\":{\"href\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/b2c6cb1348b05e8262ec5dd755660bd80eb7c3e2\"}},\"merged\":false,\"mergeable\":null,\"rebaseable\":null,\"mergeable_state\":\"unknown\",\"merged_by\":null,\"comments\":0,\"review_comments\":0,\"maintainer_can_modify\":false,\"commits\":2,\"additions\":3,\"deletions\":0,\"changed_files\":1},\"before\":\"755c4d2229a3c8ffe68bb0fc231bd4dd227bff82\",\"after\":\"b2c6cb1348b05e8262ec5dd755660bd80eb7c3e2\",\"repository\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":\"2017-08-21T23:50:28Z\",\"updated_at\":\"2017-08-21T23:50:28Z\",\"pushed_at\":\"2017-08-22T05:43:24Z\",\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":2,\"stargazers_count\":0,\"watchers_count\":0,\"language\":null,\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":1,\"forks\":0,\"open_issues\":1,\"watchers\":0,\"default_branch\":\"master\"},\"sender\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false}}" + } + }] +} diff --git a/test/fixtures/pushed.json b/test/fixtures/pushed.json new file mode 100644 index 0000000..2f9d2ac --- /dev/null +++ b/test/fixtures/pushed.json @@ -0,0 +1,7 @@ +{ + "Records": [{ + "Sns": { + "Message": "{\"ref\":\"refs/heads/master\",\"before\":\"1df85ce180fda74daf20b8b5707bd4fdbb708387\",\"after\":\"62462cba6e04982d25e6dd5fbbd220ef0de41e5a\",\"created\":false,\"deleted\":false,\"forced\":false,\"base_ref\":null,\"compare\":\"https://github.com/gci-test-data/gci-test-repo/compare/1df85ce180fd...62462cba6e04\",\"commits\":[{\"id\":\"62462cba6e04982d25e6dd5fbbd220ef0de41e5a\",\"tree_id\":\"9ffc39b7c05f0b1d80d9a5b518cae8077a5ecdc9\",\"distinct\":true,\"message\":\"message!\",\"timestamp\":\"2017-08-23T17:21:06+09:00\",\"url\":\"https://github.com/gci-test-data/gci-test-repo/commit/62462cba6e04982d25e6dd5fbbd220ef0de41e5a\",\"author\":{\"name\":\"gci-test-data\",\"email\":\"gci-test-datatr@gmail.com\",\"username\":\"gci-test-data\"},\"committer\":{\"name\":\"gci-test-data\",\"email\":\"gci-test-datatr@gmail.com\",\"username\":\"gci-test-data\"},\"added\":[],\"removed\":[],\"modified\":[\"src/functions/github-webhook-handler/index.js\"]}],\"head_commit\":{\"id\":\"62462cba6e04982d25e6dd5fbbd220ef0de41e5a\",\"tree_id\":\"9ffc39b7c05f0b1d80d9a5b518cae8077a5ecdc9\",\"distinct\":true,\"message\":\"message!\",\"timestamp\":\"2017-08-23T17:21:06+09:00\",\"url\":\"https://github.com/gci-test-data/gci-test-repo/commit/62462cba6e04982d25e6dd5fbbd220ef0de41e5a\",\"author\":{\"name\":\"gci-test-data\",\"email\":\"gci-test-datatr@gmail.com\",\"username\":\"gci-test-data\"},\"committer\":{\"name\":\"gci-test-data\",\"email\":\"gci-test-datatr@gmail.com\",\"username\":\"gci-test-data\"},\"added\":[],\"removed\":[],\"modified\":[\"src/functions/github-webhook-handler/index.js\"]},\"repository\":{\"id\":100,\"name\":\"gci-test-repo\",\"full_name\":\"gci-test-data/gci-test-repo\",\"owner\":{\"name\":\"gci-test-data\",\"email\":\"gci-test-datatr@gmail.com\",\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false},\"private\":true,\"html_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"description\":null,\"fork\":false,\"url\":\"https://github.com/gci-test-data/gci-test-repo\",\"forks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/forks\",\"keys_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/keys{/key_id}\",\"collaborators_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/collaborators{/collaborator}\",\"teams_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/teams\",\"hooks_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/hooks\",\"issue_events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/events{/number}\",\"events_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/events\",\"assignees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/assignees{/user}\",\"branches_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/branches{/branch}\",\"tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/tags\",\"blobs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/blobs{/sha}\",\"git_tags_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/tags{/sha}\",\"git_refs_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/refs{/sha}\",\"trees_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/trees{/sha}\",\"statuses_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/statuses/{sha}\",\"languages_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/languages\",\"stargazers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/stargazers\",\"contributors_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contributors\",\"subscribers_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscribers\",\"subscription_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/subscription\",\"commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/commits{/sha}\",\"git_commits_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/git/commits{/sha}\",\"comments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/comments{/number}\",\"issue_comment_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues/comments{/number}\",\"contents_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/contents/{+path}\",\"compare_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/compare/{base}...{head}\",\"merges_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/merges\",\"archive_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/{archive_format}{/ref}\",\"downloads_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/downloads\",\"issues_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/issues{/number}\",\"pulls_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/pulls{/number}\",\"milestones_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/milestones{/number}\",\"notifications_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/notifications{?since,all,participating}\",\"labels_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/labels{/name}\",\"releases_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/releases{/id}\",\"deployments_url\":\"https://api.github.com/repos/gci-test-data/gci-test-repo/deployments\",\"created_at\":1503359428,\"updated_at\":\"2017-08-22T23:44:38Z\",\"pushed_at\":1503476538,\"git_url\":\"git://github.com/gci-test-data/gci-test-repo.git\",\"ssh_url\":\"git@github.com:gci-test-data/gci-test-repo.git\",\"clone_url\":\"https://github.com/gci-test-data/gci-test-repo.git\",\"svn_url\":\"https://github.com/gci-test-data/gci-test-repo\",\"homepage\":null,\"size\":40,\"stargazers_count\":0,\"watchers_count\":0,\"language\":\"JavaScript\",\"has_issues\":true,\"has_projects\":true,\"has_downloads\":true,\"has_wiki\":true,\"has_pages\":false,\"forks_count\":0,\"mirror_url\":null,\"open_issues_count\":0,\"forks\":0,\"open_issues\":0,\"watchers\":0,\"default_branch\":\"master\",\"stargazers\":0,\"master_branch\":\"master\"},\"pusher\":{\"name\":\"gci-test-data\",\"email\":\"gci-test-datatr@gmail.com\"},\"sender\":{\"login\":\"gci-test-data\",\"id\":1,\"avatar_url\":\"https://avatars1.githubusercontent.com/u/1?v=4\",\"gravatar_id\":\"\",\"url\":\"https://api.github.com/users/gci-test-data\",\"html_url\":\"https://github.com/gci-test-data\",\"followers_url\":\"https://api.github.com/users/gci-test-data/followers\",\"following_url\":\"https://api.github.com/users/gci-test-data/following{/other_user}\",\"gists_url\":\"https://api.github.com/users/gci-test-data/gists{/gist_id}\",\"starred_url\":\"https://api.github.com/users/gci-test-data/starred{/owner}{/repo}\",\"subscriptions_url\":\"https://api.github.com/users/gci-test-data/subscriptions\",\"organizations_url\":\"https://api.github.com/users/gci-test-data/orgs\",\"repos_url\":\"https://api.github.com/users/gci-test-data/repos\",\"events_url\":\"https://api.github.com/users/gci-test-data/events{/privacy}\",\"received_events_url\":\"https://api.github.com/users/gci-test-data/received_events\",\"type\":\"User\",\"site_admin\":false}}" + } + }] +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..8736051 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,908 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +acorn-jsx@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-3.0.1.tgz#afdf9488fb1ecefc8348f6fb22f464e32a58b36b" + dependencies: + acorn "^3.0.4" + +acorn@^3.0.4: + version "3.3.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" + +acorn@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.1.1.tgz#53fe161111f912ab999ee887a90a0bc52822fd75" + +ajv-keywords@^1.0.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.8.tgz#82ffb02b29e662ae53bdc20af15947706739c536" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +ajv@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.2.2.tgz#47c68d69e86f5d953103b0074a9430dc63da5e39" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + json-schema-traverse "^0.3.0" + json-stable-stringify "^1.0.1" + +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.0.tgz#c159b8d5be0f9e5a6f346dab94f16ce022161b88" + dependencies: + color-convert "^1.9.0" + +argparse@^1.0.7: + version "1.0.9" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86" + dependencies: + sprintf-js "~1.0.2" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +babel-code-frame@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +brace-expansion@^1.1.7: + version "1.1.8" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +browser-stdout@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" + +caller-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/caller-path/-/caller-path-0.1.0.tgz#94085ef63581ecd3daa92444a8fe94e82577751f" + dependencies: + callsites "^0.2.0" + +callsites@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-0.2.0.tgz#afab96262910a7f33c19a5775825c69f34e350ca" + +chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e" + dependencies: + ansi-styles "^3.1.0" + escape-string-regexp "^1.0.5" + supports-color "^4.0.0" + +circular-json@^0.3.1: + version "0.3.3" + resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.3.tgz#815c99ea84f6809529d2f45791bdf82711352d66" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +color-convert@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.0.tgz#1accf97dd739b983bf994d56fec8f95853641b7a" + dependencies: + color-name "^1.1.1" + +color-name@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +commander@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.0.tgz#0aac662fd52be78964d5532f694784e70110acf7" + dependencies: + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cross-spawn@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +debug@2.6.8, debug@^2.6.8: + version "2.6.8" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" + dependencies: + ms "2.0.0" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +del@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" + dependencies: + globby "^5.0.0" + is-path-cwd "^1.0.0" + is-path-in-cwd "^1.0.0" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + rimraf "^2.2.8" + +diff@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" + +doctrine@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.0.0.tgz#c73d8d2909d22291e1a007a395804da8b665fe63" + dependencies: + esutils "^2.0.2" + isarray "^1.0.0" + +escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +eslint-scope@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-3.7.1.tgz#3d63c3edfda02e06e01a452ad88caacc7cdcb6e8" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +eslint@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.5.0.tgz#bb75d3b8bde97fb5e13efcd539744677feb019c3" + dependencies: + ajv "^5.2.0" + babel-code-frame "^6.22.0" + chalk "^2.1.0" + concat-stream "^1.6.0" + cross-spawn "^5.1.0" + debug "^2.6.8" + doctrine "^2.0.0" + eslint-scope "^3.7.1" + espree "^3.5.0" + esquery "^1.0.0" + estraverse "^4.2.0" + esutils "^2.0.2" + file-entry-cache "^2.0.0" + functional-red-black-tree "^1.0.1" + glob "^7.1.2" + globals "^9.17.0" + ignore "^3.3.3" + imurmurhash "^0.1.4" + inquirer "^3.0.6" + is-resolvable "^1.0.0" + js-yaml "^3.9.1" + json-stable-stringify "^1.0.1" + levn "^0.3.0" + lodash "^4.17.4" + minimatch "^3.0.2" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + optionator "^0.8.2" + path-is-inside "^1.0.2" + pluralize "^4.0.0" + progress "^2.0.0" + require-uncached "^1.0.3" + semver "^5.3.0" + strip-ansi "^4.0.0" + strip-json-comments "~2.0.1" + table "^4.0.1" + text-table "~0.2.0" + +espree@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/espree/-/espree-3.5.0.tgz#98358625bdd055861ea27e2867ea729faf463d8d" + dependencies: + acorn "^5.1.1" + acorn-jsx "^3.0.0" + +esprima@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" + +esquery@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.0.0.tgz#cfba8b57d7fba93f17298a8a006a04cda13d80fa" + dependencies: + estraverse "^4.0.0" + +esrecurse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.0.tgz#fa9568d98d3823f9a41d91e902dcab9ea6e5b163" + dependencies: + estraverse "^4.1.0" + object-assign "^4.0.1" + +estraverse@^4.0.0, estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +external-editor@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" + dependencies: + iconv-lite "^0.4.17" + jschardet "^1.4.2" + tmp "^0.0.31" + +fast-deep-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +file-entry-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-2.0.0.tgz#c392990c3e684783d838b8c84a45d8a048458361" + dependencies: + flat-cache "^1.2.1" + object-assign "^4.0.1" + +flat-cache@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-1.2.2.tgz#fa86714e72c21db88601761ecf2f555d1abc6b96" + dependencies: + circular-json "^0.3.1" + del "^2.0.2" + graceful-fs "^4.1.2" + write "^0.2.1" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + +glob@7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.3, glob@^7.0.5, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^9.17.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" + dependencies: + array-union "^1.0.1" + arrify "^1.0.0" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +growl@1.9.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + +iconv-lite@^0.4.17: + version "0.4.18" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.18.tgz#23d8656b16aae6742ac29732ea8f0336a4789cf2" + +ignore@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.3.tgz#432352e57accd87ab3110e82d3fea0e47812156d" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inquirer@^3.0.6: + version "3.2.2" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.2.2.tgz#c2aaede1507cc54d826818737742d621bef2e823" + dependencies: + ansi-escapes "^2.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-path-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" + +is-path-in-cwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz#6477582b8214d602346094567003be8a9eac04dc" + dependencies: + is-path-inside "^1.0.0" + +is-path-inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.0.tgz#fc06e5a1683fbda13de667aff717bbc10a48f37f" + dependencies: + path-is-inside "^1.0.1" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-resolvable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.0.0.tgz#8df57c61ea2e3c501408d100fb013cf8d6e0cc62" + dependencies: + tryit "^1.0.1" + +isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-yaml@^3.9.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.9.1.tgz#08775cebdfdd359209f0d2acd383c8f86a6904a0" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jschardet@^1.4.2: + version "1.5.1" + resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-1.5.1.tgz#c519f629f86b3a5bedba58a88d311309eec097f9" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json3@3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +levn@^0.3.0, levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +lodash._baseassign@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e" + dependencies: + lodash._basecopy "^3.0.0" + lodash.keys "^3.0.0" + +lodash._basecopy@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36" + +lodash._basecreate@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash._isiterateecall@^3.0.0: + version "3.0.9" + resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" + +lodash.create@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7" + dependencies: + lodash._baseassign "^3.0.0" + lodash._basecreate "^3.0.0" + lodash._isiterateecall "^3.0.0" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash@^4.0.0, lodash@^4.17.4, lodash@^4.3.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +lru-cache@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.1.tgz#622e32e82488b49279114a4f9ecf45e7cd6bba55" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +mimic-fn@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18" + +minimatch@^3.0.2, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +mkdirp@0.5.1, mkdirp@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +mocha@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.0.tgz#1328567d2717f997030f8006234bce9b8cd72465" + dependencies: + browser-stdout "1.3.0" + commander "2.9.0" + debug "2.6.8" + diff "3.2.0" + escape-string-regexp "1.0.5" + glob "7.1.1" + growl "1.9.2" + json3 "3.3.2" + lodash.create "3.1.1" + mkdirp "0.5.1" + supports-color "3.1.2" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optionator@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +os-tmpdir@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-is-inside@^1.0.1, path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pluralize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-4.0.0.tgz#59b708c1c0190a2f692f1c7618c446b052fd1762" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +readable-stream@^2.2.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + safe-buffer "~5.1.1" + string_decoder "~1.0.3" + util-deprecate "~1.0.1" + +require-uncached@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/require-uncached/-/require-uncached-1.0.3.tgz#4e0d56d6c9662fd31e43011c4b95aa49955421d3" + dependencies: + caller-path "^0.1.0" + resolve-from "^1.0.0" + +resolve-from@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-1.0.1.tgz#26cbfe935d1aeeeabb29bc3fe5aeb01e93d44226" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +rimraf@^2.2.8: + version "2.6.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" + dependencies: + glob "^7.0.5" + +run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + +safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + +semver@^5.3.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.4.1.tgz#e059c09d8571f0540823733433505d3a2f00b18e" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + +string-width@^2.0.0, string-width@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supports-color@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5" + dependencies: + has-flag "^1.0.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.2.1.tgz#65a4bb2631e90e02420dba5554c375a4754bb836" + dependencies: + has-flag "^2.0.0" + +table@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/table/-/table-4.0.1.tgz#a8116c133fac2c61f4a420ab6cdf5c4d61f0e435" + dependencies: + ajv "^4.7.0" + ajv-keywords "^1.0.0" + chalk "^1.1.1" + lodash "^4.0.0" + slice-ansi "0.0.4" + string-width "^2.0.0" + +text-table@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +tmp@^0.0.31: + version "0.0.31" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.31.tgz#8f38ab9438e17315e5dbd8b3657e8bfb277ae4a7" + dependencies: + os-tmpdir "~1.0.1" + +tryit@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tryit/-/tryit-1.0.3.tgz#393be730a9446fd1ead6da59a014308f36c289cb" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +which@^1.2.9: + version "1.3.0" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a" + dependencies: + isexe "^2.0.0" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/write/-/write-0.2.1.tgz#5fc03828e264cea3fe91455476f7a3c566cb0757" + dependencies: + mkdirp "^0.5.1" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52"