以前の記事で SonarQube を使って .NET アプリケーションの静的解析を行いました。
今回はこれに GitLab CI を使って継続的インテグレーションを行います。
具体的には Push をトリガーとして自動的にコードを解析を行い、またその解析結果をマージリクエストの画面に表示します。
尚、Jenkins 等の他の CI ツールは必要ありません。
環境
- GitLab 10.2.0
- gitlab-runner 10.2.0
- SonarQube 6.7
- SonarQube Scanner for MSBuild 4.0
- .NET Core 2.0
準備
GitLab と SonarQube の環境構築は済んでいる前提です。
Docker を使った環境構築については以下を参考にしてください。
また、GitLab CI を使うためにはタスクランナーとして gitlab-runner が必要です。
以下の記事に書いたように、C# プログラムのコード解析には OpenCover と SonarQube Scanner を使っていますが、これらは Windows 上でしか動作しません。
従って、gitlab-runner は Windows 上にインストールしたものを使う必要があります。
gitlab-runner を Windows にインストールする手順については以下の記事を参照してください。
GitLab に gitlab-runner を登録するところまでも済んでいる前提とします。
GitLab の設定
ユーザーの追加
SonarQube から GitLab に通知するためのユーザーを GitLab に作成します。
後で SonarQube の設定を行うときに作成したユーザーのトークンが必要になります。
トークンは作成したユーザーでログインし、Account のメニューの Private Token で確認できます。
もちろん、別途トークンを作成しても OK です。
Pipeline 失敗時のマージ拒否
Pipeline で失敗している場合にマージリクエストをマージできないようにしたい場合は、該当のプロジェクトで以下を設定します。
[Edit Project] > Only allow merge requests to be merged if the build succeeds
を ON にし、Save changes
をクリック
SonarQube の設定
管理者アカウントでログインして以下のことを行います。
GitLab Plugin のインストール
[Administration] > [Marketplace] > GitLab
で検索し、GitLab
をインストールします。
インストールしたら SonarQube を再起動します。
GitLab Plugin の設定
[Administration] > [Configuration] > サイドメニューより GitLab
を選択します。
GitLab url
と GitLab User Token
を設定します。GitLab User Token
には、あらかじめ GitLab に作成しておいたアカウントのトークンを設定します。
詳細は以下を参照してください。
プロジェクトの設定
該当のプロジェクトの画面で以下を設定します。
[Administration] > [General Settings] > サイドメニューより GitLab
を選択します。
GitLab Project id
を設定します。
.gitlab-ci.yml の作成
GitLab と SonarQube の設定が完了したら、.gitlab-ci.yml を作成します。
SonarQube のコード解析の部分だけのサンプルですが、例えば以下のような感じです。
variables:
SONARSCANNER: "C:\\SonarQube\\sonar-scanner-msbuild-4.0.0.821\\MSBuild.SonarQube.Runner.exe"
SONARHOST: "http://localhost:9000"
SONARKEY: "projectkey"
REPORT: "coverage.xml"
stages:
- test
Job1:
stage: test
script:
# GitLab のコンソールログでの文字化け対策
- chcp 65001
# SonarQube による解析(環境変数を先頭に置くと yaml パーサーでエラーになるので call をつけている)
- call %SONARSCANNER% begin /d:sonar.host.url=%SONARHOST% /k:%SONARKEY% /v:"1.0" /d:sonar.analysis.mode=preview /d:sonar.cs.opencover.reportsPaths=%REPORT% /d:sonar.gitlab.commit_sha=%CI_COMMIT_SHA% /d:sonar.gitlab.project_id=%CI_PROJECT_ID% /d:sonar.gitlab.ref_name=%CI_COMMIT_REF_NAME%
- dotnet build
- call .\OpenCover.bat %REPORT%
- call %SONARSCANNER% end
tags:
- windows
OpenCover の解析部分はバッチファイルにしていますが、中身については以下の記事を参考にしてください。
SonarQube の解析も、後述するように SonarQube Server と GitLab の通知のために2回行うことを前提にするならば、バッチファイルにして処理を共通化したほうが良いかなと思います。
まぁそれはともかく、とりあえずこれで全て完了です。 これで以下のように動作します。
- GitLab に Push したタイミングで GitLab CI の機能により、最新コミットのコード解析が行われる
- SonarQube での解析結果が GitLab に通知される
- 解析を行ったコミットが含まれるマージリクエストに指摘事項が表示される
マージリクエストの画面にはこんな感じで表示されます。
SonarQube Scanner for MSBuild のパラメータの一覧は以下を参照してください。
.gitlab-ci.yml で使用できる環境変数の一覧は以下を参照してください。
今回使用しているパラメータについては以下に簡単に説明します。
sonar.analysis.mode
デフォルトは publish
で、この場合、解析結果が SonarQube Server にアップロードされます。
GitLab に通知したい場合は、preview
を指定する必要があります。
SonarQube Server と GitLab の両方に通知したい場合は、面倒ですが sonar.analysis.mode
の値を変えて2回解析を実行する必要があります。
尚、publish
の場合に後述の GitLab 関連のオプションを設定していると解析に失敗するので注意です。
sonar.host.url
SonarQube Server の URL を指定します。
sonar.cs.opencover.reportsPaths
OpenCover の出力ファイルを指定します。
sonar.gitlab.commit_sha
解析対象の Git のコミットのハッシュ値を指定します。
sonar.gitlab.project_id
GitLab のプロジェクト ID を指定します。
SonarQube のプロジェクト設定で設定済みの場合は不要っぽいです。
sonar.gitlab.ref_name
ブランチ名を指定します。
sonar.gitlab.user_token
GitLab に通知する際のユーザーのトークンを指定します。
SonarQube で設定済みの場合は不要っぽいです。
はまったところ
何度見直しても正しく設定しているはずなのに、解析結果が GitLab に通知されずずっと悩んでいました。
解析ログをよく見ると、以下の警告が表示されていました。
The project does not have a valid "ProjectGuid."
ProjectGuid
が何なのかわからないまま調べてみると、どうやら .NET Core の ProjectGuid 変更になったらしく、これを手動で追加すると解析結果が GitLab に通知されるようになりました。
詳細は以下の記事を参照してください。
参考 URL
- http://codeout.hatenablog.com/entry/2015/08/21/012706
- https://qiita.com/bremen/items/f47f383b9931a840a25c
- https://gitlab.talanlabs.com/gabriel-allaigre/sonar-gitlab-plugin
- https://qiita.com/ynott/items/1ff698868ef85e50f5a1
- https://eliot-jones.com/2017/12/configure-gitlab-sonarqube-teamcity
- https://docs.gitlab.com/ce/ci/variables/README.html#using-the-ci-variables-in-your-job-scripts
- http://blog.applibot.co.jp/blog/2017/09/14/static-code-analysis-with-sonarqube/
- https://github.com/gabrie-allaigre/sonar-gitlab-plugin/issues/75
- https://github.com/mibexsoftware/sonar-bitbucket-plugin/issues/25
- https://qiita.com/teradonburi/items/776e4735395af872320a
- https://qiita.com/ijoji/items/f7dce812c84a5cfa91cf