ほんじゃーねっと

おっさんがやせたがったり食べたがったりする日常エッセイ

Subversionにコミットしたらチャットワークに通知するNode.jsスクリプト

ある開発プロジェクトで、

非技術系のメンバーにも進捗を知っておいてもらいたいものの、

「お前らSubversion入れろ」とか「リポジトリログを見ろ」といっても見そうになく、

いちいち伝えるのも面倒大変そうだったので、

Subversionにコミットがあったらメッセージ内容がリアルタイムで

チャットワークに流れる仕組みを作ってやった。

www.chatwork.com

チャットワークはチーム間でのやりとりに使っていたので、ここに流してやろうというわけだ。

チャットワークはプレビュー版ながらAPIを公開してくれているので、

developer.chatwork.com

API経由でメッセージ投稿を行うスクリプトと、

Subversionのフック機能を組み合わせることで実現することができた。

Node.jsでチャットワークのAPIにアクセスするスクリプトを作成する

今回はNode.jsでスクリプトを作成した。

手軽に環境が作れて、速くて、一通りライブラリが揃っているので気に入っている。

スクリプトの内容としては、

コマンドラインからリポジトリパスとリビジョン番号を受け取って、

svnlookコマンドでリビジョンをコミットしたユーザー名、メッセージログを取得して、

メッセージを組み立てて、

チャットワークのAPI経由で投稿している。

Subversionが動いているサーバにnode.js環境をインストールして、このスクリプトを配置する。

svn2chatwork.js

var execSync = require('child_process').execSync;
var _ = require('underscore');
var request = require('request');

if (process.argv.length < 4) {
    return;
}

var repo = process.argv[2];
var rev = process.argv[3];

var cwApiKey = '<ChatworkのAPIキー>';
var endpointBase = 'https://api.chatwork.com/v1/';

var svnRootPath = '/var/www/svn'; //Subversionのリポジトリルートパス

var targetRepos = {}; 
// このtargetReposにリポジトリパスを追加したら複数のリポジトリに対応可能
targetRepos[svnRootPath + '/<SVNリポジトリパス>'] = {'roomId': '<投稿先ChatworkのルームID>'};

var post2Chatwork = function (roomId, message, callback) {
    var options = { 
        url: endpointBase + 'rooms/' + roomId + '/messages',
         headers: {
             'X-ChatWorkToken': cwApiKey
         },  
        form: {
            body: message
        },
        json: true
    };

    request.post(options, function (error, response, body) {
        if (!error &amp;&amp; response.statusCode == 200) {
            callback(body);
        }   
    }); 
}
if (_.has(targetRepos, repo)) {
    var repoInfo = targetRepos[repo];
    var message = 'New Commit\n';

    var result = '' + execSync('svnlook author ' + repo + ' -r ' + rev);
    message += 'User:' + result;

    result = '' + execSync('svnlook log ' + repo + ' -r ' + rev);
    message += result;

    // 下記のコメントを外すと更新ファイル一覧もメッセージに追加できる(大量にファイルが更新されると結構うざい)
    // result = '' + execSync('svnlook changed ' + repo + ' -r ' + rev);
    // message += 'Files Updated:\n';
    // message += result;

    post2Chatwork(repoInfo.roomId, message, function (body) {});
}

Subversionのフックスクリプトを作成する

Subversionのリポジトリを作成すると、その中にhooksフォルダが作成され、

そこに置いたフックスクリプトを各種タイミングで実行してくれる。

Subversion フックスクリプト

今回はコミット後に上で作成したスクリプトを実行してもらいたいので、

「post-commit」という名前で下記のような内容のファイルを作成する。

作成したスクリプトにパラメータとしてリポジトリパスとリビジョン番号を渡し、nodeコマンドで実行するコマンドを書いてる。

最初のexport文を書かないと、日本語が文字化けしてしまうので注意。

あと、node.jsのバージョンとか、どこにsvn2chatwork.jsを置いたかでパスが変わるので注意。

post-commit

export LANG=ja_JP.UTF-8

REPOS='$1'
REV='$2'

# <nodeコマンドへのパス> <svn2chatwork.jsへのパス> $REPOS $REV
/usr/local/node-v0.12.7/bin/node /home/test/svn2chatwork/svn2chatwork.js $REPOS $REV

編集後、post-commitに実行権限をつけたら以降のコミットがチャットワークに通知されるはず。

おわり

ソースを整理したり、リポジトリとルームの関連付けを外部化したりしたものをGitHubに置いている。

よかったら参考にしていただきたい。

github.com

今時Subversionなんか使わねーよ!と言われるかもしれないが。

blog.honjala.net

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)

Subversion実践入門:達人プログラマに学ぶバージョン管理(第2版)