SonarCloud PR branch analysis when the main/trunk branch has not been analysed

SonarCloud (and it's on premise equivalent SonarQube) understand the concept of Git branching and PRs (in various platforms, in my case Azure DevOps was the important one). This means you can block the completion of a PR if the new code in the branch/PR does not meet the SonarCloud Quality Gate. A great way to stop the addition of technical debt.

However, I recently found a problem when starting to use SonarCloud in an older codebase. You cannot do SonarCloud analysis of a child branch before the main/trunk has been analysed.

This is most likely an issue because you are using Azure DevOps YAML Pipelines and must commit your revised pipeline, that triggers SonarCloud analysis, via a PR i.e. you cannot commit direct to main/trunk.

However, in my case I was using Azure DevOps Classic Builds and it was because the work I was doing was to move a codebase from an unsupported version of .NET to .NET 4.8. On the build agents available to me I had no means to build the old codebase, and I was not minded to provision agents just to do that job. So I looked for away to analyse the main/trunk branch to unblock my PR analysis.

Normally SonarCloud analysis is done as part of the automated build process, but there are CLI tools to manage it too. I decided to use these in the quickest dirtiest way I could think of

  1. I cloned my legacy repo (you never use the code in the repo, but it is needed so SonarCloud can detect the branch. You could possibly use an empty git repo as an alternative)
  2. I switched to the main branch and created a folder off the roo
  3. In this folder I created a new dotnet console app
  4. From the root of the repo I ran the SonarCloud dotnet CLI Scanner, passing in the details required to create a new SonarCloud project

dotnet sonarscanner begin /k:"AKEY" /o:"<my sonarcloud org name>" /d:sonar.login="<your access token>" /d:sonar.host.url="https://sonarcloud.io" /n:"Project Name"

  1. I then built the dotnet project
  2. Finally I completed the SonarCloud analysis

dotnet sonarscanner end /d:sonar.login="<your access token>"

This created an analysis of the main branch with the single dotnet program.cs file

It is then possible to do the analysis of the child branches, with all the real code. What code is detected as 'new code' in this branch by SonarCloud will be dependant on your settings. So even though the code on this first PR branch will have never been seen by SonarCloud, it might not be detected as new due to the file's last modified dates.

I realise I could have locally built the legacy code on my PC (removing steps 2 & 3, and replacing step 5 with an MSBuild), but that would have required installing legacy frameworks I did not wish to do.

So a dirty hack, but got me out of a hole, and once the PR was completed SonarCloud showed all the code metrics I would expect.

Updated: 3rd Oct 2022

Just for completeness, these are command lines to do a local MSBuild of an existing codebase using the CLI Scanner. A better options if you have a dev PC available to build the legacy code based but not suitable build agent (and don't want to make your PC a temporary build agent)

  1. Clone the legacy repo
  2. From the root of the repo run the SonarCloud dotnet MSbuild CLI Scanner, passing in the details required to create a new SonarCloud project

sonarscanner.msbuild.exe begin /k:"AKEY" /o:"<my sonarcloud org name>" /d:sonar.login="<your access token>" /d:sonar.host.url="https://sonarcloud.io" /n:"Project Name"

  1. Built the legacy project(s) with MSBuild

'C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\msbuild' .\MyProjectFolder\MyProject.csproj

  1. Completed the SonarCloud analysis

sonarscanner.msbuild.exe end /d:sonar.login="<your access token>"