8

I will preface this that my current solution to this is very easy but one I do not want to keep implementing.


The Problem

Below you will see an image outlining my current build steps. Each of these contain the default settings, with the Prepare analysis on SonarQube setup to point to my endpoint.

When I run this, again just default settings, I am presented with the following errors

WARNING: Duplicate ProjectGuid: "00000000-0000-0000-0000-000000000000". The project will not be analyzed by SonarQube. Project file: "D:\a\1\s\API.Tests.csproj"
WARNING: Duplicate ProjectGuid: "00000000-0000-0000-0000-000000000000". The project will not be analyzed by SonarQube. Project file: "D:\a\1\s\API.csproj"

This is because the build step for dotnet core, by default, looks for **/*.csproj using the linked setting (Parameters.RestoreBuildProjects) - with the update to the csproj format the project guid is no longer stored in the csproj files. What I suspect is happening is that SonarQube just defaults the guids when it finds nothing defaults to 000... and then throws this error.


The Fix

Unlinking the Path to project(s) parameter and pointing to **/.*.sln fixed the issue, because now SonarQube can see the project guids (defined the .sln)


The Question, finally

After that long winded explanation I am lead to ask if there is a better way to get SonarQube to recognise dotnet core projects.

I do not want to change the default build task every time I create a project to satisfy SonarQube's requirements.


Sonarqube with a dotnet core project

Questioning
  • 1,903
  • 1
  • 29
  • 50
  • 1
    Have you considered creating a template or task group that is configured correctly so you can just use that? – jessehouwing Jul 08 '18 at 11:58
  • @jessehouwing I have and, again, I don't particularly want to do that if there is a simpler way (such as adding an argument to one of the SonarQube tasks, or something else). I feel like SonarQube should support this out of the box / with some configuration otherwise every developer out there will have to do the same as I am. – Questioning Jul 08 '18 at 12:07
  • 1
    Send them a pull request: https://github.com/SonarSource/sonar-scanner-vsts – jessehouwing Jul 08 '18 at 13:04
  • You have to create ProjectGuid one using script https://stackoverflow.com/a/52557954/570598 – Alan Turing Dec 31 '18 at 03:56
  • @arturMustafin Yes, that is an option but it's not really a prefered one in my opinion. – Questioning Jan 09 '19 at 17:33
  • 1
    https://github.com/SonarSource/sonar-scanner-msbuild/issues/659 Coming soon... maybe. – paulio Mar 26 '19 at 20:05

3 Answers3

4
$paths = Get-ChildItem -include *.csproj -Recurse
foreach($pathobject in $paths) 
{
    $path = $pathobject.fullname
    $doc = New-Object System.Xml.XmlDocument
    $doc.Load($path)
    $child = $doc.CreateElement("ProjectGuid")
    $child.InnerText = [guid]::NewGuid().ToString().ToUpper()
    $node = $doc.SelectSingleNode("//Project/PropertyGroup")
    $node.AppendChild($child)
    $doc.Save($path)
}
Alan Turing
  • 2,482
  • 17
  • 20
1

Building on Artur Mustafin solution, I took that and put it inside a powershell step. I also check for the node incase you have a mix of .net and core

- powershell: |
   $paths = Get-ChildItem -include *.csproj -Recurse
   foreach($pathobject in $paths) 
   {
       $path = $pathobject.fullname
       $doc = New-Object System.Xml.XmlDocument
       $doc.Load($path)
       $child = $doc.CreateElement("ProjectGuid")
       $child.InnerText = [guid]::NewGuid().ToString().ToUpper()
       $node = $doc.SelectSingleNode("//Project/PropertyGroup")
       if ($node)
       {
           $node.AppendChild($child)
           $doc.Save($path)
       }
   }
  workingDirectory: '$(Build.SourcesDirectory)'
  displayName: 'Add Project GUIDs'
Nicholas Mayne
  • 1,694
  • 14
  • 18
0

The simplest approach is to create a build template as @jessehouwing suggests.

The comments in this SO question explain why SonarQube needs a stable unique id for each project. There isn't currently a flag you can pass to the tasks to tell the Scanner for MSBuild to use an alternative identity if there isn't a project guid. It also isn't obvious what could be used as an alternative id: the file path to the project isn't stable, and the project name isn't guaranteed to be unique and can change so it isn't stable either.

FYI the SonarCloud extension for VSTS now includes a minimal template for .NET Core projects to help new users try out analysing projects. That template has the build parameter set to **/*.sln, and some of the non-essential build steps removed (e.g. publishing artefacts). It's intended to allow new users to try out analysing code without having to set up any machines and with a minimum of configuration (i.e. using VSTS + SonarCloud + hosted build agent as described in this HOL).

We didn't add templates to the SonarQube extension because that's not a zero-installation option, and adding a template didn't seem to add much value. If you think it would be useful, you could make a suggestion on the SonarSource Community forum.

duncanp
  • 1,572
  • 1
  • 10
  • 8
  • The easiest option to me would be to add a flag and an pointer to the solution file in the `Prepare analysis` step. That way SonarQube can have an idea of the project id's. Something like `Is dotnet core` if yes you add the solution file pointer. Sonarcloud costs far more than the self hosted option so isn't something I can consider. – Questioning Jul 09 '18 at 11:47
  • That doesn't sound any quicker or easier than changing the build definition to build **/*.sln, and is less discoverable. BTW why do you need to unlink the build parameter? Why not just edit the parameter at process level to use **/*.sln instead? – duncanp Jul 10 '18 at 07:10
  • It is just as easy, and more importantly it is a configuration setting on SonarQube rather than a configuration setting on a default task for dotnet core. I can't provide any evidence for this but I suspect most people are fine with the defaults and don't change them - I feel like the solution should be something that does not rely on another task being configured correctly for it to function, but I'm probably being pedantic. Changing the parameter would work, but my point about configuration still stands. – Questioning Jul 10 '18 at 09:59
  • 2
    I agree it would be better if it wasn't necessary to change the task defaults. However, I think adding another setting etc would generate more support issues than it would remove. – duncanp Jul 10 '18 at 12:06
  • 1
    You could be right. I'll speak to my team and see what we want to do with this info. Thanks for the options. – Questioning Jul 10 '18 at 13:33