From 182c4c285d5df85980f379d9fa935e2ae1d66cdf Mon Sep 17 00:00:00 2001 From: William Date: Thu, 7 Apr 2016 19:43:46 +0000 Subject: [PATCH 1/2] emit github events --- Procfile | 1 + lib/github-events.js | 39 +++++++++++++++++++++++++++++ package.json | 2 ++ scripts/display-travis-status.js | 26 ++++++++++++++++++++ server.js | 42 ++++++++++---------------------- 5 files changed, 81 insertions(+), 29 deletions(-) create mode 100644 Procfile create mode 100644 lib/github-events.js create mode 100644 scripts/display-travis-status.js diff --git a/Procfile b/Procfile new file mode 100644 index 00000000..81e952f7 --- /dev/null +++ b/Procfile @@ -0,0 +1 @@ +web: node server diff --git a/lib/github-events.js b/lib/github-events.js new file mode 100644 index 00000000..80e61f55 --- /dev/null +++ b/lib/github-events.js @@ -0,0 +1,39 @@ +const crypto = require('crypto') +const debug = require('debug')('github') + +const secret = process.env.GITHUB_WEBHOOK_SECRET || 'hush-hush' + +const sign = (secret, data) => { + const buffer = new Buffer(data, 'utf8') + return 'sha1=' + crypto.createHmac('sha1', secret).update(buffer).digest('hex') +} + +module.exports = (app) => { + app.post('/hooks/github', (req, res) => { + const event = req.headers['x-github-event'] + if (!event) { + res.writeHead(400, 'Event Header Missing') + return res.end() + } + + const signature = req.headers['x-hub-signature'] + if (!signature || signature !== sign(secret, req.raw)) { + res.writeHead(401, 'Invalid Signature') + return res.end() + } + + res.end() + + const data = req.body + data.action = data.action ? event + '.' + data.action : event + + var source = data.repository ? data.repository.full_name : data.organization.login + console.log('event@%s: %s', source, data.action) + + if (debug.enabled) { + debug(JSON.stringify(data, null, 2)) + } + + app.emit(data.action, data) + }) +} diff --git a/package.json b/package.json index 3ae2b156..8526bc29 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "license": "MIT", "dependencies": { "body-parser": "^1.15.0", + "debug": "^2.2.0", + "dotenv": "^2.0.0", "express": "^4.13.4", "github": "^0.2.4", "travis-ci": "^2.1.0" diff --git a/scripts/display-travis-status.js b/scripts/display-travis-status.js new file mode 100644 index 00000000..08d53976 --- /dev/null +++ b/scripts/display-travis-status.js @@ -0,0 +1,26 @@ +'use strict' + +const debug = require('debug')('display_travis_status') +const pollTravis = require('../lib/pollTravis') + +module.exports = function (app) { + app.on('pull_request.opened', (event) => { + const owner = event.repository.owner.login + const repo = event.repository.name + if (repo !== 'nodejs.org') return + + debug(`/${owner}/${repo}/pull/${event.number} opened`) + pollTravis.pollThenComment(owner, repo, event.number) + }) + + // to trigger polling manually + app.get('/pr/:owner/:repo/:id', (req, res) => { + const owner = req.params.owner + const repo = req.params.repo + const id = req.params.id + if (repo === 'nodejs.org') { + pollTravis.pollThenComment(owner, repo, parseInt(id, 10)) + } + res.end() + }) +} diff --git a/server.js b/server.js index f28a09da..7bac9d94 100644 --- a/server.js +++ b/server.js @@ -1,39 +1,23 @@ 'use strict' +require('dotenv').load({ silent: true }) + const express = require('express') const bodyParser = require('body-parser') - -const pollTravis = require('./lib/pollTravis') +const captureRaw = (req, res, buffer) => { req.raw = buffer } const app = express() - -const port = process.env.PORT || 3000 - -app.use(bodyParser.json()) - -app.all('/hooks/github', (req, res) => { - if (wasPullRequestOpened(req)) { - const repo = req.body.repository - - console.log(`* ${repo.owner.login}/${repo.name}/#${req.body.number} Opened, starting build checks!`) - pollTravis.pollThenComment(repo.owner.login, repo.name, parseInt(req.body.number)) - } - - res.end() -}) - -// to trigger polling manually -app.get('/pr/:owner/:repo/:prId', (req, res) => { - pollTravis.pollThenComment(req.params.owner, req.params.repo, parseInt(req.params.prId)) - res.end() +app.use(bodyParser.json({ verify: captureRaw })) +require('./lib/github-events.js')(app) + +// load all the files in the scripts folder +require('fs').readdirSync('./scripts').forEach((file) => { + file = './scripts/' + file + console.log('loading:', file) + require(file)(app) }) -app.listen(process.env.PORT || 3000, () => { +const port = process.env.PORT || 3000 +app.listen(port, () => { console.log('Example app listening on port', port) }) - -function wasPullRequestOpened (req) { - const githubEvent = req.headers['x-github-event'] || '' - const githubAction = req.body.action || '' - return githubEvent === 'pull_request' && githubAction === 'opened' -} From da57626aec1a06019a30c8ba3906a91c825e296c Mon Sep 17 00:00:00 2001 From: William Date: Fri, 8 Apr 2016 16:48:46 +0000 Subject: [PATCH 2/2] allow travis script to run on citgm and readable-stream --- scripts/display-travis-status.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/display-travis-status.js b/scripts/display-travis-status.js index 08d53976..041640fd 100644 --- a/scripts/display-travis-status.js +++ b/scripts/display-travis-status.js @@ -2,12 +2,13 @@ const debug = require('debug')('display_travis_status') const pollTravis = require('../lib/pollTravis') +const enabledRepos = ['citgm', 'readable-stream', 'nodejs.org'] module.exports = function (app) { app.on('pull_request.opened', (event) => { const owner = event.repository.owner.login const repo = event.repository.name - if (repo !== 'nodejs.org') return + if (!~enabledRepos.indexOf(repo)) return debug(`/${owner}/${repo}/pull/${event.number} opened`) pollTravis.pollThenComment(owner, repo, event.number) @@ -18,7 +19,7 @@ module.exports = function (app) { const owner = req.params.owner const repo = req.params.repo const id = req.params.id - if (repo === 'nodejs.org') { + if (~enabledRepos.indexOf(repo)) { pollTravis.pollThenComment(owner, repo, parseInt(id, 10)) } res.end()