SonarQube と TravisCI を使って Github でのコードレビューを自動化する

SonarQube を使用すると、静的解析により、コードに対するさまざまな指摘を受けることができます。この指摘を、コードレビューにも転用できたら、レビューコストもグッと下がって、いろいろ捗りそう。
というわけで実際にやってみました。

# 環境

- SonarQube 5.2
- SonarQube GitHub Plugin 1.1
- GitHub (2016-02-09 現在)
- Travis CI (2016-02-09 現在)
- Maven 3.2.5
- ORACLE Java 1.8.0_31

```
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=192m; support was removed in 8.0
Apache Maven 3.2.5 (12a6b3acb947671f09b81f49094c53f426d8cea1; 2014-12-14T17:29:23+00:00)
Maven home: /usr/local/maven
Java version: 1.8.0_31, vendor: Oracle Corporation
Java home: /usr/lib/jvm/java-8-oracle/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "3.13.0-40-generic", arch: "amd64", family: "unix"
```

# 事前準備

まず、SonarQube へ、GitHub Plugin がインストールされている必要があります。また、必要な情報として、Github のアクセストークン、SonarQube サーバーのログイン情報を準備します。

それぞれ、以下のように取得します。

## GitHub Plugin のインストール

すでにインストールが完了している場合は、この手順をスキップしてください。

SonarQube へログインし、[Administration] > [System] > [Update Center] > [Available] と進めると、"GitHub" が見つかるので、[Install] します。インストールが完了したら、SonarQube を再起動します。

## Github アクセストークン

プロフィールアイコンから、[Settings] へ進みます。

<img width="185" alt="スクリーンショット 2016-02-09 16.37.25.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/00a75e1c-281b-6e95-a693-c0e58066e21d.png">

サイドメニューから、[Personal access tokens] へ進みます。

<img width="236" alt="スクリーンショット 2016-02-09 16.38.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/e29cb4ea-1c3d-e08c-4068-e6e70dc608e8.png">

[Generate new token] ボタンから、トークンを新規作成します。

<img width="736" alt="スクリーンショット 2016-02-09 16.39.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/64c76c57-7e00-5d8a-6168-4848b2372cc8.png">

[Token description] にトークンの説明を記入し、[Select scopes] では、[repo] にチェックを入れ、[Generate token] ボタンをクリックして、トークンを生成します。

<img width="738" alt="スクリーンショット 2016-02-09 16.42.07.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/0bf94df3-aa1f-90f5-e001-35a7d19a465b.png">
<img width="738" alt="スクリーンショット 2016-02-09 16.44.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/1f2ee687-550b-ec37-902c-a86861bce30c.png">

生成されたトークンが表示されるので、これを控えておきます。

<img width="736" alt="スクリーンショット 2016-02-09 16.46.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/1eeae45e-c164-15bd-63e5-a60195933ce5.png">

## SonarQube ログイン情報

SonarQube サーバーの URL と、ログインに使用する、[Login] と [Password] を控えておきます。

![スクリーンショット 2016-02-09 16.47.58.png](https://qiita-image-store.s3.amazonaws.com/0/47993/17fab486-ae4b-cd51-fc5a-ecf53cdbe895.png)

## TravisCI 環境変数

ここまでで以下の値が揃ったはずです。

- Github アクセストークン
- SonarQube URL
- SonarQube ログイン ユーザー名
- SonarQube ログイン パスワード

これらの値を TravisCI に、環境変数として設定していきます。
プロジェクトのトップで、画面右上の [Settings] > [Settings] と進んでいきます。

![スクリーンショット 2016-02-09 16.52.31.png](https://qiita-image-store.s3.amazonaws.com/0/47993/fac274b2-0258-2cdd-4308-ce0c0a8cfea9.png)

先ほどの値を使用して、それぞれ以下のように設定していきます。

| Name           | Value                       |
|----------------|-----------------------------|
| GITHUB_OAUTH   | Github アクセストークン      |
| SONAR_HOST     | SonarQube URL               |
| SONAR_USERNAME | SonarQube ログイン ユーザー名 |
| SONAR_PASSWORD | SonarQube ログイン パスワード |

# ビルド構成

事前準備を終えたら、ビルド構成を作成していきます。

## .travis.yml

TravisCI を使用するので、プロジェクトルートに `.travis.yml` を作成、配置します。
以下のようなファイルを作成します。

```yaml:.travis.yml
language: java
jdk:
  - oraclejdk8
after_success: './sonar.sh ${TRAVIS_PULL_REQUEST} ${SONAR_HOST} ${SONAR_USERNAME} ${SONAR_PASSWORD} ${GITHUB_OAUTH}'
```

注目すべきポイントは `after_success` です。
`after_success` にはビルド成功時に呼び出されるスクリプトを記述できます。
ここでは、同階層に用意された `sonar.sh` を実行し、引数に `${TRAVIS_PULL_REQUEST}`、`${SONAR_HOST}`、`${SONAR_USERNAME}`、`${SONAR_PASSWORD}`、`${GITHUB_OAUTH}` を渡しています。

TravisCI では、事前に環境変数で定義された値を、スクリプト内で参照できるため、先ほど設定した、Github アクセストークンや、SonarQube ログイン情報などがここで使用されているわけです。

ただ、先ほど設定しなかった、`${TRAVIS_PULL_REQUEST}` については、事前設定した環境変数たちとは少々異なるもので、TravisCI 側で用意してくれるものになります。
値には、プルリクエスト番号が入ります。
なお、ビルドしているブランチがプルリクエストの対象でない場合には、`false` が設定されます。

## sonar.sh

引き続き、マニュアルも読みつつ、解析をおこなうためのスクリプトを作成していきます。
http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Maven

```bash:sonar.sh
#!/bin/bash

PULLS_NUMBER=$1
SONAR_HOST=$2
SONAR_USERNAME=$3
SONAR_PASSWORD=$4
GITHUB_OAUTH=$5

if [ $PULLS_NUMBER = 'false' ]; then
  exit
fi

mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.1:sonar -Dmaven.test.skip=true -Dclirr=true -Dsonar.host.url=${SONAR_HOST} -Dsonar.login=${SONAR_USERNAME} -Dsonar.password=${SONAR_PASSWORD} -Dsonar.sourceEncoding=UTF-8 -Dsonar.analysis.mode=issues -Dsonar.github.pullRequest=${PULLS_NUMBER} -Dsonar.github.oauth=${GITHUB_OAUTH} -Dsonar.github.repository=yo1000/fizzbuzz -B -e -V
```

内容としては、プルリクエスト番号が false ではなかった場合、sonar-maven-plugin を使用して、SonarQube サーバーに解析リクエストを投入し、受け取った解析結果を Github の対象プルリクエストにコメントさせる、というものになります。

TravisCI では、プルリクエストの発生や、対象ブランチの更新もビルドトリガとなるため、プルリクエストが上がってきたら、自動的にコードの静的解析と、結果のコメントまでがおこなわれるようになります。

# 動作確認

最終的なプロジェクトは以下のようになりました。
https://github.com/yo1000/fizzbuzz/tree/sonar-test-2

実際にひどいコード変更を入れて、プルリクエストを投げてみます。
https://github.com/yo1000/fizzbuzz/pull/2

![スクリーンショット 2016-02-09 17.29.40.png](https://qiita-image-store.s3.amazonaws.com/0/47993/17c6b5f0-94db-c43b-9498-40983a2a13c3.png)

TravisCI が動き始めます。

<img width="1011" alt="スクリーンショット 2016-02-09 17.32.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/47993/ad945413-ce5a-a715-13da-a9f06c95a501.png">

レビュー結果がコメントされましたね！！

![スクリーンショット 2016-02-09 16.03.47.png](https://qiita-image-store.s3.amazonaws.com/0/47993/8bdc74b5-750e-d764-a15a-589daac16bf5.png)

コメントをつけているユーザーは、Github アクセストークンに基づくので、自動レビュー用に別途ユーザーを用意してもいいかもしれません。

ここまでで連携は完了です。
SonarQube にコードレビューしてもらうことで、レビュー負荷が軽減されるだけでなく、よりレビューが必要なポイントにもっと時間を割けるようになっていき、レビュー精度も上がっていくことでしょう。
引き続き、もっと SonarQube を使い倒していきたいですね！