Coverage exclusions must include project directory

  • SonarQube Server Enterprise 2025.1.0.102418
  • Platform: Azure DevOps
  • SonarQube tasks 7.3.0
  • SonarScanner for MSBuild 10.1.2
  • Analyze a C# solution
  • Enable monorepository support: disabled

Hi there!

I would like to refine the code coverage of my project by excluding certain directories.

To give an example, here is the structure of my repository:

├── src
├── tests
└── tools
    └── test_exclusions_sonar
        ├── Test_00.sql
        └── Test_01.sql

I want to exclude all files under tools\ from the code coverage.

According to the documentation, I set the parameter sonar.coverage.exclusions with tools/**.

It did not work as expected :frowning:

After several tests, I concluded that the project name needs to be specified in the exclusion patterns.

This is my CI task:

      - task: SonarQubePrepare@7
        displayName: 📡 Prepare SonarQube scanner
        continueOnError: true
        inputs:
          SonarQube: ${{ parameters.sonarQubeServiceConnection }}
          scannerMode: "dotnet"
          projectKey: ${{ parameters.sonarQubeProjectKey }}
          projectVersion: ${{ parameters.version }}
          extraProperties: |
            sonar.coverage.exclusions=tools/**
            sonar.verbose=true

Test files I want to exclude are in the initial scope of analysis:

sonar.sources=\
"E:\\vsts-agent\\_work\\33\\s\\my-project\\tools\\test_exclusions_sonar\\Test_00.sql",\
"E:\\vsts-agent\\_work\\33\\s\\my-project\\tools\\test_exclusions_sonar\\Test_01.sql",\

And here are the tests I performed:

  • Using sonar.coverage.exclusions=tools/**, files are indexed and included in code coverage:

    14:36:51.977 INFO:   Excluded sources for coverage: tools/**
    14:36:51.977 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_00.sql' indexed with language 'plsql'
    14:36:51.977 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_01.sql' indexed with language 'plsql'
    
  • Using sonar.coverage.exclusions=tools/test_exclusions_sonar/Test_00.sql, I expected that Test_00.sql was ignored but the two files are indexed and included for coverage:

    14:36:51.977 INFO:   Excluded sources for coverage: tools/test_exclusions_sonar/Test_00.sql
    14:36:51.977 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_00.sql' indexed with language 'plsql'
    14:36:51.977 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_01.sql' indexed with language 'plsql'
    
  • If I add the project name as root directory, Test_00.sql is excluded for coverage:

    14:42:46.958 INFO:   Excluded sources for coverage: my-project/tools/test_exclusions_sonar/Test_00.sql
    14:42:46.958 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_00.sql' indexed with language 'plsql'
    14:42:46.958 DEBUG: File my-project/tools/test_exclusions_sonar/Test_00.sql excluded for coverage
    14:42:46.958 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_01.sql' indexed with language 'plsql'
    
  • Using my-project/tools/**, the result is what I expected, but I cannot specify the project name because the pipeline template needs to work for all projects.

    15:24:24.281 INFO:   Excluded sources for coverage: my-project/tools/**
    15:24:24.281 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_00.sql' indexed with language 'plsql'
    15:24:24.281 DEBUG: File my-project/tools/test_exclusions_sonar/Test_00.sql excluded for coverage
    15:24:24.281 DEBUG: 'my-project/tools/test_exclusions_sonar/Test_01.sql' indexed with language 'plsql'
    15:24:24.281 DEBUG: File my-project/tools/test_exclusions_sonar/Test_01.sql excluded for coverage
    

**/tools/** can do the job but the risk is to exclude some other tools subdirectories.

I would obviously like to configure the exclusions from the root of the repository, without specifying the name of the repository itself. Is this normal behavior or is it a bug?
If so, what did I miss when reading the documentation?

Thanks

I chose to use $(Build.Repository.Name) as a workaround, but I still find it strange… My setting is now

sonar.coverage.exclusions=$(Build.Repository.Name)/tools/**

Hey there!

I think this is a case of the exclusions applying from the base directory. This should be logged

INFO: Base dir: <base_directory>

Is this getting set to one folder above where you expect?

Thanks Colin, you’re right about the base directory and it helped me pinpoint the problem.
As described here, the agent’s directory structure depends on whether you checkout one or multiple repos.

As my pipeline templates are stored in another repo, agent directory structure is

vsts-agent
└── _work
    └──33
       └──s
          ├──my-project
          │  ├── src
          │  └── tools
          └──my-templates

and I need to add ‘my-project’ in sonar exclusions.

So it is not a SonarQube issue.

I solved it by changing the default project base directory like this:

sonar.projectBaseDir=$(Build.SourcesDirectory)/$(Build.Repository.Name)
sonar.coverage.exclusions=tools/**

This way I can override coverage exclusions regardless of the source repo.

If anyone has a better solution, please let me know :slight_smile:

2 Likes