SonarQubeとprojectの連携方法(monorepo+React + TypeScript)

SonarQubeとprojectの連携方法(monorepo+React + TypeScript)

single projectと基本的には設定方法同じです。

親プロジェクト配下に、project1,project2,commonのサブプロジェクトが存在するとして進めます。

[React.js]monorepo環境を構築する+typescript

SonarScannerのための準備

パッケージのインストール

  • sonarqube-scanner・・・SonarQubeに静的解析結果を送信する
  • jest-sonar-reporter・・・test結果をSonarQube用に出力する

sonarqube-scannerはプロジェクト共通でインストールします。(ルートプロジェクトから実行できればいい)

yarn add -W  --dev sonarqube-scanner

jest-sonar-reporterは各プロジェクトでインストールします。

yarn workspace project1 add --dev jest-sonar-reporter
yarn workspace project2 add --dev jest-sonar-reporter
yarn workspace common add --dev jest-sonar-reporter

test reportの出力

package.jsonを修正していきます。

  ...
  "scripts": {
    "test": "jest --setupFiles ./src/test/setup-tests.ts --coverage --testResultsProcessor jest-sonar-reporter",
  },
  "testResultsProcessor": "jest-sonar-reporter",
  "jestSonar": {
    "reportPath": "report",
    "reportFile": "test-report.xml",
    "indent": 4
  }
  ...

scriptsのtest
カバレッジの出力とjest-sonar-reporterでのレポート出力を指定

testResultsProcessor
使用するレポート出力プロセッサを指定

jestSonar
レポートの出力先を指定している。
reportディレクトリにtest-report.xmlというファイル名で出力する

確認

サブプロジェクトのscriptを実行して、ファイルが作られることを確認する

yarn workspace project1 test
yarn workspace project2 test
yarn workspace common test

reportの下にtest-report.xmlが作成されればOKです。

SonarScannerの設定

ルートにsonar-scanner.jsを作成する

const scanner = require('sonarqube-scanner');
scanner(
    {
        serverUrl: "http://localhost:9000",
        options: {
            "sonar.login": "admin",
            "sonar.password": "password",
            "sonar.projectKey": 'com.example.yourproject:react-monorepo-template',
            "sonar.projectName": 'react-monorepo-template',
            "sonar.language": "js",
            "sonar.sourceEncoding": "UTF-8",
            "sonar.exclusions": "./node_modules",
            "sonar.exclusions": "**/build/**",
            "sonar.exclusions": "**/test/**",

            "sonar.modules": "packages/project1,packages/project2,packages/common",

            "packages/project1.sonar.projectName": "project1",
            "packages/project1.sonar.sources": "./src",
            "packages/project1.sonar.tests": "./src",
            "packages/project1.sonar.eslint.reportPaths": "report/eslint-report.json",
            "packages/project1.sonar.testExecutionReportPaths": "report/test-report.xml",
            "packages/project1.sonar.typescript.lcov.reportPaths": "coverage/lcov.info",

            "packages/project2.sonar.projectName": "project2",
            "packages/project2.sonar.sources": "./src",
            "packages/project2.sonar.tests": "./src",
            "packages/project2.sonar.eslint.reportPaths": "report/eslint-report.json",
            "packages/project2.sonar.testExecutionReportPaths": "report/test-report.xml",
            "packages/project2.sonar.typescript.lcov.reportPaths": "coverage/lcov.info",

            "packages/common.sonar.projectName": "common",
            "packages/common.sonar.sources": "./src",
            "packages/common.sonar.tests": "./src",
            "packages/common.sonar.eslint.reportPaths": "report/eslint-report.json",
            "packages/common.sonar.testExecutionReportPaths": "report/test-report.xml",
            "packages/common.sonar.typescript.lcov.reportPaths": "coverage/lcov.info",

            "sonar.sources": "./src",
            "sonar.tests": "./src",
            "sonar.test.inclusions": "**/*.test.tsx,**/*.test.ts",
        },
    },
    () => process.exit()
);

monorepo構成の場合、
sonar.modulesで指定したサブプロジェクトに対して、個別にsonar設定ができます。
その場合は、

[moduleで指定したサブプロジェクト名].sonar.[プロパティ]

という形で指定します。

次にpackage.jsonを修正します。

"scripts": {
  "sonar": "node sonarqube-scanner.js"
},

実行

yarn sonar

トラブルシューティング

can’t be indexed twice

sonar-scanner.jsの一番下段の設定の

"sonar.sources": "./src",
"sonar.tests": "./src",

これをサブプロジェクトで設定しているからという理由で抜いていると、script実行時にエラーが発生します。

INFO: ------------------------------------------------------------------------
INFO: EXECUTION FAILURE
INFO: ------------------------------------------------------------------------
INFO: Total time: 1:19.402s
INFO: Final Memory: 6M/24M
INFO: ------------------------------------------------------------------------
ERROR: Error during SonarScanner execution
ERROR: File packages/project1/src/index.tsx can't be indexed twice. Please check that inclusion/exclusion patterns produce disjoint sets for main and test files
ERROR: 
error Command failed with exit code 2.

関連

DockerでSonarQube環境構築を手早く構築する

SonarQubeとprojectの連携方法(Spring Boot,gradle)

SonarQubeで管理しているprojectのQualityGateの状態をAPIで取得する方法

[React.js]monorepo環境を構築する+typescript

参考

Analysis Parameters – SonarQube

React.jsカテゴリの最新記事