Quality Assurance Using SonarQube: Gitlab & SonarQube Integration
Code review is a process in software development to evaluate code’s quality of a program. A few benefit on doing code review is to identify error or bug as early as possible, detect security issue, and making sure the code is comply with the best practice concept.
Code review can be divided to 2 types, manual and automatic review. While manual review is done by individual tester — could be developer, engineer, or anyone fits the capability — , automatic review is done with tools or programs.
There are a few tools that developer can use for automatic review. One of it is SonarQube. From their documantation:
SonarQube is an automatic code review tool to detect bugs, vulnerabilities, and code smells in your code. It can integrate with your existing workflow to enable continuous code inspection across your project branches and pull requests.
SonarQube is capable to integrate to various DevOps Platform. This article will use Gitlab as our DevOps Platform.
SonarQube and Gitlab Integration
- To start, we need to add a new project in SonarQube. We can choose Gitlab when adding a new project and SonarQube will asked which Gitlab project do we want to setup. Add your Gitlab project there using Gitlab Project Access Token (in your Gitlab repository setting).
- Gitlab needs a way to connect to SonarQube. For this, we need to set it using SonarQube’s token and put it in Gitlab’s CI Variable.
- Click configure analysis in the project that we just made. We will be asked to generate a token.
- Copy the token that you just generated into Gitlab CI/CD Variable (located in your Gitlab repository setting). The key name will be SONAR_TOKEN and the value is the generated token.
With this, we can now start configuring SonarQube in our project’s code itself.
SonarQube Configuration In .gitlab-ci.yml
To automate and make SonarQube check your code quality for every changes made in your branch (whether you merge or push your code), you need to create a sonarqube job in the .gitlab-ci.yml. SonarQube provides a script template that you can use in their docs: https://docs.sonarqube.org/8.3/analysis/gitlab-cicd/. In my case, our team used this script below for our projects:
sonarqube-check:
image:
name: sonarsource/sonar-scanner-cli:latest
entrypoint: [""]
stage: test
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- sonar-scanner -Dsonar.qualitygate.wait=true
Credit to Integrasi* Sonar Scanner dan Gitlab CI/CD by Bayu Hendra Winata!
Configure sonar-project.properties
sonar-project.properties
is a file that SonarQube used for its configuration. The file is located at the root of your project base directory. The mandatory parameter is sonar’s host url and sonar’s project key. The host url is your SonarQube’s domain url (in my case we‘re using sonarqube that was set by our university). Meanwhile, you can get the project key from Project Configuration button in your SonarQube project.
Aside from the mandatory parameter, there are a few optional parameter that you can specify in sonar-project.properties. Sometimes, not all of our project’s source code need to be analyzed. Maybe there are some library, or framework’s configuration files outside of the code that we wrote that doesn’t need to be checked by SonarQube. In this case, we want to point SonarQube to only the relevant codes.
There are a few properties that you could use to achieve this. Some of it is sonar.sources
,sonar.tests
,sonar.inclusions
,sonar.exlusions
. This illustration in SonarQube’s docs below illustrate how sonar.sources works:
sonar.tests works the exact same way with sonar.sources, it’s just that sonar.tests tells SonarQube where our test located at. While sonar.inclusions will includes file that couldn’t be reached by sonar.sources, sonar.exclusions is the opposite, which will exclude files inside sonar.sources from being analyzed.
In my case, our team project source code is inside the src/ folder. But there are files in it that started with “_” that doesn’ t need to be analyzed, which we then exclude that particular files:
And SonarQube also supports wildcards! How convenient!
Reporting Coverage to SonarQube
Now, one important thing to note is this:
SonarSource analyzers do not run your tests or generate reports. They only import pre-generated reports.
Before you spent countless hours — like me — searching why your SonarQube doesn’t record any coverage, remember that SonarQube does not run your test nor generate reports on their own. Instead, what you need to do is to direct SonarQube to your coverage report file.
The coverage report file will be different depending on the language that you used for your app and how you report your coverage. In my case, we used NEXTJS (React/Javascript Framework) for our frontend application and Django (Python Framework) for our backend application.
- Frontend Application
For our frontend application, my team used Jest, a Javascript testing library that works great with React-based app. Jest generated a coverage folder, and one that we need is thelcov.info
file. Specify the file path withsonar.javascript.lcov.reportPaths
inside your sonar-project.properties file. Note that usually coverage folder is ignored by Git. Make sure you excludelcov.info
in your.gitgnore
as well.
- Backend Application
Our team use coverage python library. From this library, we can runcoverage xml -i
command to generatecoverage.xml
file. Specify this file withsonar.python.coverage.reportPaths
on sonar-project.properties.
With this, you are done! Try commit and push your changes to Gitlab and let SonarQube review your code.
Monitoring Quality With SonarQube
Here are some few examples on how SonarQube reviewed my team project application.
Python uses lowercase separated with underscore for more than one word for its naming convention. SonarQube detected that our backend application had camelCase naming and warned us about it.
In the other hand, SonarQube also detect that one of the function in our frontend application is different than the file name. When exporting a Javascript function with export default <function>
, the name of the function and the file name should be the same. SonarQube detected this and asked us to change the name.
The examples from before is in code smell category. But SonarQube can also identify issue that is more important than that. When I first initialized my team backend application, the credentials to our database was hardcoded in settings.py
file. SonarQube detected this and our security rating goes to E. SonarQube warned us that our application is vulnerable and we need to fix it. We then changed our database credentials and put the new ones in environment variables instead.
There are many more things that you can do with SonarQube and it also supports many programming language. Try it and improve your code quality to be more cleaner and safer!
Reference
- SonarQube Documentation
- Integrasi* Sonar Scanner dan Gitlab CI/CD by Bayu Hendra Winata