前提条件
- Node.js 多分v6以上かつ、
- GitHubhookを受け取れるサーバーがある
-
npm init
はもうしてる場所 - GithubのDeployKeyはもちろん通してある
本文
PHPとかはいっぱいあるのにNode.jsのサンプルあんまない!
github-webhook-handlerを使うとちょー簡単です!! ただ、Buffer.from
を内部で使ってるので4系とか古いNode.jsでは動かない。。。です多分。。。
ということでぱぱっとインストール
$ npm install github-webhook-handler -S
サンプルコード
とりあえずログまで取るようにしてる適当なサンプルコードです。
github-webhook-handlerのerr.messageはJsonなので、それに習ってlogは全部Jsonに揃えとくと綺麗かも。
execでコールバックが山なりになってますが、exec-thenとか使うともっと綺麗になるかもですね〜〜
github-webhook-handler.js
'use strict';
const logFilePath = './github-webhook.log';
const PORT = '7777';
const SECRET = process.env.WEBHOOK_SECRET || 'secret'; // ソース上にsecretがあるのはあれなので環境変数にしておくと良いかもっていう
const REPOSITORY_NAME = 'hoge'; // よしなに変えて
const errorMessages = {
noMatch: 'not match repository or branch'
};
const fs = require('fs');
const http = require('http');
const exec = require('child_process').exec;
const createHandler = require('github-webhook-handler');
const handler = createHandler({
path: '/webhook',
secret: SECRET
});
const writeLog = (data) => {
fs.appendFileSync(logFilePath, data+"\n", (err) => {
if (err) {
writeLog(JSON.stringify({error: err})+"\n");
throw err;
}
});
}
http.createServer((req, res) => {
handler(req, res, function (err) {
res.statusCode = 404;
res.end('no such location');
})
}).listen(PORT);
handler.on('error', (err) => {
writeLog(err.message);
});
handler.on('push', (e) => {
const payload = e.payload;
const repoName = payload.repository.name;
const branch = payload.ref.split("/").pop();
let log = {
pull: {
error: '',
stdout: ''
},
restart: {
error: '',
stdout: ''
}
};
// リポジトリの確認とmasterが更新されたらっていう判断
if (repoName !== REPOSITORY_NAME && branch !== 'master') {
writeLog(JSON.stringify({ error: errorMessages.noMatch }));
return;
}
// んで最後に反映する処理をよしなに書いておく...
exec('git pull origin master', (err, stdout, stderr) => {
if (err) { log.pull.error = err }
log.pull.stdout = stdout;
writeLog(JSON.stringify(log));
exec('npm install', (err, stdout, stderr) => {
if (err) { log.pull.error = err }
log.pull.stdout = stdout;
writeLog(JSON.stringify(log));
exec('forever restart app.js', (err, stdout, stderr) => {
if (err) { log.restart.error = err }
log.restart.stdout = stdout;
writeLog(JSON.stringify(log));
});
});
});
});
これでGitHubhookのpushでhostname:7777/webhook
を叩くようにしておけばページが反映されそうですね。
んでとりあえず死ぬと困ると思うのでデーモン化して起動しとこうかな...
$ npm install -g forever
$ WEBHOOK_SECRET=hogehoge forever start github-webhook-handler.js
オチ
やっぱCIツール使いましょう