SonarCloud with Dotnet Project and TypeScript

Last month, we got a chance to build a new product from scratch again. It’s a simple project that build REST API on top of .NET 5 as a backend and React as a frontend. And this is the first time that we build a frontend TypeScript that do not host with .NET web project, this is how we found this challenge.

Image by Christopher Kuszajewski from Pixabay

Before we go further, I never mention how architecture our build and release pipeline. As of Today, my team is stuck into Microsoft world, from the benefit we got from partner program which actually hard to move away from it.

We’re using Microsoft Azure DevOps as our main SCM aka source code management. We do have a build and release pipeline within Azure DevOps. In every Pull Request, we do need a certain number of team member that need to review. In each PR we have a continuous build that does check the build, run unit tests, and yes run Sonar Cloud as our static code analysis tool. This is how it begin.

Problem

The problem we found is, usually when you do use SonarCloud for .NET project, you will need to specific mode of SonarCloud extension for Azure Pipeline. This mode, MSBuild Mode, will do analyze the code by navigate to each project files in your code. This SonarCloud with MSBuild mode is working fine for any language, included TypeScript, as long as the files are included in Visual studio project file. Which it my case, it didn’t. We decide to not host the frontend with .NET, instead we do develop with VS Code and thinking about run it with simple Node.js. This is then the problem that frontend code won’t get analyzed when we use SonarCloud with MSBuild mode. It just does like those typescript file didn’t exist.

SonarCloud Azure DevOps configuration

If you enable verbose log for SonarCloud extension, by set property sonar.verbose=true, you can see that in MSBuild analysis mode, it go through each project.

INFO: Indexing files of module 'Module.Foo'
.
.
.
INFO: Indexing files of module 'Module.Bar'
.
.
.

Then we try using another mode of SonarCloud extension, CLI mode, which we have have to specific path to all files. The sad news is it’s not work, SonarCloud CLI can’t analyze .NET code since they have to do more complicate stuff for .NET, something related to Roslyn complier from .NET. So, this becomes more complicate because the one work with .NET can work only with .NET project, while another mode can’t work with .NET at all.

This is when I decided to split the CI build to do code analysis separately between backend and frontend code. However, one thing to note here is, currently the way SonarCloud extension work, you could only put one analyze task per build pipeline, at least for Azure DevOps. So you couldn’t analyze .NET first then add task to analyze the non-dotnet later in same build.

Another thing to mention, the way SonarCloud Pull Request Decoration work is, every time PR get created/updated and kick off a new build, after SonarCloud analyzed code, it will delete all existing their own comment in the PR and put the new comment in, that’s why multiple analyze not work in single build pipeline, the first analyzed comment will get deleted when the second analyze does it job. Which for this subject, I think it’s better to mark comment as resolved rather than delete it?

Solution

So, the way I get it works here is, I do separate the build, we create two CI build, one for backend which do .NET build, run unit tests, generate code coverage, and analyze code with MSBuild mode link to backend project in SonarCloud, yes – I do separate the project in SonarCloud as well. I also enable Monorepo feature of SonarCloud, which it will understand that single git repository will have multiple SonarCloud project link to it.

And then I create another CI Build for frontend which run npm build, do tests, code coverage, and analyze SonarCloud with CLI mode. This will link to the frontend project in SonarCloud.

I do set the trigger to trigger two CI when PR update so it will do frontend and backend build parallel which give me the benefit that CI will finish sooner. I can also do path filtering that the frontend build will be required to run only when the frontend folder has changes, same as backend.

After we get two builds done, you can see comments for both frontend and backend now. There will be a name of SonarCloud project in each comment to let you see which project put the comment.

Sample of PR decoration from two project of SonarCloud in single PR
Branch policy to filter CI trigger to a specific path for Azure DevOps

I guess the same could apply to SonarQube, the self-hosted version of SonarCloud.

References

SonarCloud for .NET https://docs.sonarqube.org/latest/analysis/scan/sonarscanner-for-msbuild/

Issue raised in SonarCloud https://community.sonarsource.com/t/analysing-repo-with-multiple-project-types-net-core-typescript/19202

Monorepo feature of SonarCloud, https://sonarcloud.io/documentation/advanced-setup/monorepo-support/

Scroll to top