Not able to get coverage report (json or cobertura) on SonarQube Dashboard

The following are the details:

  • SonarQube version: Not sure about this
  • Scanner version: sonar scan of version 6.2.0
  • Plugin(s) version: cobertura.xml version - 1.9
  • Any relevant extension version: [specify version]

SonarQube Deployment:

  • Deployment method: Docker (not completely sure. we are using it in Github Actions)

Objective:

  • I am attempting to generate a coverage report in cobertura.xml format and have SonarQube process this report to display the results on the dashboard.

  • Attempts So Far:

    • Converted report generation from JSON to cobertura.xml format.
    • Uploaded and downloaded the coverage report as an artifact in GitHub Actions.
    • Passed the coverage report as reportsPath in the Sonar Scan.
    • Confirmed that the Build and Analyze step completes successfully.

Despite these steps, the SonarQube Dashboard does not show any results. I have ensured that the file path to the cobertura.xml report is correct and that the report is formatted correctly as confirmed by successful import logs in the Sonar Scan job.

Detailed Explanation

I am working on a workflow in GitHub Actions that generates a test coverage report using coverlet. Initially, the report was generated in JSON format, but since SonarQube does not support JSON for reports, I have updated the generation to output in cobertura.xml format. And also if I want to use ReportGenerator to convert report type to any other format so I will use cobertura.xml

The generated unit test coverage report is uploaded as an artifact and subsequently downloaded in the Sonar Scan job. The purpose is to perform a sonar scan and integrate the results into the Sonar Dashboard. The coverage report is stored at the location /github/workspace/cobertura.xml and it is successfully imported into the Sonar Scan job.

The coverage report is getting successfully imported in Sonar Scan Job

Then I am passing this coverage report as a reportsPath in the Sonar Scan, Build and Analyze step
image

The Build and Analyze runs successfully

But I do not get any result on the SonarQube Dashboard

Hey there

What do the logs say about the import?

Hello Colin, thanks for your reply

Ya this is a snapshot of log

Though I am downloading the report from artifacts successfully

And using reportsPaths as

-d:"sonar.cs.vscoveragexml.reportsPaths=**/*.coveragexml"

or
“/d:sonar.cs.cobertura.reportsPaths=${{github.workspace}}/cobertura.xml”

It mentions that it is not getting accessible to the reportPath because ‘cobertura’ skipped because there is no related file in current project.

I have also worked on passing the exact path of cobertura.xml

But still I am not getting any coverage on sonarscan dashboard

sonar.cs.cobertura.reportsPaths isn’t a recognized parameter .

I suggest stepping back and looking through the documentation on .NET Test Coverage, which details supported formats and gives examples for generating files in those formats.

1 Like

Hi Colin, Thanks for your reply.

I have tried various approaches but still facing the same issue

  1. Generate coverage report in opencover format and then pass it

I worked on generating the coverage report in opencover format and then pass it instead of cobertura.xml

And passing it to the

/d:sonar.cs.opencover.reportsPaths=“/__w/ix-camera-system-service/ix-camera-system-service/.sonar/coverage-reports/coverage.xml”

And I believe that because of this error “Did not find deterministic source path in provided path”

I am not getting any output on the SonarQube dashboard

Are you generating the coverage report brand new in every build? Can you share your GitHub Actions YML file?

Hey Colin, yes I am generating the coverage report in every build

This is a barebone workflow file where I have included all of the required content for your reference

name: UnitTest Coverage
on:
  workflow_call:
    secrets:
      AWS_ReadSecrets_Role:
        description: AWS secert to get secert from AWS mangaer
        required: true
      ACR_USERNAME:
        description: Username for accessing Docker
        required: true
      ACR_PASSWORD:
        description: Password for accessing Docker
        required: true
      SONAR_TOKEN:
        description: Repo-specific SonarQube token
        required: true
      SONAR_HOST_URL:
        description: SonarQube Host URL
        required: true

permissions:
  id-token: write
  contents: read

jobs:
    unittestcoverage:
      runs-on: [self-hosted, x64, linux, ubuntu-latest]
      timeout-minutes: 15
      outputs:
        metricval: ${{steps.master-unittestcoverage.outputs.coverage}}
        slncheck: ${{ steps.slncheck.outputs.result }}
        default_branch: ${{ env.default_branch_ref }}

      steps:
        - uses: actions/checkout@v3

        - name: Configure aws credentials

        - name: Get secrets from AWS

        - name: Set VSS nugent endpoint

        - name: Check Cross-Platform SLN Existence

        - name: Checking for threshold bypass

        - name: Setup .NET Core
          if: ${{ steps.slncheck.outputs.result == 0  }}
          uses: actions/setup-dotnet@v2
          with:
            dotnet-version: |
              3.1.404
              6.0.x
              7.0.x
              8.0.x

        - name: Install dependencies

        - name: Build Debug
          if: ${{ steps.slncheck.outputs.result == 0  }}
          run: dotnet build --configuration Debug --no-restore

        - name: Enumerate Test Projects 

        - name: Read Unit Test Code Coverage Threshold

        - name: Determine default branch
          run: 

        - name: Unit Test Code Coverage (Feature Branch)
          if: ${{ steps.slncheck.outputs.result == 0  && github.ref != env.default_branch_ref }}
          id: unittestcoverage
          uses: action-coverlet@sonarqube-format
          with:
            threshold: ${{ steps.getCoverageThreshold.outputs.metricValue }}
            overrideThreshold: ${{ contains(steps.bypass.outputs.actionsToSkip, 'unittestcoverage') }}

        - name: Unit Test Code Coverage (Master Branch)
          if: ${{ github.event_name == 'push' && steps.slncheck.outputs.result == 0 && github.ref == env.default_branch_ref }}
          id: master-unittestcoverage
          uses: action-coverlet@sonarqube-format

        - name: Publish Coverage

        - name: Print coverage.xml
          run: cat coverage.xml || echo "File not found coverage.xml"

        - name: Upload coverage report
          uses: actions/upload-artifact@v2
          with:
            name: coverage-report
            path: coverage.xml

    metricvaluestep:
      needs: unittestcoverage

    slncheck:
      name: Check Cross-Platform SLN Existence

    sonar:
      name: Sonar Scan
      needs: [slncheck, unittestcoverage]
      runs-on: [self-hosted, x64, ubuntu-latest]
      timeout-minutes: 10
      if: ${{ needs.slncheck.outputs.result == 0}}
      container: mcr.microsoft.com/dotnet/sdk:6.0

      steps:
        - uses: actions/checkout@v3
          with:
            fetch-depth: 0

        - name: Create directory for coverage reports
          run: mkdir -p ./.sonar/coverage-reports

        - name: Download coverage report
          uses: actions/download-artifact@v2
          with:
            name: coverage-report
            path: ./.sonar/coverage-reports

        - name: List files in the coverage reports folder
          run: ls -al .sonar/coverage-reports

        - name: Print coverage.xml content
          run: cat ./.sonar/coverage-reports/coverage.xml || echo "coverage.xml not found!"

        - name: Set up JDK 17
          uses: actions/setup-java@v3
          with:
            java-version: 17
            distribution: zulu

        - name: Configure AWS credentials

        - name: Get secrets from AWS

        - name: Set VSS nuget endpoint

        - name: Install Dependencies

        - name: Cache SonarQube packages
          uses: actions/cache@v2

        - name: Cache SonarQube scanner
          id: cache-sonar-scanner

        - name: Install SonarQube scanner
          if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
          run: |
            mkdir -p ./.sonar/scanner
            dotnet tool install dotnet-sonarscanner --version 6.2.0 --tool-path ./.sonar/scanner

        - name: Configure PR Args

        - name: Build and Analyze
          env:
            GITHUB_TOKEN: ${{ env.IX_ACTIONS_PAT }}
          run: |
            rm -f ./sonar-project.properties || true
            sed -i -e '/<MSBuildTreatWarningsAsErrors>true<\/MSBuildTreatWarningsAsErrors>/d' 'Solution Items'/iX.targets
            slnFile=$(find -name *.sln)
            ./.sonar/scanner/dotnet-sonarscanner begin /k:"${{ github.event.repository.name }}" /d:sonar.token="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="${{ secrets.SONAR_HOST_URL }}" /d:sonar.cs.opencover.reportsPaths="./.sonar/coverage-reports/coverage.xml" /d:sonar.verbose="true" ${{ env.SONAR_ARGS }}
            dotnet msbuild $slnFile /t:Rebuild
            ./.sonar/scanner/dotnet-sonarscanner end /d:sonar.token="${{ secrets.SONAR_TOKEN }}"

So the error what I am facing is that the application is running in $GITHUB_WORKSPACE
which has all of the files also the CameraSystemService/CameraSystem.cs

But the opencover coverage.xml file check the File’s fullpath in “/github/workspace/CameraSystemService/CameraSystem.cs” where in the running directory there is no /github/workspace folder having this content so we are getting this issue

But I even worked on creating a folder in $GITHUB_WORKSPACE as ./github/workspace and copy pasted the folder CameraSystemService/* into it but still I am getting the same error

Hey @Colin, I tried a different method to get the data on SonarQube dashboard and it worked. I have created another discussion to clarify one of the doubt which I have regarding getting different coverage % in local scan and SonarQube dashboard