Skip to content

Commit

Permalink
Adds the ability to send a recorded webhook through the peril pipeline
Browse files Browse the repository at this point in the history
  • Loading branch information
orta committed May 6, 2018
1 parent a0e6e6a commit 82d9ec9
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 25 deletions.
2 changes: 2 additions & 0 deletions package.json
Expand Up @@ -82,6 +82,7 @@
"github-webhook-event-types": "^1.1.0",
"glob": "^7.1.2",
"graphql": "^0.13.2",
"graphql-playground-middleware-express": "^1.6.1",
"graphql-relay-tools": "^0.1.1",
"graphql-resolvers": "^0.2.2",
"graphql-tools": "^2.24.0",
Expand All @@ -95,6 +96,7 @@
"lodash": "^4.17.10",
"mongoose": "^5.0.16",
"node-fetch": "2.1.2",
"node-mocks-http": "^1.5.8",
"node-schedule": "^1.3.0",
"ts-jest": "^22.4.4",
"ts-node": "^6.0.0",
Expand Down
14 changes: 12 additions & 2 deletions source/api/api.ts
@@ -1,7 +1,8 @@
import { graphiqlExpress, graphqlExpress } from "apollo-server-express"
import { graphqlExpress } from "apollo-server-express"
import * as bodyParser from "body-parser"
import * as cookieParser from "cookie-parser"
import { Application } from "express"
import expressPlayground from "graphql-playground-middleware-express"

import { GITHUB_CLIENT_SECRET } from "../globals"
import { getJWTFromRequest } from "./auth/getJWTFromRequest"
Expand Down Expand Up @@ -52,5 +53,14 @@ export const setupPublicAPI = (app: Application) => {
}))
)

app.use("/api/graphiql", graphiqlExpress({ endpointURL: "/api/graphql" }))
app.get(
"/api/graphiql",
expressPlayground({
endpoint: "/api/graphql",
workspaceName: "Peril",
settings: {
"request.credentials": "include", // https://github.com/graphcool/graphql-playground/pull/661
} as any,
})
)
}
7 changes: 6 additions & 1 deletion source/api/graphql/index.ts
Expand Up @@ -23,6 +23,7 @@ import {
setInstallationToRecord,
wipeAllRecordedWebhooks,
} from "../../plugins/utils/recordWebhookWithRequest"
import { sendWebhookThroughGitHubRunner } from "../../plugins/utils/sendWebhookThroughGitHubRunner"
import { GraphQLContext } from "../api"
import { getDetailsFromPerilJWT } from "../auth/generate"
import { gql } from "./gql"
Expand Down Expand Up @@ -127,7 +128,7 @@ const schemaSDL = gql`
# Sets the installation to record webhooks for the next 5m
makeInstallationRecord(iID: Int!): Installation
# Send webhook
sendWebhookForInstallation(iID: Int!. eventID: String!): RecordedWebhook
sendWebhookForInstallation(iID: Int!, eventID: String!): RecordedWebhook
}
`

Expand Down Expand Up @@ -240,7 +241,11 @@ const resolvers = {
}

const webhook = await getRecordedWebhook(params.iID, params.eventID)
if (!webhook) {
return null
}

await sendWebhookThroughGitHubRunner(webhook)
return webhook
}),
},
Expand Down
1 change: 0 additions & 1 deletion source/github/events/github_runner.ts
Expand Up @@ -105,7 +105,6 @@ export const githubDangerRunner = async (event: string, req: express.Request, re
}

const settings = await setupForRequest(req, installation.settings)

// Allow edge-case repos to skip Danger rules. E.g. in Artsy, our analytics and marketing repos
// do not need the same level of thought as an larger engineering project would.
if (repoIsIgnored(settings.repoName, installation)) {
Expand Down
5 changes: 4 additions & 1 deletion source/peril.ts
Expand Up @@ -77,20 +77,23 @@ export const peril = () => {
welcomeMessages.push(tick + " Docker Webhook")
app.post(url, hyperUpdater)
}
const port = process.env.PORT || 5000

// This should go last
if (PUBLIC_FACING_API) {
welcomeMessages.push(tick + " Public API:")
welcomeMessages.push(` - Web Root: ${PUBLIC_WEB_ROOT_URL}`)
welcomeMessages.push(` - API Root: ${PUBLIC_API_ROOT_URL}`)
welcomeMessages.push(` - GraphQL : http://localhost:${port}/api/graphql`)
welcomeMessages.push(` - GraphiQL: http://localhost:${port}/api/graphiql`)
setupPublicAPI(app)
}

// Start server
app.listen(app.get("port"), () => {
if (!process.env.HEROKU || !process.env.NOW) {
welcomeMessages.push(tick + " Server:")
welcomeMessages.push(` - Local: http://localhost:${process.env.PORT || 5000}`)
welcomeMessages.push(` - Local: http://localhost:${port}`)
}
welcomeMessages.forEach(l => logger.info(l))
logger.info("")
Expand Down
6 changes: 3 additions & 3 deletions source/plugins/utils/recordWebhookWithRequest.ts
Expand Up @@ -4,7 +4,7 @@ import { getDB } from "../../db/getDB"
import { MongoDB } from "../../db/mongo"
import { actionForWebhook } from "../../github/events/utils/actions"

interface RecordedWebhook {
export interface RecordedWebhook {
iID: number
event: string
eventID: string
Expand Down Expand Up @@ -42,7 +42,7 @@ export const recordWebhookWithRequest = async (req: express.Request) => {
json: req.body,
}

RecordedWebhook.create(record)
await RecordedWebhook.create(record)
}

/** Triggers the recording time for a specific installation to be for the next 5m */
Expand All @@ -64,4 +64,4 @@ export const getRecordedWebhooksForInstallation = async (installationID: number)

/** Gets an webhook */
export const getRecordedWebhook = async (installationID: string, eventID: string) =>
RecordedWebhook.find({ iID: installationID, eventID })
RecordedWebhook.findOne({ iID: installationID, eventID })
15 changes: 15 additions & 0 deletions source/plugins/utils/sendWebhookThroughGitHubRunner.ts
@@ -0,0 +1,15 @@
import { createRequest, createResponse } from "node-mocks-http"
import { githubDangerRunner } from "../../github/events/github_runner"
import { RecordedWebhook } from "./recordWebhookWithRequest"

/** Takes a recorded webhook and sends it through the Peril runner */
export const sendWebhookThroughGitHubRunner = async (webhook: RecordedWebhook) => {
const request = createRequest({
headers: {
"X-GitHub-Delivery": webhook.eventID,
},
body: webhook.json,
})
const response = createResponse()
await githubDangerRunner(webhook.event, request, response, () => null)
}
2 changes: 1 addition & 1 deletion tsconfig.json
Expand Up @@ -3,7 +3,7 @@
"module": "commonjs",
"target": "es2017",
"outDir": "out",
"lib": ["esnext"],
"lib": ["esnext", "dom"], // Re:dom https://github.com/graphcool/graphql-request/issues/26#issuecomment-354482903
"sourceMap": true,
"rootDir": "source",
"allowJs": true,
Expand Down
55 changes: 39 additions & 16 deletions yarn.lock
Expand Up @@ -237,7 +237,7 @@ abbrev@1:
version "1.0.9"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135"

accepts@~1.3.5:
accepts@^1.3.3, accepts@~1.3.5:
version "1.3.5"
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2"
dependencies:
Expand Down Expand Up @@ -2568,7 +2568,7 @@ depd@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359"

depd@~1.1.1, depd@~1.1.2:
depd@^1.1.0, depd@~1.1.1, depd@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9"

Expand Down Expand Up @@ -3302,7 +3302,7 @@ fragment-cache@^0.2.1:
dependencies:
map-cache "^0.2.2"

fresh@0.5.2:
fresh@0.5.2, fresh@^0.5.2:
version "0.5.2"
resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7"

Expand Down Expand Up @@ -3617,7 +3617,7 @@ graphql-playground-html@1.5.5:
dependencies:
graphql-config "2.0.0"

graphql-playground-middleware-express@1.6.1:
graphql-playground-middleware-express@1.6.1, graphql-playground-middleware-express@^1.6.1:
version "1.6.1"
resolved "https://registry.yarnpkg.com/graphql-playground-middleware-express/-/graphql-playground-middleware-express-1.6.1.tgz#d6287d124a1c55845a52a7d727c371da99cdf0b0"
dependencies:
Expand Down Expand Up @@ -5571,7 +5571,7 @@ mem@^1.1.0:
dependencies:
mimic-fn "^1.0.0"

merge-descriptors@1.0.1:
merge-descriptors@1.0.1, merge-descriptors@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"

Expand All @@ -5585,7 +5585,7 @@ merge@^1.1.3:
version "1.2.0"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"

methods@~1.1.2:
methods@^1.1.2, methods@~1.1.2:
version "1.1.2"
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"

Expand Down Expand Up @@ -5659,6 +5659,10 @@ mime@1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.4.1.tgz#121f9ebc49e3766f311a76e1fa1c8003c4b03aa6"

mime@^1.3.4:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"

mimic-fn@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.1.0.tgz#e667783d92e89dbd342818b5230b9d62a672ad18"
Expand Down Expand Up @@ -5846,6 +5850,10 @@ negotiator@0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9"

net@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/net/-/net-1.0.2.tgz#d1757ec9a7fb2371d83cf4755ce3e27e10829388"

node-cleanup@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c"
Expand All @@ -5869,6 +5877,21 @@ node-int64@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"

node-mocks-http@^1.5.8:
version "1.5.8"
resolved "https://registry.yarnpkg.com/node-mocks-http/-/node-mocks-http-1.5.8.tgz#cbcc6dc8278861f96522c51ae858cf62806e2f80"
dependencies:
accepts "^1.3.3"
depd "^1.1.0"
fresh "^0.5.2"
merge-descriptors "^1.0.1"
methods "^1.1.2"
mime "^1.3.4"
net "^1.0.2"
parseurl "^1.3.1"
range-parser "^1.2.0"
type-is "^1.6.14"

node-modules-regexp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40"
Expand Down Expand Up @@ -6371,7 +6394,7 @@ parseuri@0.0.5:
dependencies:
better-assert "~1.0.0"

parseurl@~1.3.2:
parseurl@^1.3.1, parseurl@~1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3"

Expand Down Expand Up @@ -6633,7 +6656,7 @@ randomstring@^1.1.5:
dependencies:
array-uniq "1.0.2"

range-parser@~1.2.0:
range-parser@^1.2.0, range-parser@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"

Expand Down Expand Up @@ -8042,20 +8065,20 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"

type-is@^1.6.14, type-is@~1.6.15, type-is@~1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
dependencies:
media-typer "0.3.0"
mime-types "~2.1.18"

type-is@^1.6.9:
version "1.6.14"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2"
dependencies:
media-typer "0.3.0"
mime-types "~2.1.13"

type-is@~1.6.15, type-is@~1.6.16:
version "1.6.16"
resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194"
dependencies:
media-typer "0.3.0"
mime-types "~2.1.18"

typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
Expand Down Expand Up @@ -8348,7 +8371,7 @@ vlq@^0.2.2:
version "0.2.3"
resolved "https://registry.yarnpkg.com/vlq/-/vlq-0.2.3.tgz#8f3e4328cf63b1540c0d67e1b2778386f8975b26"

"vm2@github:patriksimek/vm2#custom_files":
vm2@patriksimek/vm2#custom_files:
version "3.5.0"
resolved "https://codeload.github.com/patriksimek/vm2/tar.gz/7e82f90ac705fc44fad044147cb0df09b4c79a57"

Expand Down

0 comments on commit 82d9ec9

Please sign in to comment.