diff --git a/.gitignore b/.gitignore index 46c283f992d49..f5bd238b99fba 100644 --- a/.gitignore +++ b/.gitignore @@ -49,3 +49,4 @@ node_modules/ .idea/ .vscode/ +.serverless/ diff --git a/infrastructure/Dockerfile b/infrastructure/Dockerfile new file mode 100644 index 0000000000000..8268e14ad2faf --- /dev/null +++ b/infrastructure/Dockerfile @@ -0,0 +1,13 @@ +FROM node:8 +RUN npm install -g yarn@1.3.2 +RUN yarn global add gatsby-cli gatsby-dev-cli +RUN mkdir ~/.ssh && echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config +RUN git clone https://github.com/gatsbyjs/gatsby.git +RUN wget https://github.com/github/hub/releases/download/v2.3.0-pre10/hub-linux-amd64-2.3.0-pre10.tgz --directory-prefix /usr/local/bin +RUN cd gatsby && gatsby-dev --set-path-to-repo . && yarn bootstrap +RUN mkdir -p gatsby/infrastructure +COPY package.json gatsby/infrastructure/ +COPY yarn.lock gatsby/infrastructure/ +RUN cd gatsby/infrastructure && yarn +COPY build-site.js gatsby/infrastructure/ +CMD ["node", "gatsby/infrastructure/build-site.js"] diff --git a/infrastructure/blue b/infrastructure/blue new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/infrastructure/build-site.js b/infrastructure/build-site.js new file mode 100644 index 0000000000000..f0b6ad14968e1 --- /dev/null +++ b/infrastructure/build-site.js @@ -0,0 +1,172 @@ +const shell = require("shelljs") +const { spawn } = require("child_process") +const path = require("path") +const GraphQLClient = require("graphql-request").GraphQLClient +const queue = require(`async/queue`) +const s3 = require("s3") + +const commitId = process.env.CODEBUILD_SOURCE_VERSION + +const s3Client = s3.createClient({ + s3Options: { + accessKeyId: process.env.accessKeyId, + secretAccessKey: process.env.secretAccessKey, + region: "us-east-1", + endpoint: "s3.us-east-1.amazonaws.com", + }, +}) + +const client = new GraphQLClient( + "https://api.graph.cool/simple/v1/cj8xuo77f0a3a0164y7jketkr", + { + headers: { + Authorization: `Bearer ${process.env.GRAPHCOOL_TOKEN}`, + }, + } +) + +function createBuild(sha, commitObjId, url) { + return client.request(` + mutation { + createBuild(gitSha: "${sha}", result: BUILDING, url: "${url}", commitId: "${commitObjId}", logsIds: []) { + id + } + } + `) +} + +function updateBuild(buildId, status) { + return client.request(` + mutation { + updateBuild(id: "${buildId}", result: ${status}) { + id + } + } + `) +} + +function createLogLine(logLine, buildId, stderr = false) { + return client.request( + ` + mutation createLogLine($text: String!, $buildId: ID!, $stderr: Boolean) { + createLogLine(text: $text, buildId: $buildId, stderr: $stderr) { + id + } + } + `, + { text: logLine, buildId, stderr } + ) +} + +const getCommitObjectByHash = commitId => { + return client + .request( + ` + { + allCommits( + filter: { hash: "46f5ed9d8d05a9608bc9c98fcb5867a892149e94" } + ) { + id + } + } + ` + ) + .then(result => result.allCommits[0].id) +} + +console.log(process.env) + +var q = queue(function({ logLine, buildId, stderr }, callback) { + createLogLine(logLine, buildId, stderr).then(callback) +}, 1) + +const Main = async () => { + if (!process.env.PATH_TO_SITE) { + console.log("Missing required environment variable PATH_TO_SITE") + process.exit(1) + } + + console.log(process.cwd()) + + // Navigate to Gatsby directory + shell.cd(`/gatsby/`) + + // Ensure we have the latest code + shell.exec(`git fetch`) + + // Check if the commit exists (later we'll grab pull requests as well + // but we're just building branches on gatsbyjs/gatsby while testing) + const commitExists = shell.exec(`git cat-file -e ${commitId}`) + console.log(`commitExists`, commitExists) + if (commitExists.code !== 0) { + process.exit(commitExists.code) + } + + // It does! So let's checkout our commit and initialize the environment. + shell.exec(`git checkout -b newbranch ${commitId}`) + shell.exec(`yarn bootstrap`) + + // Now go to the site and install + const pathToSite = path.join(`/gatsby/`, process.env.PATH_TO_SITE) + shell.cd(pathToSite) + shell.exec(`yarn`) + shell.exec(`gatsby-dev --scan-once --quiet`) + + // Create the build + const commitObjId = await getCommitObjectByHash(commitId) + const url = `${process.env.PATH_TO_SITE}---${commitId}.gatsbydev.com` + const result = await createBuild(commitId, commitObjId, url) + const buildId = result.createBuild.id + + // Start building! + const child = spawn(`gatsby`, [`build`]) + child.on(`error`, err => console.log(`err:`, err)) + child.stdout.pipe(process.stdout) + child.stderr.pipe(process.stderr) + child.stdout.on("data", data => { + // Create new logline + q.push({ logLine: data.toString("utf8"), buildId }) + }) + child.stderr.on("data", data => { + // Create new logline + q.push({ logLine: data.toString("utf8"), buildId, stderr: true }) + }) + + // On end + child.on("exit", (code, signal) => { + console.log( + "child process exited with " + `code ${code} and signal ${signal}` + ) + // Gatsby build failed + if (code !== 0) { + updateBuild(buildId, "FAILURE") + process.exit(code) + } + const publicDir = `${pathToSite}/public` + console.log(`uploading files from ${publicDir}`) + + // 1. Push built files to s3 bucket + const upload = s3Client.uploadDir({ + localDir: publicDir, + s3Params: { + Prefix: url, + Bucket: `gatsby-js-builds`, + }, + }) + upload.on(`fileUploadEnd`, () => + console.log(`${upload.progressAmount / upload.progressTotal}`) + ) + upload.on(`error`, error => { + console.error(error) + updateBuild(buildId, "FAILURE").then(() => { + process.exit(code) + }) + }) + // 2. Write final status of build and exit. + upload.on(`end`, () => { + updateBuild(buildId, "SUCCESS").then(() => process.exit()) + }) + }) +} + +Main() diff --git a/infrastructure/functions/onGithubWebhook/handler.js b/infrastructure/functions/onGithubWebhook/handler.js new file mode 100644 index 0000000000000..38d7ca2764441 --- /dev/null +++ b/infrastructure/functions/onGithubWebhook/handler.js @@ -0,0 +1,104 @@ +// handler.js + +"use strict" +const axios = require("axios") +const Libhoney = require("libhoney").default +const flatten = require("flat") +const GraphQLClient = require("graphql-request").GraphQLClient + +const hny = new Libhoney({ + writeKey: process.env.HONEYCOMB_KEY, + dataset: "gatsbyjs-os.lambda.github-webhook", +}) + +console.log(`env vars`, process.env) + +const client = new GraphQLClient( + "https://api.graph.cool/simple/v1/cj8xuo77f0a3a0164y7jketkr", + { + headers: { + Authorization: `Bearer ${process.env.GRAPHCOOL_TOKEN}`, + }, + } +) + +function createBranch(branch) { + hny.sendNow({ createBranch: branch }) + return client.request(` + mutation { + createBranch(name: "${branch}", commits: []) { + id + } + } + `) +} + +function getBranch(branch) { + return client.request(` + query { + allBranches(filter: {name: "${branch}"}) { + id + name + } + } + `) +} + +const createBranchIfDoesNotExist = branch => + getBranch(branch).then(result => { + if (result.allBranches.length === 0) { + return createBranch(branch).then(newBranch => { + console.log(`newBranch`, newBranch) + return newBranch.createBranch.id + }) + } else { + console.log(`allBranches`, result) + return result.allBranches[0].id + } + }) + +const createCommit = (commit, branchId) => { + hny.sendNow(Object.assign({ createCommit: true, branchId: branchId }, commit)) + return client.request(` + mutation { + createCommit(authorName: "${commit.author.name}",authorUsername: "${commit + .author.username}", authorEmail: "${commit.author + .email}", hash: "${commit.tree_id}", message: "${commit.message}", branchIds: ["${branchId}"]) { + id + } + } + `) +} + +module.exports.event = function(event, context, callback) { + if (event && event.body) { + event.body = JSON.parse(event.body) + } + console.log(event) // Contains incoming request data (e.g., query params, headers and more) + hny.sendNow(flatten(event)) + + const response = { + statusCode: 200, + body: ``, + } + + new Promise(resolve => { + // Commit push + if ( + event.headers[`X-GitHub-Event`] === `push` && + event.body.ref.split(`/`)[1] === `heads` + ) { + const branchName = event.body.ref.split(`/`)[2] + + // Check if the branch exists + createBranchIfDoesNotExist(branchName).then(branchId => { + // Create commits + resolve( + Promise.all( + event.body.commits.map(commit => createCommit(commit, branchId)) + ) + ) + }) + } + }).then(() => callback(null, response)) +} diff --git a/infrastructure/functions/onGithubWebhook/package.json b/infrastructure/functions/onGithubWebhook/package.json new file mode 100644 index 0000000000000..26a2dd04a4dde --- /dev/null +++ b/infrastructure/functions/onGithubWebhook/package.json @@ -0,0 +1,17 @@ +{ + "name": "ongithubwebhook", + "version": "1.0.0", + "description": "", + "main": "handler.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^0.17.0", + "flat": "^4.0.0", + "graphql-request": "^1.4.0", + "libhoney": "^1.0.0-beta.10" + } +} diff --git a/infrastructure/functions/onGithubWebhook/serverless.yml b/infrastructure/functions/onGithubWebhook/serverless.yml new file mode 100644 index 0000000000000..d031731be221b --- /dev/null +++ b/infrastructure/functions/onGithubWebhook/serverless.yml @@ -0,0 +1,106 @@ +# Welcome to Serverless! +# +# This file is the main config file for your service. +# It's very minimal at this point and uses default values. +# You can always add more config options for more control. +# We've included some commented out config examples here. +# Just uncomment any of them to get that config option. +# +# For full config options, check the docs: +# docs.serverless.com +# +# Happy Coding! + +service: onGithubWebhook + +# You can pin your service to only deploy with a specific Serverless version +# Check out our docs for more details +# frameworkVersion: "=X.X.X" + +provider: + name: aws + runtime: nodejs6.10 + +# you can overwrite defaults here +# stage: dev +# region: us-east-1 + +# you can add statements to the Lambda function's IAM Role here +# iamRoleStatements: +# - Effect: "Allow" +# Action: +# - "s3:ListBucket" +# Resource: { "Fn::Join" : ["", ["arn:aws:s3:::", { "Ref" : "ServerlessDeploymentBucket" } ] ] } +# - Effect: "Allow" +# Action: +# - "s3:PutObject" +# Resource: +# Fn::Join: +# - "" +# - - "arn:aws:s3:::" +# - "Ref" : "ServerlessDeploymentBucket" +# - "/*" + +# you can define service wide environment variables here +# environment: +# variable1: value1 + +# you can add packaging information here +#package: +# include: +# - include-me.js +# - include-me-dir/** +# exclude: +# - exclude-me.js +# - exclude-me-dir/** + +functions: + event: + handler: handler.event + events: + - http: POST event + +# The following are a few example events you can configure +# NOTE: Please make sure to change your handler code to work with those events +# Check the event documentation for details +# events: +# - http: +# path: users/create +# method: get +# - s3: ${env:BUCKET} +# - schedule: rate(10 minutes) +# - sns: greeter-topic +# - stream: arn:aws:dynamodb:region:XXXXXX:table/foo/stream/1970-01-01T00:00:00.000 +# - alexaSkill +# - alexaSmartHome: amzn1.ask.skill.xx-xx-xx-xx +# - iot: +# sql: "SELECT * FROM 'some_topic'" +# - cloudwatchEvent: +# event: +# source: +# - "aws.ec2" +# detail-type: +# - "EC2 Instance State-change Notification" +# detail: +# state: +# - pending +# - cloudwatchLog: '/aws/lambda/hello' +# - cognitoUserPool: +# pool: MyUserPool +# trigger: PreSignUp + +# Define function environment variables here +# environment: +# variable2: value2 + +# you can add CloudFormation resource templates here +#resources: +# Resources: +# NewResource: +# Type: AWS::S3::Bucket +# Properties: +# BucketName: my-new-bucket +# Outputs: +# NewOutput: +# Description: "Description for the output" +# Value: "Some output value" diff --git a/infrastructure/functions/onGithubWebhook/yarn.lock b/infrastructure/functions/onGithubWebhook/yarn.lock new file mode 100644 index 0000000000000..86241b9a11626 --- /dev/null +++ b/infrastructure/functions/onGithubWebhook/yarn.lock @@ -0,0 +1,208 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +axios@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.17.0.tgz#7da747916db803f761651d6091d708789b953c6a" + dependencies: + follow-redirects "^1.2.3" + is-buffer "^1.1.5" + +combined-stream@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +component-emitter@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +cookiejar@^2.0.6: + version "2.1.1" + resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.1.tgz#41ad57b1b555951ec171412a81942b1e8200d34a" + +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-fetch@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-0.0.8.tgz#01ed94dc407df2c00f1807fde700a7cfa48a205c" + dependencies: + node-fetch "1.7.3" + whatwg-fetch "2.0.3" + +debug@^2.2.0, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +extend@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" + +extend@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend/-/extend-2.0.1.tgz#1ee8010689e7395ff9448241c98652bc759a8260" + +flat@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/flat/-/flat-4.0.0.tgz#3abc7f3b588e64ce77dc42fd59aa35806622fea8" + dependencies: + is-buffer "~1.1.5" + +follow-redirects@^1.2.3: + version "1.2.5" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.2.5.tgz#ffd3e14cbdd5eaa72f61b6368c1f68516c2a26cc" + dependencies: + debug "^2.6.9" + +form-data@1.0.0-rc4: + version "1.0.0-rc4" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.0-rc4.tgz#05ac6bc22227b43e4461f488161554699d4f8b5e" + dependencies: + async "^1.5.2" + combined-stream "^1.0.5" + mime-types "^2.1.10" + +formidable@^1.0.17: + version "1.1.1" + resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.1.1.tgz#96b8886f7c3c3508b932d6bd70c4d3a88f35f1a9" + +graphql-request@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.4.0.tgz#f5b067c83070296d93fb45760e83dfad0d9f537a" + dependencies: + cross-fetch "0.0.8" + +iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +is-buffer@^1.1.5, is-buffer@~1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +libhoney@^1.0.0-beta.10: + version "1.0.0-beta.10" + resolved "https://registry.yarnpkg.com/libhoney/-/libhoney-1.0.0-beta.10.tgz#5ee682f38fa7ef8103810237d7f94345c6fb5134" + dependencies: + superagent "^2.3.0" + urljoin "^0.1.5" + +methods@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +mime-db@~1.30.0: + version "1.30.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01" + +mime-types@^2.1.10: + version "2.1.17" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a" + dependencies: + mime-db "~1.30.0" + +mime@^1.3.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +node-fetch@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +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" + +qs@^6.1.0: + version "6.5.1" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" + +readable-stream@^2.0.5: + 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" + +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" + +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" + +superagent@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/superagent/-/superagent-2.3.0.tgz#703529a0714e57e123959ddefbce193b2e50d115" + dependencies: + component-emitter "^1.2.0" + cookiejar "^2.0.6" + debug "^2.2.0" + extend "^3.0.0" + form-data "1.0.0-rc4" + formidable "^1.0.17" + methods "^1.1.1" + mime "^1.3.4" + qs "^6.1.0" + readable-stream "^2.0.5" + +urljoin@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/urljoin/-/urljoin-0.1.5.tgz#b25d2c6112c55ac9d50096a49a0f1fb7f4f53921" + dependencies: + extend "~2.0.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +whatwg-fetch@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" diff --git a/infrastructure/package.json b/infrastructure/package.json new file mode 100644 index 0000000000000..b6ea36a688ca9 --- /dev/null +++ b/infrastructure/package.json @@ -0,0 +1,17 @@ +{ + "name": "infrastructure", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "dependencies": { + "async": "^2.6.0", + "graphql-request": "^1.4.0", + "s3": "^4.4.0", + "shelljs": "^0.7.8" + } +} diff --git a/infrastructure/yarn.lock b/infrastructure/yarn.lock new file mode 100644 index 0000000000000..928e6ae368cf4 --- /dev/null +++ b/infrastructure/yarn.lock @@ -0,0 +1,221 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +async@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4" + dependencies: + lodash "^4.14.0" + +aws-sdk@~2.0.31: + version "2.0.31" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.0.31.tgz#e72cf1fdc69015bd9fd2bdf3d3b88c16507d268e" + dependencies: + xml2js "0.2.6" + xmlbuilder "0.4.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" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +cross-fetch@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-0.0.8.tgz#01ed94dc407df2c00f1807fde700a7cfa48a205c" + dependencies: + node-fetch "1.7.3" + whatwg-fetch "2.0.3" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +fd-slicer@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.0.1.tgz#8b5bcbd9ec327c5041bf9ab023fd6750f1177e65" + dependencies: + pend "~1.2.0" + +findit2@~2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/findit2/-/findit2-2.2.3.tgz#58a466697df8a6205cdfdbf395536b8bd777a5f6" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +glob@^7.0.0: + 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" + +graceful-fs@~3.0.5: + version "3.0.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-3.0.11.tgz#7613c778a1afea62f25c630a086d7f3acbbdd818" + dependencies: + natives "^1.1.0" + +graphql-request@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-1.4.0.tgz#f5b067c83070296d93fb45760e83dfad0d9f537a" + dependencies: + cross-fetch "0.0.8" + +iconv-lite@~0.4.13: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +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: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +interpret@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.4.tgz#820cdd588b868ffb191a809506d6c9c8f212b1b0" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +lodash@^4.14.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +mime@~1.2.11: + version "1.2.11" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.2.11.tgz#58203eed86e3a5ef17aed2b7d9ebd47f0a60dd10" + +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.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +natives@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/natives/-/natives-1.1.0.tgz#e9ff841418a6b2ec7a495e939984f78f163e6e31" + +node-fetch@1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +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-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +pend@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +resolve@^1.1.6: + version "1.5.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.5.0.tgz#1f09acce796c9a762579f31b2c1cc4c3cddf9f36" + dependencies: + path-parse "^1.0.5" + +rimraf@~2.2.8: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +s3@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/s3/-/s3-4.4.0.tgz#56a4f775515a7b6b9c8e5c6b1ab51f9037669f1f" + dependencies: + aws-sdk "~2.0.31" + fd-slicer "~1.0.0" + findit2 "~2.2.3" + graceful-fs "~3.0.5" + mime "~1.2.11" + mkdirp "~0.5.0" + pend "~1.2.0" + rimraf "~2.2.8" + streamsink "~1.2.0" + +sax@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/sax/-/sax-0.4.2.tgz#39f3b601733d6bec97105b242a2a40fd6978ac3c" + +shelljs@^0.7.8: + version "0.7.8" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +streamsink@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/streamsink/-/streamsink-1.2.0.tgz#efafee9f1e22d3591ed7de3dcaa95c3f5e79f73c" + +whatwg-fetch@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +xml2js@0.2.6: + version "0.2.6" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.2.6.tgz#d209c4e4dda1fc9c452141ef41c077f5adfdf6c4" + dependencies: + sax "0.4.2" + +xmlbuilder@0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-0.4.2.tgz#1776d65f3fdbad470a08d8604cdeb1c4e540ff83"