Code Coverage Zero for Mono Repo

Hi everyone,

we are using SonarCloud with automatic analysis and are overall happy with it.

Now we want to add coverage results for out GoLang projects but I cannot get it to work. I switched from automatic analysis to ci-based analysis and configured the sonarcloud-github-action (see below) but I cannot get the coverage results in the project.

This feature is only available for CI-based analysis. It is not available for automatic analysis.
Source: Test coverage & SonarCloud

Our Code structure

We have a mono repo with all our GoLang projects that looks like the following. During build/test cycle we generate the coverage.out files.

go-project-1/coverage.out
go-project-1/go.mod
...
go-project-2/coverage.out
go-project-2/go.mod
...
go-project-3/coverage.out
go-project-3/go.mod
...

This is the config for the GH action that we used.

      - name: SonarCloud Scan
        uses: SonarSource/sonarcloud-github-action@master
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
        with:
          args: >
            -Dsonar.organization=${{ secrets.SONARCLOUD_ORGANIZATION }}
            -Dsonar.projectKey=${{ secrets.SONARCLOUD_PROJECT_KEY }}
            -Dsonar.sources=.
            -Dsonar.tests=.
            -Dsonar.test.inclusions=**/*.spec.ts,**/*.spec.tsx,**/*.test.ts,**/*.test.tsx
            -Dsonar.go.coverage.reportPaths=go-project-1/coverage.out,go-project-2/coverage.out,go-project-3/coverage.out

In the GH action logs I can see that it is loading the coverage.out files but it is writing a warning that the files are not included in the project and that they are being ignored.

INFO: Load coverage report from '/github/workspace/go-project-1/coverage.out'
INFO: Load coverage report from '/github/workspace/go-project-2/coverage.out'
INFO: Load coverage report from '/github/workspace/go-project-3/coverage.out'
WARN: File 'github.com/<GITORG>/go-project-1/internal/routes/regions.go' is not included in the project, ignoring coverage
WARN: File 'github.com/<GITORG>/go-project-1/internal/routes/ping.go' is not included in the project, ignoring coverage
WARN: File 'github.com/<GITORG>/go-project-1/internal/routes/organizations.go' is not included in the project, ignoring coverage
...

This is what the coverage.out files look like

mode: atomic
github.com/dash0hq/go-project-1/internal/config/config.go:65.83,69.49 3 0
github.com/dash0hq/go-project-1/internal/config/config.go:69.49,72.3 2 0
github.com/dash0hq/go-project-1/internal/config/config.go:74.2,76.16 3 0
github.com/dash0hq/go-project-1/internal/config/config.go:76.16,78.3 1 0
github.com/dash0hq/go-project-1/internal/config/config.go:79.2,82.16 4 0
...

What we tried

1. Using projectBaseDir

The only thing that worked for us is creating a separate project in SonarCloud for each GoLang project, and running the GH action for each projectBaseDir.

uses: sonarsource/sonarcloud-github-action@master
with:
  projectBaseDir: go-project-1
...

We don’t like that approach since this would create a lot of separate projects in SonarCloud. This would also make PR reviews harder.

2. global go.mod project

We also tried creating a global go.mod project in the root project with a Go file that imports all other go projects just for the analysis. We saw a similar solution somewhere online (can’t find the link anymore) but that did not work.

Has anyone figured out a way how to get this working?

1 Like

We have a similar issue: monorepo with a go.mod file in the root dir, and multiple Go modules as directories in the project. Please see https://github.com/testcontainers/testcontainers-go

Our issue is related to the code coverage view shows 0% coverage where the go toolchain shows a 48% coverage for certain file. More precisely, the file options.go is the one that I’m interested, but there are more of them:

  • every Go module has its own CI workflow, which uploads the coverage and XUnit test files to a GH artifact. Because all workflows share the same artifact name, they are contributing their files to the same file system without collisions (see attachment sonarcloud.zip (49.6 KB).
  • we use the official GH action to run sonarcloud
  • we checkout the project
  • we download the artifact (see attachment) to the workspace, using the sonar.properties file (see file in the root dir of the repo).
  • we have verified that the XUnit tes file has the methods to cover the affected lines.
  • we have verified that the coverage file has the lines covered with a “1” value.

URLs of interest

There is a difference for the same method.

As a side note, there is no specific docs for Go here: Test coverage overview. Do you think this issue can come with an outcome of adding Go there?

1 Like

Hello @MarcelBirkner and welcome to the sonar community!

The warnings tell that those files are not found so their coverage is not included in the final coverage. Can you check the those files exist in your project?

Can you check that your coverage.out files have actually some coverage? Just verify that there is at least a line ending with a 1, instead of having all zeroes. Try with the command below:

grep '1$' **/coverage.out | wc -l  

In case the result is different than zero then there is a problem.

Meanwhile, I have reproduced your scenario and I was able to get the coverage. You can check the reproducer, and the analysis results at SonarCloud.

I’m running the analysis manually using the latest Sonar Scanner CLI as follows:

sonar-scanner-5.0.1.3006-macosx/bin/sonar-scanner \
   -Dsonar.organization="jvm-squad" \
   -Dsonar.projectKey="jvm-squad_gomonoreporeproducer" \
   -Dsonar.sources="." \
   -Dsonar.exclusions="**/*_test.go" \
   -Dsonar.tests="." \
   -Dsonar.test.inclusions="**/*_test.go" \
   -Dsonar.host.url="https://sonarcloud.io" \
   -Dsonar.go.coverage.reportPaths="**/coverage.out"

Each project has a coverage.out file, so I simplified the list of paths.

Could you try using the last Scanner CLI?

Cheers,
Angelo

Hello @mdelapenya and welcome to the Sonar Community.

Thank you for providing all these details, I can’t find anything wrong from the fist look. Can you provide the logs from the analysis to make sure that the reports are correctly loaded?

May I ask you to elaborate your question? What do you mean by “outcome of adding Go there”?

Cheers,
Angelo

Sorry for the late response. I went back to this task and found related issues as described in Monorepo: how to add subprojects automatically to the parent project when a build is triggered

I’ll update both threads with the results once the pipeline works with success.

Thanks!

Hi! I managed to build the code analisys for the monorepo, building the project keys on the GH worker on-the-fly. This is possible because each module in the monorepo is built in isolation in the GH workflow: testcontainers-go/.github/workflows/ci-test-go.yml at main · testcontainers/testcontainers-go · GitHub

Thanks in any case for your support!

1 Like