Jenkinsを使ってGitHubのPull Requestが自動でテストできちゃう？



できちゃうんです。
CIの一環で、表題のような開発フローを試してみました。

# What's CI?
Continuous Integration（継続的インテグレーション）は、[こちらの記事](http://www.atmarkit.co.jp/ait/articles/1309/04/news022.html)によると、

>1度限りもしくは数回限りではなく、継続的に小まめにビルドを実行していくプラクティス 

のことです。


# Merits
ここも、[上記](http://www.atmarkit.co.jp/ait/articles/1309/04/news022.html)の引用ではありますが・・・。

- 想定外の状況が起こったときに、素早く検知できる
 - 仕込んでしまったバグを即座に検知できる
- 開発者の環境依存の問題を検知しやすくなる
 - 「私の環境では動くけど・・・」
- ビルドが属人化せずに画一的になりやすい
 - 「◯◯さんがビルドしたら失敗/成功した」

こういう状況に思い当たる節のある人も、いますでしょうか・・・？


# 役に立ちそうなツール
- [Travis CI](https://travis-ci.org)
 - 最近GitHubのプロジェクトに"build"とか"passing"とかタグがついてるあれ
 - [Travis CIを使ってみた: GitHubのレポジトリにバッジを貼りたかったから](http://rcmdnk.github.io/blog/2014/09/08/computer-github-travis/)
- [Circle CI](https://circleci.com)
- [Jenkins CI](http://jenkins-ci.org)

今回は、Jenkins CIを使ってみました。
主な選定理由は・・・

- 最も歴史が長く、情報入手が容易
- プラグインの種類が豊富


# Sample development flow試してみました

## 環境

- ローカル開発環境: MacBook Pro
- サーバ: AWS EC2
- VCS: Git
 - hosting service: GitHub (StashやBitBucket用の類似プラグインあり)
- サンプルアプリ: AngularJS, Java (JAX-RS)
- 依存管理: Maven
- アプリサーバ: Glassfish
- CIツール: Jenkins
- 開発フロー: [GitHub flow](http://qiita.com/tbpgr/items/4ff76ef35c4ff0ec8314)

開発フローは、masterから機能ごとにブランチを切るGitHubフローにしました。
git-flowは、個人開発には少し複雑すぎる印象を受けたので・・・。


## サンプルプロジェクトの準備

[前回のAPIドキュメンテーションの記事](http://qiita.com/kazuhirokomoda/items/c6c373c0f7ad2331ed4a#jax-rsアプリケーション作成)で紹介したような、JAX-RSアプリケーションを準備します。

## Jenkinsの設定

### インストール・初期設定
以下のリンクなどを参考に・・・
[Jenkinsのインストールと初期設定](http://hidemium.hatenablog.com/entry/2014/05/03/234917)
[Jenkins公式](http://pkg.jenkins-ci.org/redhat/)
[Jenkinsのセキュリティを設定する](http://dev.classmethod.jp/cloud/aws/jenkins_on_ec2/)

### プラグイン
GitHub pull request builder pluginの力を借ります！




### 事前準備

```bash:事前準備
# GitHubのボットユーザを作成する
## プラグインがGitHubのPull Requestにコメントするときに使う

# 対象リポジトリのコラボレータにボットユーザを追加する
## Settings > Collaborators

# jenkinsユーザの設定
## Jenkinsユーザでログイン
sudo su jenkins
			
# 公開鍵の作成
cd /var/lib/jenkins/.ssh/
ssh-keygen -t rsa
## パスフレーズは空
	
# 作成した公開鍵(id_rsa.pub)を、Jenkins用GitHubアカウントに追加

# jenkinsユーザのgit設定
git config --global user.email "hoge@XXXXX.co.jp" (Jenkins用アカウントのe-mail)
git config --global user.name "hoge" (user名)

# GitHubへのssh接続テスト
## うまく行かなければjenkinsユーザを/etc/sudoersに追加するといいかもしれない？（未確認）
sudo -u jenkins ssh -T git@github.com

```

### GitHub pull request builder pluginをインストール

### GitHub Pull Request Builder pluginの設定

```bash:プラグインの設定
# 「Jenkinsの管理」>「システム設定」> GitHub pull requests builder

# botアカウントのアクセストークンを設定
## 事前準備で作成したGitHubのボットユーザのユーザ名とパスワードを設定
## 「Create Access Token」
	
#「Admins list」にbotアカウントを追加します

# 「高度な設定」の確認
```

### Jobを作成する

```bash:ジョブの作成

# "GitHub project"フィールドに対象のリポジトリのURLを記述する
https://github.com/kazuhirokomoda/simpleMavenGlassfishJaxrs

#Git SCMを選択する

#Repository URLにGitHubのリポジトリURLを入力
git@github.com:kazuhirokomoda/simpleMavenGlassfishJaxrs.git

#「高度な設定」を開き、「Refspec」に入力
+refs/pull/*:refs/remotes/origin/pr/*

#「Branch Specifier」
${sha1}

#「ビルド・トリガ」
##「Github pull requests builder」にチェックを入れる

# adminのユーザ設定
## 上記pluginで登録したユーザがデフォルトで入る？

# whitelistにあるユーザーのpull requestのみ自動的にビルドされる。
## そのため、予めユーザーを追加しておくか、
## Organizationで利用している場合は「List of organisations. Their members will be whitelisted.」に対象のorganizationを加える。

```



## 開発フロー

### 説明的な名前のブランチをmasterから作成する
2つの数の割り算ができるAPIを開発するとします。

> /simple/path_param_division/11/2

そののためのブランチを、masterから直接作ります。(add-two-number-division)


```bash
git branch --all
git checkout -b add-two-number-division
git branch --all
```

### 作成したブランチでローカル開発/プッシュ
がんがん開発します。このブランチには頻繁にコミット・プッシュします。

```bash
git status
git add .
git commit -m コメント
git push origin add-two-number-division
```


### Pull Request を作成
add-two-number-divisionブランチから、masterブランチへPull Requestを作成します。
![github_open_PR.png](https://qiita-image-store.s3.amazonaws.com/0/32910/be7b41fb-52fd-e002-a206-fe7d4caa0a32.png)


そうすると、cronで設定した時刻にJenkinsのジョブが起動し、あらかじめ用意したテストケースが実行されるので、reviewerはこの情報も参考にしながらレビューができます。

自動テスト実行中...
![github_during_part.png](https://qiita-image-store.s3.amazonaws.com/0/32910/684946b3-c196-5c97-9983-887c797245a4.png)



### 自動テストNG
あれ。。。

![github_failure.png](https://qiita-image-store.s3.amazonaws.com/0/32910/b99b55e0-cd04-1cca-ea99-785a28b03f53.png)

- "Details"リンクでJenkinsのジョブに飛んで、エラーを確認できる
- 11/2 = 5.5になることを期待していたが、Integerで割り算すると5になる


### 再度、ローカル開発/プッシュ
- Integer型からDouble型に変更
- 同じブランチにpushで、再びテストが実行される
- 自動テストOK

![github_success2.png](https://qiita-image-store.s3.amazonaws.com/0/32910/e2edd388-5a61-6a9f-4c7e-6d16ec126601.png)



### reviewerがmasterへマージ
GitHubとかStashとかだと、ボタン一つでマージできますね。

### 使わないブランチを消したければ

ローカルのmasterブランチにも変更を反映した上で

```bash
git checkout master
git pull origin master
```

[こちら](http://qiita.com/makoto_kw/items/c825e17e2a577bb83e19)を参考に

```bash
git branch -d add-two-number-division
git push origin :add-two-number-division
```


### なるべく早くデプロイ
しましょう。


# おわりに

GitHubとJenkinsを使って、エンジニアがPull Requestを出したタイミングでテストを自動で走らせ、

- 単純なミスがリリースに紛れ込む可能性を減らし
- reviewerの負担も減らす

ことができそうな枠組みを試作してみました。