Multibranch PipelineによるJenkinsとGitBucketの連携
JenkinsのMultibranch Pipelineを利用するとCIで以下ができるようになります。
- ビルドの設定を
Jenkinsfile
に書いてバージョン管理できる。 - リポジトリへのpushやPull Requestのマージを契機にジョブを実行できる。
- パイプラインでビルドフローを分かりやすく記述できる。
(2017/10/3追記) GitBucketの公式Wikiに設定方法を書きました。
以下の情報は古いため、GitBucketの公式Wikiを参照してください。
JenkinsとGitBucketを連携させるにはGitBucket Pluginを使う方法がありますが、GitBucketの仕様によりPull Requestのマージを契機にジョブを実行できない制約があります。Multibranch Pipelineを使うとPull Requestのマージを契機にジョブを実行できたので、設定方法をまとめてみました。
前提
GitBucketにGitHub互換のURLでアクセスできるようにリダイレクトを設定する必要があります。GitBucketの手前にリバースプロキシを入れて、リダイレクトの設定を書くのが簡単でしょう。詳しくは下記の記事を参照してください。
(10/7追記)上記の記事の内容だと、OrganizationsのリポジトリにPipelineを設定しようとするとエラーになりました。GitBucketでは /api/v3/users/:name
でOrganizationの情報を取得できないためのようです。
GitBucketのワークアラウンド
まとめるとGitBucketで以下に対応する必要があります。
- GitHub互換URLでgit fetchするためのリダイレクト
- リダイレクト元:
/:user/:repo.git*
- リダイレクト先:
/git/:user/:repo.git*
(先頭に/git
を付加する)
- リダイレクト元:
- Organizationsの情報を/usersで取得できるようにする
/api/v3/users/:user
がエラーを返したら/api/v3/orgs/:user
を試す。それでもエラーの場合はあきらめる。
nginxを下記のように設定すれば動くようになります。
# nginx.conf server { listen 80; server_name git.example.org; client_max_body_size 10M; # GitHub互換URLでgit fetchするためのリダイレクト location ~ ^/[^/]+/[^/]+\.git.*$ { return https://git.example.org/git$request_uri; } # Organizationsの情報を/usersで取得できるようにする location ~ ^/api/v3/users/(.*)$ { proxy_intercept_errors on; error_page 404 = /api/v3/orgs/$1; # 以下はlocation /と同じ proxy_pass http://gitbucket:8080; proxy_set_header Host $host; } location / { proxy_pass http://gitbucket:8080; proxy_set_header Host $host; # 以下はNginxより手前にSSLロードバランサがある場合の設定 proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto; proxy_set_header X-Forwarded-Host $host:$http_x_forwarded_port; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $http_x_forwarded_for; } }
(10/10追記)Pull Requestを送ってみたので、将来のバージョンでは改良されるかもしれません。
GitBucketの設定
GitBucketにjenkinsユーザを作成します。適当なパスワードを設定しておきます。Normalユーザで構いません。
リポジトリのWebhookを設定します。Jenkinsが https://jenkins.example.org で動いている場合は https://jenkins.example.org/github-webhook/ がWebhook URLになります。最後のスラッシュは必要です。
リポジトリにJenkinsfileを作成します。ここでは以下の内容にします。
node { stage('Fetch') { checkout scm } stage('Build') { sh 'env' } }
Jenkinsの設定
Jenkinsの設定画面を開き、GitHub Enterprise ServersでGitBucket APIを追加します。GitBucketが https://git.example.org で動いている場合は https://git.example.org/api/v3 がAPIのURLになります。
JenkinsからGitBucketにアクセスできるようにjenkinsユーザの認証情報を追加します。パスワードはGitBucketのjenkinsユーザのものです。
JenkinsでMultibranch Pipelineジョブを作成します。
Branch sourceにGitHubを追加します。まず、API endpointでGitBucketを選び、Ownerにユーザ名を入力すると、リポジトリ一覧が表示されるようになります。Scan credentialsには先ほど追加したjenkinsユーザを指定します。
ジョブを作成すると、自動的にブランチ一覧を取得するジョブが実行されます。GitBucketへのアクセスに問題がなければmasterブランチが表示されるはずです。
リポジトリへのPushによるビルド実行
リポジトリのmasterブランチを更新してみましょう。ここでは、GitBucketの画面からREADME.mdを編集してコミットします。
Webhookの設定で問題がなければ、Jenkinsのジョブが実行されるはずです。
masterブランチのジョブでFull Stage Viewを選ぶと、パイプラインのステータスを確認できます。
Pull Requestのマージによるビルド実行
リポジトリにPull Requestを作成してみましょう。ここでは、GitBucketの画面から新しいブランチを作成し、README.mdをコミットします。そして、ブランチ一覧の画面からPull Requestを作成します。
GitBucketの画面からPull Reqeustをマージします。Jenkinsを確認すると、マージを契機にジョブが実行されているはずです。
GitBucketのリポジトリ設定でProtected Branchを設定することで、CIを通ったブランチしかマージできないように品質ゲートを設けることも可能です。
まとめ
Multibranch Pipelineを使うとTravis CIやCircle CIのようなモダンなCIを実現できます。よさそうなので実戦投入してみよう。