GitLabのrelease
ブランチにpushイベントがあったとき(⊃ マージされた時)にrelease
ブランチに自動反映できるようにします。
GitLab CI等のCIツールを入れるほどじゃない小さなアプリケーションを複数人で高速にサクッと開発していきたいときには、これぐらいでもいいのかなと考えています。
スクリプトは非常に簡単にPHPで書きます。
初心者向け:そもそもWebhookって何?
特定のアクションをトリガーとしてある指定したURLにHTTPリクエストを送ることのできるAPIのことです。
GitLabのwebhookではpushイベントをトリガーにできるので、
あとはURLだけ指定すれば決まったリクエストがpushイベントのたびに送られます。
これを使うと、特定のブランチにpushイベントが有ったときに何らか動作をさせる、という動作が可能になる、というわけです。
ぱっとググッたらここがわかりやすかったです。
https://sendgrid.kke.co.jp/blog/?p=1851
どんなふうに作るか
GitLabはpushイベント時にwebhookが使えるので、
http://webhook.mydomain.com/release.php
で叩き、
同サーバー内のアプリケーションのディレクトリでgit pull origin release
を実行させるようにする。
スクリプト
<?php
$secret_key = "secretkey"; // GitLab以外からのリクエストを受け付けないためのキー
$git_username = "bot"; // gitlabのログインパスワード
$git_password = "password"; // gitlabのログインパスワード
$log_file = '/path/to/webhook_log.txt';
$date = (new DateTime())->format('Y-m-d H:i:s');
$path_to_repository = '/path/to/repository';
$branch_name = 'release';
$git = '/usr/local/bin/git';
if ( !isset($_GET['key']) || !($_GET['key']==$secret_key) ) {
echo "Invalid key";
$is_logged = error_log("[{$date}] Error: Invalid key\n",3,$log_file);
exit;
}
$json_string = file_get_contents('php://input');
$json = json_decode($json_string,true);
error_log("[{$date}] Pushed to {$json['ref']}\n",3,$log_file);
if ($json['ref']=="refs/heads/{$branch_name}") { // releaseブランチのpushイベントの時のみ実行
$git_remote = "http://{$git_username}:{$git_password}@gitlab.mydomain.com/group/repository_name.git";
$command = "cd {$path_to_repository} && ${git} pull {$git_remote} {$branch_name} 2>&1";
exec($command, $output, $exit_status);
if ($exit_status > 0) {
$error_msg = "[{$date}] Error: \n";
foreach ($output as $line) {
$error_msg .= " {$line}\n";
}
error_log($error_msg,3,$log_file);
} else {
error_log("[{$date}] Updated successfully\n",3,$log_file);
}
}
webhook.mydomain.com
のようなサブドメインを作ってApacheなどでvirtualhostを作り、このドキュメントルートにこのrelease.php
を入れればOK。
また、git pull origin release
が実行されるのはApacheの実行ユーザーなので、コマンドやリポジトリのパスは絶対パスで指定したほうがいい。またリポジトリの所有権をApacheの実行ユーザーにしておいている。
GitLabのpushイベントのPOSTデータの中身は以下を参照。
https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/web_hooks/web_hooks.md
GitLabでの設定
リポジトリのsettingの中にwebhookという項目があるので、そこでpush
にチェックを入れて以下のURLを入力すればOK。
http://webhook.mydomain.com/release.php?key=secretkey
secretkey
は攻撃を受けないためのささやかな対策。
終わりに
超簡単ですがこれで反映ができるようになりました。
スクリプトはまだまだ改善の余地あり。
エラーじゃないのにerror_logでログはいてたり、権限設定がすごく面倒だったり。
あと、自動デプロイだけではバグが本番で見つかった場合に戻すのが手動なので、git clone
しなおしてシンボリックリンクを張り替える形式にしたほうがよいのかもしれないです。