diff --git a/.gitea/workflows/sonarqube.yml b/.gitea/workflows/sonarqube.yml index 4fa4f85..1f2041b 100644 --- a/.gitea/workflows/sonarqube.yml +++ b/.gitea/workflows/sonarqube.yml @@ -41,6 +41,31 @@ jobs: # compute "new code". A shallow clone degrades both. fetch-depth: 0 + # SonarQube runs static analysis only — it never executes the test suite, + # so we must produce a coverage report ourselves and hand it to the + # scanner (see sonar.javascript.lcov.reportPaths in sonar-project.properties). + # Node's built-in `lcov` coverage reporter needs Node >= 22. + - uses: actions/setup-node@v4 + with: + node-version: 22 + cache: npm + cache-dependency-path: server/package-lock.json + + - name: Install server deps + run: npm ci --prefix server + + - name: Generate server test coverage (LCOV) + # Run from the repo root (not `--prefix server`) so the LCOV `SF:` paths + # are emitted as `server/src/...`, matching sonar.sources and letting the + # scanner resolve them against the project base dir. The server tests stub + # their models and point the DB pool at a dead port, so no MariaDB is needed. + run: | + mkdir -p server/coverage + node --test --experimental-test-coverage \ + --test-reporter=spec --test-reporter-destination=stdout \ + --test-reporter=lcov --test-reporter-destination=server/coverage/lcov.info \ + server/test/*.test.js + - name: Run SonarQube scan uses: sonarsource/sonarqube-scan-action@v4 env: diff --git a/.gitignore b/.gitignore index 251ec80..987f65b 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,10 @@ server/node_modules/ # build output client/dist/ +# test coverage (generated in CI for SonarQube) +server/coverage/ +coverage/ + # env / secrets .env *.env diff --git a/sonar-project.properties b/sonar-project.properties index ed4b092..bd7b2fc 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -14,7 +14,14 @@ sonar.sources=server/src,client/src,bot/src sonar.tests=server/test sonar.test.inclusions=server/test/**/*.test.js +# Coverage. The sonarqube.yml workflow runs the server suite with Node's built-in +# test-coverage and writes an LCOV report here BEFORE the scan runs; without it +# the dashboard shows 0% (the scanner never executes tests itself). The SF: paths +# in the report are repo-root-relative (server/src/...) so the scanner resolves +# them against the project base dir. +sonar.javascript.lcov.reportPaths=server/coverage/lcov.info + # Never analyse dependencies, build output, generated specs, or runtime dirs. -sonar.exclusions=**/node_modules/**,client/dist/**,client/public/**,server/swagger/**,server/logs/**,server/uploads/**,**/*.min.js +sonar.exclusions=**/node_modules/**,client/dist/**,client/public/**,server/swagger/**,server/logs/**,server/uploads/**,server/coverage/**,**/*.min.js sonar.sourceEncoding=UTF-8