Last week I’ve attempted to setup SonarCloud for a Nx repository hosted in Azure DevOps.
However, I’m having some trouble understand the functioning of the Azure DevOps SonarCloud prepare step and, the monorepo setup in general.
For clarification we have both .NET Core applications, libraries and, Angular applications and libraries.
Generally speaking a NX monorepo looks like this:
In the azure-pipelines.yml:
I’ve added a SonarCloudPrepare task for each application and library.
I’ve added keys to each SonarCloudPrepare task.
I’ve set the sonar.projectVersion to $(Build.SourceVersion) for each SonarCloudPrepare task. (We don’t have version management that uses semantic versioning or any kind of tagging)
I’ve added a SonarCloudAnalyze task.
I’ve added a SonarCloudPublish task.
I’ve enabled Monorepo support for each project.
I’ve set the analysis scope and narrowed the inclusion to: “apps/app-x//*" or "libs/lib-X//*”.
I’ve set the New Code Definition to “Previous version”.
This “seems” to go well. However, when I check the Analysis logs and the Publication on SonarCloud I only ever see one project being updated with a new analysis.
This project is always the last project for which a SonarCloudPrepare task was started.
I’m quite baffled by this behavior and I would love some support here.
Just stating upfront – no experience with Nx here other than a quick glance at the documentation.
To accomplish what I think you’re trying to do (separate projects for each build), you would need to wrap each individual project build with its own Prepare and Analyze step. We also don’t well support a setup where projects are selectively built based on what changed (and for C# code – we can’t get analysis results without a build).
Can you tell us a bit more about what Nx is doing behind the scenes? Is it, for example, not running a dotnet build on a project if it hasn’t changed?
To accomplish what I think you’re trying to do (separate projects for each build)
Not entirely. Separate projects for each application. It is intended to be setup as stated in the SonarCloud documentation. [ Monorepo Support | SonarCloud Docs ].
I was unable to find a mono-repo example hence, I assumed this is what the documentation intended.
Is it, for example, not running a dotnet build on a project if it hasn’t changed?
This is correct. Nx can retrieve the applications/libraries affected by a change and run selected tasks on them.
This is why I added conditions to prevent SonarCloudPrepare from being run for projects which were not affected by a change.
This is a community forum where we try and help users get the most our of Sonar. We also take holidays, pay attention to other threads, etc. Your patience is appreciated, but bumping threads multiple threads is not.
Thanks for the further details.
SonarCloud relies on a pair of SonarCloudPrepare and SonarCloudAnalyze for each project being targeted for analysis. A single SonarCloudAnalyze will not publish results to multiple SonarQube projects.
Today, I don’t think there’s any graceful way to handle a situation where what is being built by a single build command changes from build to build.
You would effectively need to change your build to have multiple build commands each wrapped by a different set of Prepare/Analayze tasks (which only build one specific project), which I suppose you’d only want to run if they are affected.
I’m happy to flag this thread for some expert attention in case our .NET experts have some other ideas (or simply to make them aware that this tooling is out there, and we don’t integrate well with it)
From my POV this is not entirely correct. Since SonarCloudAnalyze does not define input variables which would allow providing a project-key. Hence the pairing is not explicit but implicit. This means, as you stated, the only way to analyze a build is to run a SonarCloudPrepare, build a single application and then run a SonarCloudAnalyze.
Furthermore, a consequence is that any preceding SonarCloudAnalyze tasks are ignored. This is not stated in the documentation afaik.
Correct. Unfortunately, we cannot run separate tasks to do this because we’re running a mono-repo build-tool which builds multiple applications. I was not able to derive this information from the documentation provided on sonarcloud.io and I would like to suggest this be clarified if possible.
For those interested.
I ended up writing 3 Nx Custom Executors.
Respectively, 2 for Sonar (prepare and analyze) and 1 to wrap the nx-dotnet build executor with the 2 Sonar executors.
It was quite the hassle to achieve this and I will most likely be filing 2 feature requests.
One with SonarSource to support building multiple projects without having to wrap each dotnet build call and one with nx-dotnet to support dotnet tools tasks.