Hookの機構を使うと、GitHubに変更がプッシュされたタイミングで自動的にJenkinsのジョブが走るようにすることができます。ポーリングに比べて、プッシュからビルドまでの時差が減り、無駄な通信も減りますが、アクセス制御が有効になっている場合の設定で少しはまってしまったので方法を書いておきます。
Hookをトリガーにしたビルド
Gitには、コミット直前やプッシュ完了時など、任意のタイミングでスクリプトを実行できるHookという機構があります。この機構を利用すると、レポジトリに変更がプッシュされたタイミングでJenkinsのジョブを実行させることができます。
GitHubの場合は、レポジトリのAdmin -> Service Hooksページ内でHookの設定ができます。幸い、Jenkinsと連携させるための項目が最初から用意されています。ここでJenkins内のジョブ実行用のURLを指定しておくと、プッシュがあったタイミングでそのURLにリクエストが送信され、Jenkins側でジョブが実行される、という仕組みです。
GitプラグインとGitHubプラグイン
Hook経由でJenkinsのジョブを実行させるにはGitプラグインを使う方法とGitHubプラグインを使う方法の二つがあります。GitHub上でもそれぞれ設定できるようになっています。
アクセス制御
GitHubプラグインの方は、Jenkinsの方でGitHubのアカウントを設定しておくと、自動的にこのHookの設定もやってくれる機能があったりして便利なのですが、残念ながらJenkins上のアクセス制御が有効になっている場合の設定方法に関する有効な資料がまとまっていませんでした。
実際のJenkinsの運用では、セキュリティ面での問題から基本的にはアクセス制御を有効にしておくべきです。幸いGitプラグインの方では、アクセス制御が有効になっている場合でも問題なくジョブを実行できるので、Gitプラグインの方を使いましょう。
Gitプラグインを使った設定
Gitプラグインを使った設定方法については、Jenkinsの作者でもあるKohsuke Kawaguchiさんのポスト「Polling must die: triggering Jenkins builds from a git hook」にて説明されていますが、Gitプラグインが有効になっている状態で
http://Jenkinsサーバー/git/notifyCommit?url=gitのレポジトリURL
というURLを叩くと、Jenkins側でそのレポジトリに関連するすべてのジョブが実行されます。GitHubのレポジトリのService Hooks上からJenkins (Git Plugin)を選択し、ここでこのURLをセットし「Active」にチェックをつけましょう。
注意しなければいけない点としては、
- この方法で動かしたいジョブはSCMポーリングを有効に設定しておくこと
- Multiple SCMsで複数レポジトリを設定している場合は実行されない
というものがあります。なお、Multiple SCMsを使っている場合は上流プロジェクトを一つ用意して、そこで単一のレポジトリをセットする方法がよさそうです。
動作テスト
GitHub上で設定をする前に、curlコマンドを使ってそのURLをたたいてみましょう。
curl "http://example.com:8080/git/notifyCommit?url=git@github.com:foo/bar"
正常に受理されると、ポーリングがスケジュールされたジョブの一覧が表示されます。
Scheduled polling of BarBuild
なお、このリクエストではポーリングがスケジュールされるだけなので、実際にレポジトリ上で変更がなかった場合はビルドは実行されません。
GitHubのHookの設定
最後に、GitHubのService Hooksの設定から上のURLを設定してActiveにセットしたら完了です。試しに適当な変更をプッシュしてみて、ビルドが実行されるかチェックしてみましょう。
“GitHubとJenkinsの連携 | なんてこったいブログ” http://t.co/NEwXSgLd
GitHubとJenkinsの連携 http://t.co/Xe7mBmVx @croquette0212さんから
“GitHubとJenkinsの連携 | なんてこったいブログ” http://t.co/WI7eZpeF
参考になりました!「Jenkinsを使ったiOSアプリビルド自動化11 GitHubとJenkinsの連携 | なんてこったいブログ http://t.co/njGtAxy5」