Skip to content
Latchkey

How to Import Coverage Into SonarQube in CI

SonarQube does not run tests; it imports a report you already generated via a coverage report path property.

Generate coverage first, then set the matching sonar.<lang>.coverage.*ReportPaths property so the scanner reads it. The property differs per language (lcov for JS, coverage.xml for Python, jacoco.xml for Java).

sonar-project.properties

sonar-project.properties
sonar.projectKey=my-project
sonar.sources=src
sonar.tests=tests

# JavaScript / TypeScript
sonar.javascript.lcov.reportPaths=coverage/lcov.info
# Python
sonar.python.coverage.reportPaths=coverage.xml
# Java (JaCoCo)
sonar.coverage.jacoco.xmlReportPaths=target/site/jacoco/jacoco.xml

Workflow

.github/workflows/ci.yml
steps:
  - run: npx jest --coverage
  - uses: SonarSource/sonarqube-scan-action@v4
    env:
      SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
      SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}

Gotchas

  • The coverage step must run before the scanner, or the report path is empty and coverage shows 0%.
  • Report paths are relative to the project base directory; a wrong base dir is the usual cause of a missing import.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →