プロジェクト

全般

プロフィール

(3)SonarQubeで静的解析&コードカバレッジ集計

最終更新日:2022/05/15

第三部、Jenkinsおじさんは疲れたので特に何もしない。

はじめに

このページは「Jenkinsで.NET用環境構築を作る」の第三部です。

(1).NET用Jenkinsを立ち上げる
(2)Giteaからソースを取得してビルド&テスト
(3)SonarQubeで静的解析&コードカバレッジ集計←イマココ!

第三部ではSonarQubeを使ってソースの静的解析を行い、ついでに単体テストのコードカバレッジも集計していきます。
SonarQube自体はC#以外にも色んな言語に対応しているので、覚えておくとソースのクオリティが上がります(多分)

SonarQubeとは

SonarQubeとはコードを静的解析し、品質やセキュリティを保つ素晴らしいツール。
オープンソースであり無料で使え、JenkinsやGitHubなど、他のプラットフォームとの連携も可能。
有償プランもあり、対応言語とかレポートの出力とか追加される。

Code Quality and Code Security | SonarQube
https://www.sonarqube.org/

SonarQube Documentation | SonarQube Docs
https://docs.sonarqube.org/latest/

SonarQube構築

(1):下準備

Dockerで立ち上げる前に、プロセスが使用可能なメモリマップ領域を確認する、下記のコマンドで確認可能。
低すぎるとSonarQubeが動かない可能性があるため、最大値を上げる。

sysctl vm.max_map_count

設定方法は2種類、手っ取り早いのは以下、ただし再起動すると元に戻る。

sysctl -w vm.max_map_count=524288

もう1つは直接「/etc/sysctl.conf」を編集する、こちらは再起動しても設定した値になる。
下記の設定を書き込むだけ、編集方法は任せる!

vm.max_map_count=524288

これらはLinuxの場合のみ、Windowsは・・・知らんw

(2):DockerCompose編集

前回のdocker-compose.ymlにSonarQubeと、SonarQube用のPostgresを追加する。
特に追加の環境設定はなし。

version: '3.8'
services:

  jenkins:
    image: localhost/bitnami_jenkins_net:2.0.0
    container_name: jenkins_cont
    ports:
      - '8080:8080'
      - '50000:50000'
    environment:
      - JENKINS_USERNAME=user
      - JENKINS_PASSWORD=bitnami
    volumes:
      - 'jenkins_data:/bitnami/jenkins'

  gitea:
    image: gitea/gitea:latest
    container_name: gitea_cont
    ports:
      - "3000:3000"
      - "3022:22"
    environment:
      - GITEA__webhook__ALLOWED_HOST_LIST=*
    volumes:
      - gitea_data:/data

  # ★SonarQube用Postgresを追加!
  postgres:
    container_name: postgres_cont
    image: postgres:13.4-alpine
    environment:
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
    volumes:
      - postgres_data:/var/lib/postgresql/data

  # ★SonarQubeを追加!
  sonarqube:
    container_name: sonarqube_cont
    image: sonarqube:community
    depends_on:
      - postgres
    environment:
      SONAR_JDBC_URL: jdbc:postgresql://postgres:5432/sonar
      SONAR_JDBC_USERNAME: sonar
      SONAR_JDBC_PASSWORD: sonar
    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_extensions:/opt/sonarqube/extensions
      - sonarqube_logs:/opt/sonarqube/logs
    ports:
      - "9000:9000"

volumes:
  jenkins_data:
    driver: local
  gitea_data:
    driver: local
  postgres_data:
    driver: local
  sonarqube_data:
    driver: local
  sonarqube_extensions:
    driver: local
  sonarqube_logs:
    driver: local

(3):立ち上げ

「http://(IPアドレス):9000」にアクセスしてログインページが表示されたら立ち上げは成功。
立ち上げに時間がかかるので、紅茶でも飲んで少し待つこと。
初期IDとパスワードは「admin」で、初回ログイン後にパスワードの再設定をする。

sonar_01.png

ログイン後のページ、ここで後ほどプロジェクトを作成する。

sonar_02.png

(4):プロジェクト作成

SonarQubeはプロジェクト単位で静的解析とかを行う。
今回は前回の.NET Coreのソースを利用するので、C#のプロジェクトを作成していく。
手動で行うので「Manually」を選択。

sonar_03.png

プロジェクト作成ページでは、プロジェクト名とプロジェクトキーを入力する。
ここでは「TestCS」とする。
入力後「SetUp」を選択して次へ。

sonar_04.png

ここでは解析するリポジトリを選択する。
「Jenkins」があるがこれは罠で、下の「Locally」を選択する。

sonar_05.png

解析プロジェクトページではまずはアクセス用のトークンを生成する。
適当に入力してトークンを生成、これは後で使うのでメモっておく。
生成したら「Continue」で次へ。

sonar_06.png sonar_07.png

次へと言ったが、ここは実はただの解説ページなので飛ばしていい。
一応説明すると今回は.NET Coreが対象なので、ビルド対象を「.NET」、ビルドツールを「.NET Core」と選択すると、その使い方が表示される。

sonar_08.png

これでSonarQubeでの作業は終わり。

Jenkins連携

(1):SonarQubeプラグイン追加

Jenkinsのプラグイン管理のページで、右上の検索窓に「sonarqube」と入力。
するとSonarqubeプラグインが表示されるので、チェックしてインストールする。

sonar_09.png

インストール後、システム設定のページにSonarQubeのプラグインの項目が追加されているので、そこに立てたSonarQubeのアドレスを入力する。
「Name」は何入力してもいいが、後で使用するのでメモしておく。
その後、先程生成したアクセストークンの認証情報を追加するので、下の追加を選択する。

sonar_10.png

認証情報追加ダイアログが表示されるので、種類の「Sercret Text」を選択し、「Sercret」にアクセストークンをコピペする。
「ID」はJenkins内での識別用ID、「説明」はその認証情報の説明なので分かりやすいものを入力しておく。
終わったら「追加」を選択し、追加した認証情報を選択して保存する。

sonar_11.png sonar_12.png

(2):Jenkinsファイル編集

SonarQubeプラグインの設定が終わったら、次はそれを使用するためにJenkinsファイルを編集する。
SonarQube用の環境変数を呼び出す「withSonarQubeEnv」を追加し、その中で第一部で.NET用Jenkins構築時に追加したツールを呼び出す。

「withSonarQubeEnv」のパラメータは、SonarQubeサーバーを追加した時に「Name」に入力した名称を設定する。

ツール「SonarScanner」の使い方は簡単で、「begin」~「end」の間にビルドとテストをするだけ。
「begin」のパラメータ「/k」には、SonarQubeで作成したプロジェクト名を設定する。

ツール「ReportGenerator」は、レポートを生成するツール。
ここでは単体テスト時にコードカバレッジレポートを出力し、このツールでSonarQube用に変換している。

stage('SonerQube') {
    steps {
        withSonarQubeEnv('SonarQube') {
            echo 'SonerQube'
            sh 'dotnet sonarscanner begin /k:"TestCS" /d:sonar.coverageReportPaths="./SonarQubeCoverage/SonarQube.xml"'
            sh 'dotnet build ./RunRunGridLinerCore/'
            sh 'dotnet test ./RunRunGridLinerCore_Test/ --collect:"XPlat Code Coverage"'
            sh 'reportgenerator -reports:"RunRunGridLinerCore_Test/TestResults/*/coverage.cobertura.xml" -targetdir:"./SonarQubeCoverage" -reporttypes:"SonarQube"'
            sh 'dotnet sonarscanner end'
        }
    }
}

最終的にはこんな感じ。
Jenkinsファイルの編集が終わったらリポジトリにアップする。

pipeline {
    agent any

    stages {
        stage('Hello') {
            steps {
                echo 'Hello World'
                sh 'dotnet --info'
            }
        }
        stage('Clean') {
            steps {
                echo 'Clean'
                sh 'dotnet clean ./RunRunGridLinerCore/'
                sh 'dotnet clean ./RunRunGridLinerCore_Test/'
            }
        }
        stage('Build') {
            steps {
                echo 'Build'
                sh 'dotnet build ./RunRunGridLinerCore/'
            }
        }
        stage('Test') {
            steps {
                echo 'Test'
                sh 'dotnet test ./RunRunGridLinerCore_Test/'
            }
        }
        stage('SonerQube') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    echo 'SonerQube'
                    sh 'dotnet sonarscanner begin /k:"TestCS" /d:sonar.coverageReportPaths="./SonarQubeCoverage/SonarQube.xml"'
                    sh 'dotnet build ./RunRunGridLinerCore/'
                    sh 'dotnet test ./RunRunGridLinerCore_Test/ --collect:"XPlat Code Coverage"'
                    sh 'reportgenerator -reports:"RunRunGridLinerCore_Test/TestResults/*/coverage.cobertura.xml" -targetdir:"./SonarQubeCoverage" -reporttypes:"SonarQube"'
                    sh 'dotnet sonarscanner end'
                }
            }
        }
    }
}

「SonarScanner」の詳しい使い方は↓の公式へ!

SonarScanner for .NET | SonarQube Docs
https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/

「ReportGenerator」の詳しい使い方は↓の公式へ!

単体テストにコードカバレッジを使用する - .NET | Microsoft Docs
https://docs.microsoft.com/ja-jp/dotnet/core/testing/unit-testing-code-coverage?tabs=windows

(3):ビルド実行

Jenkinsに戻り、ジョブの左のメニューから「ビルド実行」を選択しビルド実行。
前回から続きであれば自動ビルドが走るはず。
少し時間がかかるので、紅茶飲みながらクッキーでも食べて待つこと。

成功すると、SonarQube用に追加したステージ「SonarQube」が追加される。
また、左のメニューにSonarQubeの該当のプロジェクトへのリンクが追加されている。

sonar_13.png

(4):静的解析結果

SonarQubeの作成したプロジェクトを見てみると、先程の静的解析の結果が反映されている。
「Pass」と出てるので、多分良い結果なはずw

sonar_14.png

「Issues」のページに詳細が出ており、ここでどのコードを直せばいいか確認できる。

sonar_15.png

「Measures」のページではコードカバレッジの結果が出ており、単体テストでどれぐらいコードをカバーしたか確認できる。

sonar_16.png

他にはセキュリティに関する関するページなどもあるので、ヤバそうなコードがあったらここに表示されると思う。

おわりに

これでSonarQubeで静的解析とコードカバレッジ集計ができました。
昨今色々なツールがありますが、ローカルな環境で静的解析できるのは便利だと思いました。

以上で「Jenkinsで.NET用環境構築を作る」は終わりです。
Jenkinsは遊び甲斐があるので、これからも解説は増やしていきたいですね!

(1).NET用Jenkinsを立ち上げる
(2)Giteaからソースを取得してビルド&テスト
(3)SonarQubeで静的解析&コードカバレッジ集計←イマココ!


メインページに戻る

他の形式にエクスポート: PDF HTML TXT