SonarScanner & msbuild called by tools

Preambel:

  • SonarQube: 7.9.1.27448
  • TFS: 2017

We have set up a SonarQube server and we do use TFS build definition to actually create statistics for asp.net MVC projects. The statistics are fine so far: We do see stats for java script, xml, etc.
We do not see stats for C# files.

I expect this to be the reason: As far as I understand, the build step “Prepare Analysis Configuration” somehow hooks into msbuild.
Now we are not calling msbuild directly in the build step but run a small C# application from which we then run msbuild. This tool, amongst other things, determines the actual msbuild version to use.

In the end analysis step, I do see this output:

2019-11-06T01:15:57.5651686Z ##[error]The SonarQube MSBuild integration failed: SonarQube was unable to collect the required information about your projects.
Possible causes:

  1. The project has not been built - the project must be built in between the begin and end steps
  2. An unsupported version of MSBuild has been used to build the project. Currently MSBuild 14.0.25420.1 and higher are supported.
  3. The begin, build and end steps have not all been launched from the same folder
  4. None of the analyzed projects have a valid ProjectGuid and you have not used a solution (.sln)

I assume that this “hooking” of yours somehow doesn’t work in that scenario.

My actual question is: What exactly do you do to hook into msbuild?
Once we understand this, we can find ways to use our tool for analysis as well.

Thx
Michael

Hi @Xantur. Welcome to the community.

I’m assuming you have selected the “Integrate with MSBuild” option when configuring the Prepare Analysis Configuration step i.e.
image

If so, then the SonarQube extension is effectively acting as a wrapper around the SonarScanner for MSBuild, so the documentation for that might help you. Depending on exactly what you are doing, you might find it easier to call the SonarScanner for MSBuild directly as a command line tool.

We hook in to the MSBuild process using the ImportBefore mechanism. We have two targets files. The first, SonarQube.Integration.ImportBefore.targets, is a small stub whose only job is the load the main SonarQube.Integration.targets that do the actual work.

For each supported version of MSBuild, the Prepare Analysis Configuration/begin step copies the loader targets into the MSBuild ImportBefore folder under %LOCALAPPDATA% e.g. %localappdata%\Microsoft\MSBuild\15.0\Microsoft.Common.targets\ImportBefore
MSBuild will automatically import all files in ImportBefore into any build, so we use this mechanism to hook into the built without having to make changes to the MSBuild project files being analysed.

The Prepare Analysis Configuration/begin step also copies the main targets file and supported task assemblies to a .sonarqube working folder under the current directory.

When MSBuild runs, it will import the loader targets, which will try to load the main targets from the .sonarqube folder. If the main targets are loaded, then they will write data about the build under .sonarqube folder.

When the Run Code Analysis/end executes, it looks in the .sonarqube for the data collected about each project, generates a sonar-project.properties file and then calls the Java scanner-cli to upload the results to SonarQube.

Debugging tip: the Sonar targets write out info messages in the log to help diagnose any issues. From v4.7+ of the Scanner for MSBuild all of the messages from our targets are prefixed with Sonar: .

Mandatory health warning: the description above is of the internal implementation. The mechanism wasn’t designed to be extensible/customised by consumers, and could change without notice in a future release of the SonarScanner for MSBuild or Azure Marketplace extension. Having said that, it hasn’t changed since the first release in 2015.