SonarQubeでソースコードの品質チェック

# ゴール
こんな感じでSonarQubeさんからコードレビューされます。
各種言語のソースコードでダメな内容をLint的な感じで教えてくれます。
リンククリックで該当箇所も表示されます。

![review.png](https://qiita-image-store.s3.amazonaws.com/0/55077/b04607b4-458d-1f5e-d7d5-2fdf9cffa958.png)
![review2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/70bf8d0f-e56b-4a78-0282-131d074efb4b.png)



# コードの品質担保
プロジェクトが大きくなると技術的負債がソースコードに蓄積されていきます。
技術的負債がたまってくると新規機能追加や既存機能改修時に色々悪影響が出てきてプロジェクトが遅延します。
技術的負債がたまるにつれ、リファクタリングコストが高くなり、
最悪作り直しの方が早いという結果にもなりかねません。:anger: 
何より常時問題がある箇所を直していれば、誰かが書いた負債を引き継がなくて済むというメリットがあるので
精神的な負荷を下げることができます。:smile:

# 手動でのコードレビューはしんどい
かといって目見でコードレビューをするには人的コストもかかるし限界もあります。
ツールを使い自動でやる場合は、ソフトウェアメトリックスという指標でソースコードの品質評価を行うのが一般的です。
SonarQubeを使えば、以下のソースコードを自動的に算出してくれます。

* 論理コードの行数(LOC)
* 問題箇所、問題の重要度
* 技術的負債を返済する時間の目安
* 複雑度
* コード重複率
* 履歴

日本語化プラグインが中途半端なため、英語と日本語が混じってしまっていますが・・・

![sdk.png](https://qiita-image-store.s3.amazonaws.com/0/55077/71091bac-2095-fd49-b444-06749bca8cfc.png)


# 構成図
次のような構成にします。

* GitLab
* Jenkins
* SonarQube

![flow.png](https://qiita-image-store.s3.amazonaws.com/0/55077/70dbb11d-14cd-0e2f-3091-b9205b1c5158.png)

# ローカルから直接SonarQubeにアップロードする方法
前座としてローカル(Mac OSX)から直接SonarQube Serverにアップロードする方法を示します。
参考：[Mac OS X に SonarQube 導入 - UnityのC#コーディング規約チェック](http://kenzo0107.hatenablog.com/entry/2014/06/22/024501)


## SonarQube Serverのインストール
SonarQube Serverはこちらよりダウンロードできます。（6.0で試しました。）
公式：[SonarQube](http://www.sonarqube.org/downloads/)

![Download.png](https://qiita-image-store.s3.amazonaws.com/0/55077/36aa46e5-f986-54b0-65d9-405b6eaba8dc.png)


## SonarQube Serverの起動
SonarQubeはJavaで動いています。

SonarQubeサーバを動かす前に
DBをインストールして次のスキーマとユーザを作成する必要があります。

* スキーマ名:sonar
* ユーザ:sonar
* パスワード:sonar

DBは次のメジャーなものに対応しています。

* Oracle
* Postgre
* MySQL
* SQL Server

ローカルのMySQLの場合は次のように作成します。

```
$ mysql -u root -p(MYSQL_PASSWORD記載のパスワード)
>CREATE DATABASE sonar;
>CREATE USER 'sonar'@'localhost' IDENTIFIED BY 'sonar';
>GRANT ALL PRIVILEGES ON sonar.* TO 'sonar'@'localhost';
>exit;
```

SonarQube Server設定ファイルにDB接続設定を編集します。
設定ファイルはsonarqube-6.0/conf/sonar.propertiesです。

```
# User credentials.
# Permissions to create tables, indices and triggers must be granted to JDBC user.
# The schema must be created first.
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar

#----- Embedded Database (default)
# H2 embedded database server listening port, defaults to 9092
#sonar.embeddedDatabase.port=9092
#----- MySQL 5.6 or greater
# Only InnoDB storage engine is supported (not myISAM).
# Only the bundled driver is supported. It can not be changed.
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance
```

Postgreの場合はJDBCドライバーをjdbc:mysqlではなく、jdbc:postgreに置き換えてください
次のsonar.shでSonarQube Serverを起動できます。

```
$./sonarqube-6.0/bin/macosx-universal-64/sonar.sh start
```

正常に起動すると9000ポートで立ち上がります。
http://localhost:9000

画面下に赤い警告が出ている場合はDBに接続できていないので接続設定を見直してください
（その場合はh2 DBでインメモリとして起動してる模様）

右上のログインボタンよりログインします。
ユーザ：admin
パスワード：admin
![SonarQube.png](https://qiita-image-store.s3.amazonaws.com/0/55077/05b0c604-6787-4dda-5b8e-cefe12a9a456.png)


## SonarQube Serverに解析プラグインを入れる
Administoration→System→update center→Availableよりインストールできます。
![plugin.png](https://qiita-image-store.s3.amazonaws.com/0/55077/f9644fd4-587a-e572-b489-781d63319440.png)

次の各プログラミング言語で使う解析プラグインを入れておくと良いでしょう。

* Android
* CSS
* JavaScript
* Web
* C/C++,Objective-C(有償)
* Swift(有償)
* PHP
* Python
* C#
* VB.Net(有償)

有償プラグインに関してはライセンスキーが必要です。

Rubyに関しては検索にでてこないので次よりダウンロードして
[SonarQube Ruby Plugin](https://github.com/GoDaddy-Hosting/ruby-sonar-plugin)

SonarQube Serverのプラグインフォルダに放り込みます。
プラグインフォルダは下記にあります。
 sonarqube-6.0/extensions/plugins

SonarQubeを再起動します。


## SonarScannerで解析してみる
ローカルからSonarQube ServerにアップロードするためにはSonarScannerをインストールします。
下記よりダウンロードします。
[Analyzing with SonarQube Scanner](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner)

![download2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/e36c556e-3079-9695-ffa1-048074ae3463.png)


SonarScannerの設定ファイルを編集します。
sonar-scanner-2.7/conf/sonar-scanner.properties

SonarQube ServerとDBへの接続情報を記述します。

```
----- Default SonarQube server
#sonar.host.url=http://localhost:9000

#----- Default source code encoding
sonar.sourceEncoding=UTF-8

#----- Global database settings (not used for SonarQube 5.2+)
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar

#----- MySQL
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&amp;characterEncoding=utf8
```

解析したいソースファイル対象のフォルダに次のようなsonar-project.propertiesファイルを作成します。

```
# Project identification
sonar.projectName=AppName
sonar.projectKey=Javascript:TestApp
sonar.projectVersion=1.0

# Info required for Sonar
sonar.sources=（解析したいソースコードのフォルダパス）
sonar.exclusions=（解析から除外したいパス）

# Comma-separated paths to directories with sources (required)
sonar.language=js

#----- Default source code encoding
sonar.sourceEncoding=UTF-8
```

sonar.projectName,sonar.projectKeyはアプリ単位に識別するためのものです。
sonar.languageは解析する言語指定です。Javascriptだとjsを指定します。例えば、C#の場合はcsを指定します。
sonar.sources、sonar.exclusionsはカンマ区切りで複数指定できます。
適宜変えてください

sonar-project.propertiesがあるフォルダでsonar-runnerを実行します。
sonar-runnerをaliasなどに登録しておくと便利かもしれません。

```
$sonar-scanner-2.7/bin/soner-runner
```

アップロードに成功するとSonerQube Serverに次のような解析結果が表示されます。
![js.png](https://qiita-image-store.s3.amazonaws.com/0/55077/5bf765b3-e652-e521-9516-d2bafba731c2.png)


##  ダッシュボードのカスタマイズ
ダッシュボードにてウィジットの編集ができます。
![widget.png](https://qiita-image-store.s3.amazonaws.com/0/55077/3bc0097f-a51c-4170-90cd-11f2f2f3e0dd.png)
好きなレイアウトを選択して表示したい解析結果をカスタマイズしましょう。
![widget2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/4f4bf47f-a163-7374-ee59-7bd33ceb51e7.png)


# GitLab、Jenkins、SonarQube連携
それではGitLabからJenkins経由でSonarQubeを動かし、ソースコードレビュー結果をGitLabにコメントしてもらいましょう。
GitLab、Jenkinsのインストールに関しては省略します。
参考:[Jenkins + SonarQube で PHPコードメトリクス計測！](http://kenzo0107.hatenablog.com/entry/2016/05/21/010902)

## WebHook連携
Gitプッシュ時にJenkinsのジョブが起動するようにします。

Git PluginとGitLab Hook PluginをJenkinsにインストールし、Gitリポジトリにアクセスできるcredentialを作成します。
参考：[GitLab と Jenkins を連携する(1)](http://qiita.com/garbagetown/items/fe055dcfd8e0c090e610)

Jenkinsプロジェクトでビルド・トリガーの
Build when a change is pushed to GitLab. GitLab CI Service URL項目にチェックを入れます。
このときWebHookのURLが払い出されます。
![webhook1.png](https://qiita-image-store.s3.amazonaws.com/0/55077/1c2772ad-bfe5-72c5-fe3f-39bdeee902c5.png)
GitLabのプロジェクトのWebHook項目にて先ほどのWebHook URLを設定します。
![webhook2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/61480e65-2bdc-1fc8-3e58-4051ccd25891.png)


## SonarQubeユーザトークンの払い出し
設定→セキュリティー→ユーザ
![token0.png](https://qiita-image-store.s3.amazonaws.com/0/55077/d1548a98-0c98-6f17-8bf8-783247adf5b6.png)
![token1.5.png](https://qiita-image-store.s3.amazonaws.com/0/55077/82964c8c-6478-5148-4c6a-3531f87fb1d3.png)
Tokens項目をクリックしてトークンを払い出します。
![token1.png](https://qiita-image-store.s3.amazonaws.com/0/55077/7665c0b9-b37e-ef03-92c6-47c4ac0f2586.png)
トークン名は適当で構いません。
![token2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/47d799db-6452-b031-9d77-9de71a77f2ff.png)


## GitLabユーザトークンの払い出し
Profile Settings→Access Tokenよりユーザトークンを払い出しします。

![gitlkab_token.png](https://qiita-image-store.s3.amazonaws.com/0/55077/ead4c79e-5862-94bc-ae10-51d7f64a1c4c.png)

![gitlab_token2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/19c88f70-95a8-103e-c29f-9d3ea759dcc6.png)


## Sonar GitLab Pluginの導入
[Sonar GitLab Plugin](https://gitlab.talanlabs.com/gabriel-allaigre/sonar-gitlab-plugin)をSonarQube Serverにインストールします。


sonarqube-6.0/extensions/pluginsフォルダ以下にsonar-gitlab-plugin-1.7.0.jarをダウンロードして格納します。
SonarQubeを再起動します。

設定→プロジェクト→GitLab→Reportに
GitLabのURLとGitLabのユーザトークンを指定します。
![sonar-gitlab1.png](https://qiita-image-store.s3.amazonaws.com/0/55077/66a2acf5-6ef1-2872-0b0c-2ad79359f0e0.png)


プロジェクトのプロジェクト設定からGitLabプラグインを選択して
GitLabのプロジェクトパスを指定します。
![sonar-gitlab2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/39bccb5b-42ff-3734-65e6-9ba3c1eb1da5.png)



JenkinsにSonarQube Pluginをインストールします。
![sonar0.png](https://qiita-image-store.s3.amazonaws.com/0/55077/b4c2623c-2a56-c761-e444-d75ff299c4d7.png)

システム管理よりSonarQube Serverの設定を行います。
Server authentication tokenに先ほど払い出したユーザトークンを指定してください。
![sonar1.png](https://qiita-image-store.s3.amazonaws.com/0/55077/8dfa0cd4-1ebb-096e-b28c-4c9a412d86dd.png)

Global Tool ConfigurationよりSonarScannerの設定を行います。
自動インストールにするとジョブ実行時にSonarQube Serverからプラグインをインストールします。
![sonar2.png](https://qiita-image-store.s3.amazonaws.com/0/55077/b6a3395e-3a41-f6df-35d3-550163e5ec44.png)


JenkinsプロジェクトのExecute Sonar Scanner欄に
sonar-project.propertiesファイルと同様の設定を追加します。

```
# Project identification
sonar.projectName=プロジェクト名
sonar.projectKey=JavaScript:プロジェクトキー
sonar.projectVersion=1.0

# Info required for Sonar
sonar.sources=${WORKSPACE}/libs/common

# Comma-separated paths to directories with sources (required)
sonar.language=js

#----- Default source code encoding
sonar.sourceEncoding=UTF-8

sonar.analysis.mode=preview
sonar.issuesReport.console.enable=true
sonar.gitlab.commit_sha=${GIT_COMMIT}
sonar.gitlab.ref=master
```

![sonar3.png](https://qiita-image-store.s3.amazonaws.com/0/55077/6ff82d49-86ac-72c6-1243-d489e2bc31a4.png)


次の行はSonarQubeとGitLab連携に必要になります。

```
sonar.analysis.mode=preview
sonar.issuesReport.console.enable=true
sonar.gitlab.commit_sha=${GIT_COMMIT}
sonar.gitlab.ref=master
```

上記設定でjenkinsプロジェクトを保存後、
GitLabでPushするとJenkinsにWebhook連携され、GitLabにレビューが書き込まれます。

previewモードだとGitLabにレビューされる代わりにSonarQube側には送信されないようです。
previewモードをコメントアウトすることでSonarQube Serverにレポートが送信されます。

```
#sonar.analysis.mode=preview
```

Execute Sonar Scannerジョブを２つ作れば、２回実行することになりますが
GitLabのレビューとSonarQube Serverへのレポート送信が同時にできます。