イマドキの GitBucket + Jenkinsの連携は Jenkinsfile と GitHub Organization Folder プラグインでこんなに簡単（になる予定）

# TL;DR

GitBucket と Jenkins の連携はとても簡単なのですが、2017/3/末リリースのGitBucket の 4.11（か、5.0かも？） を待ってください。
GitHub Oraganization Folder を使った設定をしておくと リポジトリに Jenkinsfile を置くだけで GitBucket - Jenkins の連携が全部自動的に設定されます。

# 注意

**この記事はGitBucketの未リリースの機能について書いています。上手くいけば2017/3/末にリリースされる4.11(?)に含まれる見込みです。**

Jenkins の GitHub Branch Source Plugin バージョン 2.0.0 以降（？）で GitHub API の使い方が大きく変更になり、GitBucket 4.10 までの API 実装では対応できず、Jenkins 側で NullPointerException が発生するようになっています。
[#1478](https://github.com/gitbucket/gitbucket/pull/1478) がマージされているので、今月末にリリースされるバージョンでは解決しています。
[#1488](https://github.com/gitbucket/gitbucket/pull/1488) がマージされると、この記事で解説する User/Group レベルの WebHook 設定が実現されます。

# 前提

* GitBucket 4.11 以降
* Jenkins 2.x
* Jenkins のプラグインはインストール時にオススメで入るものだけ

GitBucket プラグインや GitHub Pull Request Builder プラグインは使わない。

# 本記事での設定

GitBucket を直接 80 番ポートで動かしています。URL は http://localhost/ です。

Jenkins は 10080 番ポートで動かしています。（別アプリが8080を使っているため・・・）URL は http://localhost:10080/ です。

本記事では Windows で動かしていますが、Linux/Mac でも特に変わりは無いと思います。一応、git のバージョンには注意した方がいいかもしれません。

# Git の設定

Windows に限り、Jenkins が Git で GitBucket にアクセスするときにパスワードを訊ねるダイアログが出ないように、以下の設定が必要になります。コマンドプロンプトを（多分）管理者権限で開いて以下のコマンドを実行してください。

```
git config --system --unset credential.helpers
```

Git をインストールした時の選択にもよりますが、デフォルトでcredential.helpers=managerと、システムに設定されているため credential-manager.exe という GUI のアプリケーションがパスワードを訊ねるダイアログを出るようになっています。
ログインしたユーザが使うには便利なのですが、サービスで Jenkins を実行しているときには GUI がいつまでも入力を待ち続けてしまうので困ってしまいます。ですので、システム全体の設定からこの設定を外してやる必要があります。
このままだとログインしたユーザが使うときにダイアログが出なくなって不便なので、その場合はそのユーザで `git config --global credential.helpers manager` と実行しておくといいでしょう。
本番サーバで、ユーザがログインして Git を使うことを想定していないときには `git config --global credential.helpers manager` は実行しないでも構いません。

# GitBucket の設定

## 重要な設定

HTTP なら **80** 番、HTTPS なら **443** 番ポートで git リポジトリへのアクセスが出来ることが必要です。実現方法は大きく分けて2つ、GitBucket が直接 80 番ポートで待ち受けるか、Apache や nginx などでリバースプロキシを構成するかのどちらかです。

どうにかして、http://servername/username/reponame.git で Git リポジトリにアクセスできるようにしてください。

## ユーザ設定

適当なユーザとグループを設定するものとします。説明では root ユーザと gr1 グループを使うことにします。gr1 グループには root ユーザが所属しているものとします。

## WebHook 設定

gr1 グループに対して Group レベルの WebHook を設定します。
http://localhost/gr1 にアクセスして、WebHooks タブを選択します。

![204614-gr1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/95ff1c14-1b5f-cb65-dbdb-5e1b2917580e.png)

![204752-gr1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/256639aa-35bc-5cb6-79cc-7db34065d44f.png)

Add webhook ボタンを押して出てくる画面で、以下の設定をします。

* Payload URL に http://localhost:10080/github-webhook/ を設定します。最後の/を忘れないように。
* Content type は application/x-www-form-urlencoded のままで OK です。
* Security Token は空白で OK です。
* Which events would you like to trigger this webhook? の下のチェックボックスでは Pull Request と Push の2つにチェックを入れます（Push はもともとチェックされてます）。

設定を入力すると下図のようになります。

![205142-gr1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/945b09f8-5515-6b6c-5dbf-d64d4035487a.png)

ここで、Test Hook ボタンを押して確認をします。下図のように Response 200 となっていれば OK です。

![205236-gr1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/2b4e7483-f461-ccfb-7871-3c864eef8117.png)

最後に Add webhook ボタンを押して webhook を追加しましょう。

GitBucket の設定はこれで終わりです。**これ以降、何個リポジトリを作ろうと、このグループに対しては GitBucket で設定をする必要はありません。**

[#1488](https://github.com/gitbucket/gitbucket/pull/1488) がマージされるまではグループレベルの Webhook 機能が無いので、全てのリポジトリに対して1個ずつ Webhook を設定してください。

# Jenkins の設定

まず、GitBucket の URL を Jenkins に登録します。Jenkins には見かけ上、GitHub Enterprise のように振舞う（API が同じ）ので、GitHub Enterprise を登録するような気持ちで設定してください。

Jenkins の管理→システムの設定で、「GitHub」と「GitHub Enterprise Servers」の2箇所に登録します。確か、前者が Jenkins の Webhook で送り元が正しいか調べるような奴で、後者が GitHub Organization Folder プラグインなどで使ってるやつだったような・・・あまり良く分かっていませんが、両方きちんと設定しておきましょう。

![205632-システムの設定 [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/141e9715-bc5e-5f09-4571-39dc533cd529.png)

API URL (API endpoint) は http://localhost/api/v3/ です。Credentials はなしで構いません。システム全体にパスワード・API キーを登録する必要はないです。

Manage hooks は上で設定した Group レベルの WebHook を Jenkins が自動的に設定してくれる機能のオン・オフですが、現時点ではその API に GitBucket が対応していないため、どちらでも関係ありません。

GitHub Enterprise Servers のほうの Name は分かりやすいようにつけます。

![210210-システムの設定 [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/028c4269-027f-96ec-7842-923667a8274c.png)

こんな感じに設定して保存を押します。

## ジョブ（GitHub Organization Folder）の設定

新規ジョブの作成から、GitHub Organization を選択し、名前を適当につけて OK を押します。

![210753-新規ジョブ作成 [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/865c8efc-a200-9d3b-a7c4-d44f5b9d14b0.png)

Projects→GitHub Organization→API endpointで上記で設定した GitBucket の endpoint を選択します。

Owner に gr1 を設定します。今回はグループを設定していますが、ユーザを設定することもできます。

Scan credentials の右の「追加」ボタンから Jenkins を選び認証キーの登録をします。ユーザ名 root と対応するパスワードを入れて追加を押します。

![211222-GHO-gr1 Config [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/3564c28c-79fb-f06f-bd0d-667a9cef39a5.png)

root/***** がScan credentials に追加されるので、それを選択します。

他の設定項目はデフォルトのままで OK ですので、保存ボタンを押します。

![211334-GHO-gr1 Config [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/f873d87d-c396-58ba-1c74-1f0d6a1087be.png)

Scan Organization コンソール出力という画面に変わります。

![211418-GHO-gr1 Scan Organization Log [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/36845884-dc76-22a3-6c15-1fd78e5cf6f6.png)

最後の行に Finished: SUCCESS とあることを確認してください。FAILURE（だったかな？）などの場合は認証キーや API endpoint の設定あたりが間違っていると思われます。

以上で Jenkins 側の設定は終わりです。**これ以後は何個リポジトリを作ろうと、Jenkins の設定は不要です**

# 普段のユースケース

## リポジトリの作成と Jenkinsfile の配置、実行の確認

設定は全て終わっているので、gr1 にリポジトリを作成し、Jenkinsfile を配置するだけで自動的に Jenkins のビルドチェックが走ります。

ここでは test1 という名前のリポジトリを作ってみます。

![211856-Create a New Repository - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/e9722939-dc5f-9db4-01ce-8ffe96968735.png)

README を作っておいたので、リポジトリの操作をブラウザからできます（ないと作業マシンから push しないとならない）。

![212108-gr1／test1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/125ab65a-78d0-1aa8-32b8-d39c2e090a0c.png)

+ ボタンで新規ファイルとして Jenkinsfile を作成します。内容は適当にそれっぽくジョブの定義をしてみます。

![212300-New File - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/9462632a-584a-dd1d-5e66-9532dc6b50b8.png)

Commit changes ボタンを押してこのファイルをコミットすると、先に設定しておいた Push Webhook が実行されて Jenkins に通知が飛び、Jenkins 側が自動的にリポジトリをスキャンします。
スキャンしたときに Jenkinsfile が見つかると、GHO-gr1 フォルダーの下に test1 ジョブが自動的に登録されます。

![213559-default [GHO-gr1 ≫ test1] [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/f54859d7-8ded-47dd-6048-703cd0eec12b.png)

test1 ジョブはブランチ・プルリクエストごとにさらにジョブが定義されています。今は master ブランチだけがあります。

![213650-default [GHO-gr1 ≫ test1] [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/3ddedabe-72b9-fd88-f8e9-04c9c234a418.png)

master ブランチのビルド結果を見ると、パイプラインを実行した結果が見られます。

![213741-master [GHO-gr1 ≫ test1] [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/281787af-84e4-b392-c3fa-ef6036223b32.png)

## プルリクエスト時の動作確認

続けて、プルリクエストを作成してみましょう。まずは pr-test という名前でブランチを作ります（手抜きで Web UI から操作します）。

![214059-gr1／test1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/2f9a2896-bfef-7f59-c48d-288fb423620a.png)

最初はビルドに失敗するようにしたいので、Jenkinsfile の構文エラーになるようにしておきます。

![214253-Editing Jenkinsfile at pr-test - gr1／test1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/d87d6544-804e-34bc-bf55-9678c2e5bbde.png)

Branches から New Pull request でプルリクエストを作ります。

![214409-gr1／test1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/97111b3c-7e35-e8d6-4e9a-3e238524e87c.png)

![214445-Pull requests - gr1／test1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/043b1849-d578-1fc9-9c62-21ddf06317fe.png)

作成したプルリクエストに Jenkins でのチェック結果が自動的に反映されています。

![214550-Create Bad PR . - Pull request #1 - gr1／test1 - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/5cee83d4-72dc-84ff-a0ca-1b8dfd2b9b5a.png)

このブランチに修正を加えてももちろん自動的に Jenkins チェック結果が反映されます。ですので、後は Jenkins のチェックが通るまで修正すれば良いというわけです。

Jenkins 側に戻ると、今作った pr-test ブランチが増えています。ビルドステータスも失敗ですね。

![214751-default [GHO-gr1 ≫ test1] [Jenkins] - Google Chrome.png](https://qiita-image-store.s3.amazonaws.com/0/53147/43b91bfa-1186-dcd1-f20b-c150349ee9fd.png)

# 後は・・・

ここまで出来れば、後はいくつリポジトリを作ろうが、Jenkinsfile さえ置けば Jenkins が自動的にビルドしてくれます。連携が問題あるようなら Jenkinsfile を置かなければ良いです（ブランチごとにチェックされます）。

説明の都合上、GitBucket の root パスワードを Jenkins に登録するとかいうアレなことをしていますが、Jenkins 専用のユーザを作るなり適当に対処してください。

Jenkins のチェックが入るようになったので、リポジトリの設定でブランチプロテクションでチェックをパスしないとマージできないようにするとか出来ます。

GitHub Organization Folder プラグインの「グループ内全リポジトリに対して処理される」という機能が嫌だとか何か理由があるときは、Multibranch Pipeline を使うと良いでしょう（多分こちらも現時点での Jenkins プラグインと GitBucket 4.10 の組み合わせでは動かないので、4.11 を待つ必要があります）。