/** * Service which will listen for a Github webhook, fired on push. * This service can be used to rebuild / restart the app automatically * when new code is pushed. */ var crypto = require('crypto') var exec = require('child_process').exec var path = require('path') function OKWebhook (options) { if (!(this instanceof OKWebhook)) return new OKWebhook(options) options = options || {} if (!options.express) throw new Error('Express not provided to OKWebhook'); if (!options.config) throw new Error('Configuration not provided to OKWebhook'); if (options.config.active && !options.config.secret) throw new Error('Github secret not provided to OKWebhook'); if (options.config.active && !options.config.command) throw new Error('Build command not provided to OKWebhook'); var express = options.express var router = express.Router() var config = options.config var secret = config.secret var command = config.command router.get('/', function (req, res) { res.send('GET not supported') }) router.post('/', getBody, function (req, res) { if (!config.active) return console.log("OKWebhook received push") var event = req.headers['x-github-event'] if (event !== "push") { return res.sendStatus(500) } var sig = req.headers['x-hub-signature'].split('=')[1] var text = req.rawBody var hash = crypto.createHmac('sha1', secret).update(text).digest('hex') if (hash !== sig) { return res.sendStatus(500) } res.sendStatus(200) var cwd = path.dirname(command) exec(command, { cwd: cwd }, function(err, stdout, stderr){ // may not fire if process was restarted.. console.log(process.env) console.log(stdout) }) }) function getBody (req, res, next) { req.rawBody = '' // req.setEncoding('utf8') req.on('data', function(chunk) { req.rawBody += chunk }) req.on('end', function() { try { req.body = JSON.parse(req.rawBody) } catch (e) { return res.sendStatus(500) } next() }) } this._router = router } OKWebhook.prototype.middleware = function () { return this._router } module.exports = OKWebhook