LoginSignup
5
5

More than 5 years have passed since last update.

Node.jsサーバーでGitHubhook受け取ってpushだけで簡単にページ反映させる

Last updated at Posted at 2017-12-30

前提条件

  • Node.js 多分v6以上かつ、
  • GitHubhookを受け取れるサーバーがある
  • npm initはもうしてる場所
  • GithubのDeployKeyはもちろん通してある

本文

PHPとかはいっぱいあるのにNode.jsのサンプルあんまない!:sweat:
github-webhook-handlerを使うとちょー簡単です!! ただ、Buffer.fromを内部で使ってるので4系とか古いNode.jsでは動かない。。。です多分。。。:sleeping:

ということでぱぱっとインストール

$ npm install github-webhook-handler -S

サンプルコード

とりあえずログまで取るようにしてる適当なサンプルコードです。
github-webhook-handlerのerr.messageはJsonなので、それに習ってlogは全部Jsonに揃えとくと綺麗かも。
execでコールバックが山なりになってますが、exec-thenとか使うともっと綺麗になるかもですね〜〜:blush:

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を叩くようにしておけばページが反映されそうですね。
んでとりあえず死ぬと困ると思うのでデーモン化して起動しとこうかな...:innocent:

$ npm install -g forever
$ WEBHOOK_SECRET=hogehoge forever start github-webhook-handler.js

オチ

やっぱCIツール使いましょう:smiley:

5
5
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
5