Unity のソースコードを SonarQube で静的解析する

# はじめに
プロダクト開発が長期化してくると、追加機能が当初の設計とそぐわなかったり、チームメンバの入れ替わりによって、コードのメンテナンス性が悪くなってくる。そこで、静的解析ツールの一つである [SonarQube](http://www.sonarqube.org) をCI環境に組み込み、コード品質を常に評価できる仕組みを構築する。CI環境には [Jenkins](https://jenkins.io) を使用する。

# 環境構築

以下のインスタンスを用意する。

- SonarQube
- Jenkins (slave)
- Jenkins (master)

## SonarQube 

以下の作業を行う。

- SonarQube のインストール
- アクセストークンの発行
- プロジェクトの作成

### インストールから起動まで

SonarQube の立ち上げについては[ここ](http://qiita.com/karasusan/items/643b2abeaab67bfc13b1)を参照。

### アクセストークンの発行

初期状態では admin アカウントでログインできる。 

```
username : admin
password : admin
```

![Screen_Shot_2016-08-21_at_10_26_54__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/a262fa0a-2688-fdb7-040c-89bdaa232d9e.png)


admin アカウントでログインしたら、Jenkins 用にアクセストークンを発行する。
メニューから `Administration` -> `Security` -> `Users` に移動する。

![Screen_Shot_2016-08-21_at_10_28_56__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/3085193a-ad9a-c320-a68b-943dd02188fa.png)

トークン名を入力し、 `Generate` ボタンを押す。

![Screen_Shot_2016-08-21_at_10_31_00__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/c1b051dc-2c35-c786-5e48-d2ad136fdcdf.png)

発行されたトークンをコピーする。このページを閉じるとトークンを再確認できなくなるので注意すること。

![Screen_Shot_2016-08-21_at_10_33_48__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/a4ca9eac-c4d7-cd99-9b8d-7ad36266df37.png)

### プロジェクトの作成

Unityプロジェクトのコード解析を行うには、SonarQube 側に対応するプロジェクトを作成する必要がある。

 `Administration` -> `Projects` -> `Management` に移動して、`Create Project` ボタンをクリックする。

![Screen_Shot_2016-08-21_at_10_48_29__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/24e55536-ec62-fca3-cbb6-3a0150bdb8fd.png)

プロジェクト名とキーを入力して（Branch は空欄で問題ない）、 `Create` ボタンを押す。

![Screen_Shot_2016-08-21_at_10_51_05__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/b2280bed-372a-9086-3bc7-decfe2c52491.png)


## Jenkins (slave)

Jenkins のスレーブとして動作させるインスタンス。
このインスタンス上で SonarQube Scanner が動作してコード解析を行う。

なお、このインスタンスは他のインスタンスと異なり、 MSBuild を実行する必要があるため、Windows 環境であることが必須になる。

以下のソフトウェアをインストールする。

- Unity
- MSBuild 14.0

### MSBuild のインストール

SonarQube Scanner は MSBuild 14.0 を要求するため、[chocolatey](https://chocolatey.org) からインストールするのが簡単。
以下のコマンドを PowerShell で実行する。管理者モードの PowerShell で実行する必要がある。

```sh
choco install microsoft-build-tools
```

## Jenkins (master)

Jenkins のコントロール用インスタンス。
あらかじめJenkinsスレーブマシンを登録しておくこと。

以下の Jenkins プラグインをインストールする必要がある。

- SonarQube プラグイン
- Unity プラグイン
- MSBuild プラグイン

### SonarQube プラグインの設定

Jenkins のシステム設定で SonarQube の設定を行う。

SonarQube の URL とアクセストークンを貼り付ける。

<img width="1052" alt="Screen_Shot_2016-08-13_at_12_46_00.png" src="https://qiita-image-store.s3.amazonaws.com/0/74764/5ca0ca15-764d-c280-c02a-ef1eed1a9911.png">

### MSBuild プラグインの設定

MSBuild のパスを指定する。

![Screen_Shot_2016-08-21_at_12_57_56__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/16b7d0da-7aa9-0363-1fdd-693ebd495135.png)

### SonarQube Scanner for MSBuild の設定

MSBuild 用の SonarQube Scanner のインストールを行う。
こちらも Jenkins の設定から行うことができる。github から自動でインストールするように設定しておく。

![Screen_Shot_2016-08-21_at_13_01_48__2_.png](https://qiita-image-store.s3.amazonaws.com/0/74764/31f38274-2188-60ff-38ed-287ae29e9bdc.png)


# Jenkins ジョブの設定

Jenkins ジョブを作成する。
以下のビルドステップを追加する必要がある。

- sln ファイルの生成
- SonarQube Scanner の起動

### sln ファイルの生成

Sonar Scanner を実行するには Unity プロジェクトの sln が必要になる。しかし、Unity プロジェクトでは sln はバージョン管理しないので、動的に生成する必要がある。

以下のコードを `Batch.cs` として、 Unity プロジェクトのEditor フォルダ以下に配置する。

```csharp
using UnityEditor;

public class Batch
{
    public static void OpenProject()
    {
        EditorApplication.ExecuteMenuItem("Assets/Open C# Project");         
    }
}
```

jenkins 側で Unity をバッチ起動して、上記の OpenProject メソッドを呼び出すと、解析に必要な sln ファイルや proj ファイルが自動生成される。
`Add Build Step` で `Invoke Unity3d Editor` を追加して、コマンド引数に以下のように指定する。

```
-batchmode -quit -projectPath "${BuildPath}" -logFile .\build.log -executeMethod Batch.OpenProject
```

![Screen_Shot_2016-08-21_at_13_09_52.png](https://qiita-image-store.s3.amazonaws.com/0/74764/f911b352-f335-ac23-52d5-9c04892c4b8e.png)

### SonarQube Scanner の起動

SonarQube Scanner for MSBuild を動作させるには、`Begin Analysis` -> `MSBuild` -> `End AnalySis` の順序でビルドステップを組み立てる必要がある。

まずは `Begin Analysis` のビルドステップを追加して、以下のように設定する。
引数に `/d:sonar.verbose=true` を指定すれば、 jenkins のログに SonarQube Scanner の全てのログが出力されるので、最初のうちは指定おいたほうがよい。

![Screen_Shot_2016-08-21_at_13_14_49.png](https://qiita-image-store.s3.amazonaws.com/0/74764/15a09765-ec47-9027-1af1-4128bcfa9577.png)

次に `MSBuild` のビルドステップを追加し以下のように設定する。

![Screen_Shot_2016-08-21_at_13_20_14.png](https://qiita-image-store.s3.amazonaws.com/0/74764/f1921557-531e-e40d-33ea-867ae155d37b.png)


最後に `End AnalySis` のビルドステップを追加する。

![Screen Shot 2016-08-21 at 13.20.20.png](https://qiita-image-store.s3.amazonaws.com/0/74764/eb54e36d-71b2-3842-d323-00f9ed197608.png)

これでジョブを走らせれば、SonarQube 側に解析結果が反映される。