SonarScanner .Net supplying analysis parameters in .csproj

I’m trying to run SonarScanner .NET. I’d like to keep most of the fixed analysis parameters in the config file rather than building huge CLI command each time. I’m not finding the documentation very clear on how to that. I’ve seen this example:

<!-- in .csproj -->
<ItemGroup>
  <SonarQubeSetting Include="sonar.stylecop.projectFilePath">
    <Value>$(MSBuildProjectFullPath)</Value>
  </SonarQubeSetting>
</ItemGroup>

so I tried to replicate it:

<Project Sdk="Microsoft.NET.Sdk.Web">
    <PropertyGroup>
        <TargetFramework>net6.0</TargetFramework>
        <RuntimeIdentifier>linux-x64</RuntimeIdentifier>
        ...
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="NLog" Version="4.7.14"/>
        ...
    </ItemGroup>
    <ItemGroup>
        <ProjectReference Include="..\lib\<local-dependency>.csproj" />
    </ItemGroup>
    <ItemGroup>
        <SonarQubeSetting Include="sonar.projectKey">
            <Value>myorg_myproj</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.organization">
            <Value>myorg</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.host.url">
            <Value>https://sonarcloud.io</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.projectName">
            <Value>myproj</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.sources">
            <Value>src/</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.exclusions">
            <Value>**/*.json, **/*.py, **/*.js, **/*.xml, **/*.html, **/*.yml, **/*.yaml</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.tests">
            <Value>test/</Value>
        </SonarQubeSetting>
        <SonarQubeSetting Include="sonar.cs.vscoveragexml.reportsPaths">
            <Value>dist/coverage.xml</Value>
        </SonarQubeSetting>
      </ItemGroup>
</Project>

Yet when I run /root/.dotnet/tools/dotnet-sonarscanner begin I get the following output:

SonarScanner for MSBuild 6.2
Using the .NET Core version of the Scanner for MSBuild
Pre-processing started.
Preparing working directories...
07:59:34.867  07:59:34.865  A required argument is missing: /key:[SonarQube/SonarCloud project key]
07:59:34.867  Expecting at least the following command line argument:
- SonarQube/SonarCloud project key
The full path to a settings file can also be supplied. If it is not supplied, the exe will attempt to locate a default settings file in the same directory as the SonarQube Scanner for MSBuild.
Use '/?' or '/h' to see the help message.
07:59:34.867  Pre-processing failed. Exit code: 1

What am I missing?

After spending a good few hours researching the topic on my own, I found some pointers that SonarQube.Analysis.xml might be what I’m looking for, however it didn’t seem to be picked up by the dotnet-sonarscanner globally installed tool (not surprising considering that official docs mention it ONLY in the context of the Standalone Executable).

After a bit more of the hopeless research I came across this thread that talked about a seemingly undocumented /s:settings_file argument (no, my bad, it’s only missing from the online docs, but appears in the help output of the dotnet-sonarscanner). So I added SonarQube.Analysis.xml to the project root and moved all key settings to it:

<?xml version="1.0" encoding="utf-8" ?>
<SonarQubeAnalysisProperties
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.sonarsource.com/msbuild/integration/2015/1">
  <Property Name="sonar.verbose">true</Property>
  <Property Name="sonar.host.url">https://sonarcloud.io</Property>
  <Property Name="sonar.projectKey">myorg_myproj</Property>
  <Property Name="sonar.organization">myorg</Property>
  <Property Name="sonar.projectName">MYPROJ</Property>
  <Property Name="sonar.exclusions">**/*.json, **/*.py, **/*.js, **/*.xml, **/*.html, **/*.yml, **/*.yaml</Property>
  <Property Name="sonar.cs.vscoveragexml.reportsPaths">dist/coverage.xml</Property>
</SonarQubeAnalysisProperties>

And just when I thought my project settings nightmare was over, this is what I see in the stdout after setting the /s:settings_file argument:

$ /root/.dotnet/tools/dotnet-sonarscanner "begin" "/s:SonarQube.Analysis.xml" "/d:sonar.token=..."
SonarScanner for MSBuild 6.2
Using the .NET Core version of the Scanner for MSBuild
Loading analysis properties from /data/work/.../myproject/SonarQube.Analysis.xml
sonar.verbose=true was specified - setting the log verbosity to 'Debug'
Pre-processing started.
Preparing working directories...
Using environment variables to determine the download directory...
07:33:02.81  07:33:02.808  A required argument is missing: /key:[SonarQube/SonarCloud project key]
07:33:02.81  07:33:02.81  Unable to find the analysis settings file '/data/work/.../myproject/.sonarqube/SonarQube.Analysis.xml'. Please fix the path to this settings file.
07:33:02.81  Expecting at least the following command line argument:
- SonarQube/SonarCloud project key
The full path to a settings file can also be supplied. If it is not supplied, the exe will attempt to locate a default settings file in the same directory as the SonarQube Scanner for MSBuild.
Use '/?' or '/h' to see the help message.
07:33:02.81  Pre-processing failed. Exit code: 1

Loading analysis properties from /data/work/.../myproject/SonarQube.Analysis.xml
  • Ok, great, it seems to have picked up the verbose flag!
07:33:02.81  07:33:02.81  Unable to find the analysis settings file '/data/work/.../myproject/.sonarqube/SonarQube.Analysis.xml'. Please fix the path to this settings file.
  • Huh?

Is this a bug? Is it a feature? Please consider streamlining the project configuration. It should NOT be that difficult, especially for someone who comes with the previous experience of configuring SonarCloud in 10+ other projects. I understand that different ecosystems may have impact on how the scan is implemented, but the documentation should smooth out all the bumps.

2 Likes

Is it really that uncommon to use file-based configuration for .Net ecosystem? If so, I’d love to know why is that - maybe I’m doing something wrong/creating more problems down the line by trying to pursue the file-based configuration? FYI not a .Net expert here.

Hi @Ivan_Ribakov

Sorry for the delayed answer.

Sorry for this. The SonarQube docs mention the parameter, but not the SonarCloud docs. I’ve opened an internal ticket for our docs team to fix this.

  • /s:<custom.analysis.xml>
  • [optional] Overrides the $install_directory/SonarQube.Analysis.xml. You need to give the absolute path to the file.

This is unexpected.

Could you please provide the commands you are executing? Do you have a small reproducer project with a script to execute the commands, to easily reproduce this? Are you providing an absolute path to the file?

Thanks!

The snippet above includes the command invoked:

$ /root/.dotnet/tools/dotnet-sonarscanner "begin" "/s:SonarQube.Analysis.xml" "/d:sonar.token=..."

No, relative.

Here’s an MRE:

/sonar_mre
├ Dockerfile
├ Program.cs
├ sonar_mre.csproj
├ SonarQube.Analysis.xml

Dockerfile:

FROM mcr.microsoft.com/dotnet/sdk:6.0-bullseye-slim

ARG SONAR_DOTNET_SCANNER_VER=6.2.0
RUN dotnet tool install --global dotnet-sonarscanner --version ${SONAR_DOTNET_SCANNER_VER}

RUN apt-get update \
 && apt-get install -y \
    openjdk-17-jre-headless \
 && apt-get clean \
 && rm -rf /var/lib/apt/lists/*

Program.cs

Console.WriteLine("Hello, World!");

sonar_mre.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net6.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

SonarQube.Analysis.xml

<?xml version="1.0" encoding="utf-8" ?>
<SonarQubeAnalysisProperties
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns="http://www.sonarsource.com/msbuild/integration/2015/1">
  <Property Name="sonar.verbose">true</Property>
  <Property Name="sonar.host.url">https://sonarcloud.io</Property>
  <Property Name="sonar.projectKey">myorg_myproj</Property>
  <Property Name="sonar.organization">myorg</Property>
  <Property Name="sonar.projectName">MYPROJ</Property>
</SonarQubeAnalysisProperties>

Steps to reproduce:

$ cd sonar_mre
$ docker build . -t sonar_mre:latest
$ docker run -it --rm -v /<path-to>/sonar_mre:/app -w /app sonar_mre:latest
$ /root/.dotnet/tools/dotnet-sonarscanner "begin" "/s:SonarQube.Analysis.xml" "/d:sonar.token=foo"
SonarScanner for MSBuild 6.2
Using the .NET Core version of the Scanner for MSBuild
Loading analysis properties from /app/SonarQube.Analysis.xml
sonar.verbose=true was specified - setting the log verbosity to 'Debug'
Pre-processing started.
Preparing working directories...
Using environment variables to determine the download directory...
11:00:27.803  11:00:27.802  A required argument is missing: /key:[SonarQube/SonarCloud project key]
11:00:27.803  11:00:27.803  Unable to find the analysis settings file '/app/.sonarqube/SonarQube.Analysis.xml'. Please fix the path to this settings file.
11:00:27.803  Expecting at least the following command line argument:
- SonarQube/SonarCloud project key
The full path to a settings file can also be supplied. If it is not supplied, the exe will attempt to locate a default settings file in the same directory as the SonarQube Scanner for MSBuild.
Use '/?' or '/h' to see the help message.
11:00:27.803  Pre-processing failed. Exit code: 1
1 Like

When I try to supply the absolute path, logs are less confusing but still don’t quite make sense:

$ /root/.dotnet/tools/dotnet-sonarscanner "begin" "/s:/app/SonarQube.Analysis.xml" "/d:sonar.token=foo"
SonarScanner for MSBuild 6.2
Using the .NET Core version of the Scanner for MSBuild
Loading analysis properties from /app/SonarQube.Analysis.xml
sonar.verbose=true was specified - setting the log verbosity to 'Debug'
Pre-processing started.
Preparing working directories...
Using environment variables to determine the download directory...
11:03:50.837  11:03:50.836  A required argument is missing: /key:[SonarQube/SonarCloud project key]
11:03:50.838  11:03:50.837  Loading analysis properties from /app/SonarQube.Analysis.xml
11:03:50.838  Expecting at least the following command line argument:
- SonarQube/SonarCloud project key
The full path to a settings file can also be supplied. If it is not supplied, the exe will attempt to locate a default settings file in the same directory as the SonarQube Scanner for MSBuild.
Use '/?' or '/h' to see the help message.
11:03:50.838  Pre-processing failed. Exit code: 1
  1. It seems that /app/SonarQube.Analysis.xml is found and read:
Loading analysis properties from /app/SonarQube.Analysis.xml
sonar.verbose=true was specified - setting the log verbosity to 'Debug'
  1. Yet for some reason sonar.projectKey is not picked up from that file:
11:03:50.837  11:03:50.836  A required argument is missing: /key:[SonarQube/SonarCloud project key]
11:03:50.838  11:03:50.837  Loading analysis properties from /app/SonarQube.Analysis.xml
11:03:50.838  Expecting at least the following command line argument:
- SonarQube/SonarCloud project key

Hi @Andrei_Epure, so am I looking at a bug or a feature in the end?
Are there any other workarounds aside from supplying project key as a CLI argument?

Hi @Ivan_Ribakov

Again, apologies for the delay. The fix is to provide /k (project key) and /o (organization) via command line, and the absolute path to the SonarQube.Analysis.xml:

dotnet-sonarscanner "begin" "/k:myorg_myproj" "/o:my-org" "/s:C:\full\path\to\SonarQube.Analysis.xml" "/d:sonar.token=foo" 

Our documentation mentions the fact that the /k and /o arguments are required command line parameters, and that the /s file needs to be an absolute path:

  • /k:<project-key>
    [required] Specifies the key of the analyzed project in SonarCloud.
  • /o:<organization>
    [required] Specifies the name of the target organization in SonarCloud.
  • /s:<custom.analysis.xml>
    [optional] Overrides the $install_directory/SonarQube.Analysis.xml. You need to give the absolute path to the file.

This is consistent with the error messages you have received:

and when you provide the project key via the cmdline, but leave the organization via the settings file, you will get an error

sonar.organization parameter has been detected in the provided SonarQube.Analysis.xml config file. Please pass it in the command line instead, using /o: flag.

This is the current design of the scanner and the public documentation mentions those arguments as required command line arguments. That being said, the error message for missing the /k project key argument suggest that providing a settings file should be an alternative to passing via command line, thus I created a task for improving it: Align error message for missing project key with error message for missing organization, when the settings file is provided · Issue #2120 · SonarSource/sonar-scanner-msbuild · GitHub .

And I created a ticket to improve the overall design: Project key and organization should be read from settings file · Issue #2119 · SonarSource/sonar-scanner-msbuild · GitHub

In addition:

Many thanks for your contribution to our community and to improving our products. I really appreciate your time, and I apologize for the tool being counter intuitive in its behavior and error messages.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.