# (3)SonarQubeで静的解析&コードカバレッジ集計 _**最終更新日:2022/05/15**_ 第三部、Jenkinsおじさんは疲れたので特に何もしない。 {{toc}} ## はじめに このページは「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が動かない可能性があるため、最大値を上げる。 ``` shell sysctl vm.max_map_count ``` 設定方法は2種類、手っ取り早いのは以下、ただし再起動すると元に戻る。 ``` shell sysctl -w vm.max_map_count=524288 ``` もう1つは直接「/etc/sysctl.conf」を編集する、こちらは再起動しても設定した値になる。 下記の設定を書き込むだけ、編集方法は任せる! ``` shell vm.max_map_count=524288 ``` これらはLinuxの場合のみ、Windowsは・・・知らんw ### (2):DockerCompose編集 前回のdocker-compose.ymlにSonarQubeと、SonarQube用のPostgresを追加する。 特に追加の環境設定はなし。 ``` yaml 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」で、初回ログイン後にパスワードの再設定をする。 {{thumbnail(sonar_01.png, size=400, title=ログイン1)}} ログイン後のページ、ここで後ほどプロジェクトを作成する。 {{thumbnail(sonar_02.png, size=400, title=ログイン2)}} ### (4):プロジェクト作成 SonarQubeはプロジェクト単位で静的解析とかを行う。 今回は前回の.NET Coreのソースを利用するので、C#のプロジェクトを作成していく。 手動で行うので「Manually」を選択。 {{thumbnail(sonar_03.png, size=400, title=プロジェクト作成1)}} プロジェクト作成ページでは、プロジェクト名とプロジェクトキーを入力する。 ここでは「TestCS」とする。 入力後「SetUp」を選択して次へ。 {{thumbnail(sonar_04.png, size=400, title=プロジェクト作成2)}} ここでは解析するリポジトリを選択する。 「Jenkins」があるがこれは罠で、下の「Locally」を選択する。 {{thumbnail(sonar_05.png, size=400, title=プロジェクト作成3)}} 解析プロジェクトページではまずはアクセス用のトークンを生成する。 適当に入力してトークンを生成、これは後で使うのでメモっておく。 生成したら「Continue」で次へ。 {{thumbnail(sonar_06.png, size=400, title=プロジェクト作成4)}} {{thumbnail(sonar_07.png, size=400, title=プロジェクト作成5)}} 次へと言ったが、ここは実はただの解説ページなので飛ばしていい。 一応説明すると今回は.NET Coreが対象なので、ビルド対象を「.NET」、ビルドツールを「.NET Core」と選択すると、その使い方が表示される。 {{thumbnail(sonar_08.png, size=400, title=プロジェクト作成6)}} これでSonarQubeでの作業は終わり。 ## Jenkins連携 ### (1):SonarQubeプラグイン追加 Jenkinsのプラグイン管理のページで、右上の検索窓に「sonarqube」と入力。 するとSonarqubeプラグインが表示されるので、チェックしてインストールする。 {{thumbnail(sonar_09.png, size=400, title=プラグイン追加1)}} インストール後、システム設定のページにSonarQubeのプラグインの項目が追加されているので、そこに立てたSonarQubeのアドレスを入力する。 「Name」は何入力してもいいが、後で使用するのでメモしておく。 その後、先程生成したアクセストークンの認証情報を追加するので、下の追加を選択する。 {{thumbnail(sonar_10.png, size=400, title=プラグイン追加2)}} 認証情報追加ダイアログが表示されるので、種類の「Sercret Text」を選択し、「Sercret」にアクセストークンをコピペする。 「ID」はJenkins内での識別用ID、「説明」はその認証情報の説明なので分かりやすいものを入力しておく。 終わったら「追加」を選択し、追加した認証情報を選択して保存する。 {{thumbnail(sonar_11.png, size=400, title=プラグイン追加3)}} {{thumbnail(sonar_12.png, size=400, title=プラグイン追加4)}} ### (2):Jenkinsファイル編集 SonarQubeプラグインの設定が終わったら、次はそれを使用するためにJenkinsファイルを編集する。 SonarQube用の環境変数を呼び出す「withSonarQubeEnv」を追加し、その中で第一部で.NET用Jenkins構築時に追加したツールを呼び出す。 「withSonarQubeEnv」のパラメータは、SonarQubeサーバーを追加した時に「Name」に入力した名称を設定する。 ツール「SonarScanner」の使い方は簡単で、「begin」~「end」の間にビルドとテストをするだけ。 「begin」のパラメータ「/k」には、SonarQubeで作成したプロジェクト名を設定する。 ツール「ReportGenerator」は、レポートを生成するツール。 ここでは単体テスト時にコードカバレッジレポートを出力し、このツールでSonarQube用に変換している。 ``` shell 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ファイルの編集が終わったらリポジトリにアップする。 ``` shell 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の該当のプロジェクトへのリンクが追加されている。 {{thumbnail(sonar_13.png, size=400, title=ビルド実行)}} ### (4):静的解析結果 SonarQubeの作成したプロジェクトを見てみると、先程の静的解析の結果が反映されている。 「Pass」と出てるので、多分良い結果なはずw {{thumbnail(sonar_14.png, size=400, title=静的解析結果1)}} 「Issues」のページに詳細が出ており、ここでどのコードを直せばいいか確認できる。 {{thumbnail(sonar_15.png, size=400, title=静的解析結果2)}} 「Measures」のページではコードカバレッジの結果が出ており、単体テストでどれぐらいコードをカバーしたか確認できる。 {{thumbnail(sonar_16.png, size=400, title=コードカバレッジ集計)}} 他にはセキュリティに関する関するページなどもあるので、ヤバそうなコードがあったらここに表示されると思う。 ## おわりに これでSonarQubeで静的解析とコードカバレッジ集計ができました。 昨今色々なツールがありますが、ローカルな環境で静的解析できるのは便利だと思いました。 以上で「Jenkinsで.NET用環境構築を作る」は終わりです。 Jenkinsは遊び甲斐があるので、これからも解説は増やしていきたいですね! [[(1).NET用Jenkinsを立ち上げる]] [[(2)Giteaからソースを取得してビルド&テスト]] [[(3)SonarQubeで静的解析&コードカバレッジ集計]]←イマココ! --- [[wiki|メインページに戻る]]