クリアコードが開発に関わっているプロジェクトではdiff付きのコミットメールを流すようにしています。
コミットメールを流すための方法を紹介します1。
使用しているのは以下の2つのGemです。
- git-commit-mailer
- コミットメールを生成して送信するコマンド
- github-web-hooks-receiver
- GitHub2のWeb hookのエンドポイントとして機能するウェブアプリ
環境はDebian GNU/Linux wheezyを想定しています。Rubyのバージョンは1.9.3以降であれば問題ありません。
専用のユーザを用意します。
$ sudo useradd app
アプリケーションをデプロイするディレクトリを用意します。
$ sudo mkdir -p /srv/www/webapps/web-hooks-receiver
$ sudo chwon -R app:app /srv/www/webapps
/srv/www/webapps/web-hooks-receiver/Gemfileを用意します。
source "https://rubygems.org"
gem "git-commit-mailer"
gem "github-web-hooks-receiver"
ここではApache+Passengerでセットアップします3。
以下のコマンドを実行し、必要なGemをインストールします。
$ cd /srv/www/webapps/web-hooks-receiver
$ sudo -u app -H bundle install --binstubs --path vendor/bundle --without=development,test
ここで--binstubs
オプションを付けているのは、カレントディレクトリのbin以下にgit-commit-mailerコマンドをインストールするためです。
Rackアプリケーションとして動作させるための設定ファイルconfig.ruを用意します。
require "yaml"
require "pathname"
require "github-web-hooks-receiver"
use Rack::CommonLogger
use Rack::Runtime
use Rack::ContentLength
base_dir = Pathname(__FILE__).realpath.dirname
config_file = base_dir + "config.yaml"
options = YAML.load_file(config_file.to_s)
map "/post-receiver/" do
run GitHubWebHooksReceiver::App.new(options)
end
もし、GitHubWebHooksReceiver::App
の実行中に発生したエラーをメールで通知したい場合は、exception_notificationやrackngaを使うと良いでしょう。
Passenger の設定は以下のようにします4。
/etc/apache2/sites-available/github-web-hooks-receiver:
<VirtualHost *:80>
ServerName web-hooks-receiver.example.com
DocumentRoot /srv/www/webapps/web-hooks-receiver/public
<Directory /srv/www/webapps/web-hooks-receiver/public>
AllowOverride all
Options -MultiViews
</Directory>
ErrorLog ${APACHE_LOG_DIR}/web-hooks-receiver_error.log
CustomLog ${APACHE_LOG_DIR}/web-hooks-receiver_access.log combined
AllowEncodedSlashes On
AcceptPathInfo On
</VirtualHost>
/etc/apache2/mods-available/passenger.conf:
PassengerRoot /path/to/passenger
PassengerRuby /path/to/ruby
/etc/apache2/mods-available/passenger.load:
LoadModule passenger_module /path/to/mod_passenger.so
GitHubWebHooksReceiver
用の設定ファイルconfig.yamlを用意します5。
base_dir: /srv/www/webapps/web-hooks-receiver
mirrors_directory: mirrors
git_commit_mailer: bin/git-commit-mailer
to:
- commit+default@example.com
error_to: commit+error@example.com
exception_notifier:
subject_label: "[git-commit-mailer]"
sender: null+git-commit-mailer@example.com
add_html: false
domains:
github.com:
owners:
clear-code:
to: commit@example.com
from: null+github@example.com
repositories:
cutter:
to:
- cutter-commit@lists.sourceforge.net
cutter-macports:
to:
- cutter-commit@lists.sourceforge.net
pikzie:
to:
- pikzie-commit@lists.sourceforge.net
rabbit-shocker:
to: commit@ml.rabbit-shocker.org
from: null@rabbit-shocker.org
gitlab.example.com:
to: commit+internal@example.com
from: null+gitlab@example.com
-
base_dir
-
基準となるディレクトリを絶対パスで指定します。
-
mirrors_directory
-
Gitリポジトリをミラーするディレクトリをbase_dir からの相対パス、または、絶対パスで指定します。 省略すると
#{base_dir}/mirrors
を使用します。 -
git_commit_mailer
-
git-commit-mailer コマンドへのパスを指定します。 ruby コマンドの引数として実行するので、任意の Ruby スクリプトでも構いません。
-
error_to
-
エラーが発生したときの宛先を指定します。
-
to
-
コミットメールの宛先を配列で指定します。
-
sender
-
送信者のメールアドレスを指定します。 Sender ヘッダーの値や from が指定されなかった場合のエンベロープFromの値として使用します。
-
from
-
省略すると Author の name と email から「Commiter Name commiter@example.com」のようなメールアドレスを生成して使用します。指定可能なのはメールアドレスの部分のみです。
-
add_html
-
true を指定すると、HTMLメールで色付きのdiffを生成します。
-
send_per_to
-
true を指定するとtoごとに別のSMTPセッションでコミットメールを送信します。
-
sleep_per_mail
-
コミットメールを一通送信するごとに指定された秒数だけsleepします。
コミットメールの宛先を指定する方法
以下の4つの単位で指定することができます。マッチした条件のうち最も小さい範囲にコミットメールを送信します。
- 全体
- ドメイン単位
- オーナー単位
- リポジトリ単位
上の例で言うと、以下のように配信します。
- github.com の clear-code organization にある cutter, cutter-macports リポジトリは cutter-commit@lists.sourceforge.net にコミットメールを配信する。その際 From ヘッダーの値には Author の name と email を使用する。
- github.com の clear-code organization にある pikzie リポジトリは pikzie-commit@lists.sourceforge.net にコミットメールを配信する。その際 From ヘッダーの値には Author の name と email を使用する。
- github.com の clear-code organization にある cutter, cutter-macports, pikzie 以外のリポジトリは commit@example.com にコミットメールを配信する。その際 From ヘッダーの値には Author の name と null+github@example.com を使用する。
- github.com の rabbit-shocker organization の全てのリポジトリは commit@ml.rabbit-shocker.org へコミットメールを配信する。その際 From ヘッダーの値は Author の name と null@rabbit-shocker.org を使用する。
- gitlab.example.com の全てのリポジトリは commit+internal@example.com へコミットメールを配信する。その際 From ヘッダーの値には Author の name と null+gitlab@example.com を使用する。
- 上記全ての条件にマッチしないリポジトリは commit+default@example.com へコミットメールを配信する。その際 From ヘッダーの値には Author の name と email を使用する。
プライベートリポジトリのコミットメールを流す場合
GitHubやGH:Eの場合は、検証していないのでわかりません。検証した人はこっそり教えてください。
GitLab の場合は、全てのリポジトリにReporter権限のユーザーを追加して、そのユーザーにパスフレーズなしの公開鍵を登録します。その上で以下のコマンドを一度実行して $HOME/.ssh/known_hosts に情報を登録しておきます。
$ ssh -T git@gitlab.example.com
この作業を忘れると、コミットメール配信用のリポジトリをミラーできません。
予告
GitLab でリポジトリを追加するたびに手動でWeb hookを追加するのは面倒です。 そこで、自動でWeb hookを登録できるWeb hook6としてgitlab-system-hooks-receiverを作りました。
またGitHubで自分の管理下にないリポジトリのdiff付きのコミットメールを読みたくなることがあると思います。GitHubのフィードだとdiffが付いていないため、diffの確認に一手間かかってしまいます。github-event-watcherを使うと自分の管理下にないリポジトリでもdiff付きのコミットメールを配信することができます。
次回はそれらの使い方を紹介します。
まとめ
GitHubやGitLabにあるリポジトリのコミットを色付きのdiffを含むコミットメールで通知する方法を紹介しました。