SonarQube is a great tool for static code analysis.
As a standalone app, SonarQube offers free version of its product - called Community - and tree paid versions - Developer, Enterprise and Data Center. There is also a paid SaaS solution called Sonar Cloud, which is free for open source projects on GitHub, Bitbucket or Azure DevOps
SonarQube provides about 20, mostly language-related, out-of-the-box plugins. Their numbers may vary, depending on the version. There are also nearly 60 third-party plugins of different types:
-
Language (e.g. Groovy, YAML)
-
External analyzers (e.g. Checkstyle, FindBugs, PMD, Ansible Lint)
-
Integration (e.g. GitLab and Bitbucket authentication)
-
Code coverage
-
Localization
-
And more
The free community version of SonarQube and free version of Sonar Cloud have different functionalities, shown in this side-by-side comparison:
In this blog, we’ll take a closer look at the latest free community versions: 7.9.2 LTS and 8.1.
Installation
There are several ways to install SonarQube.
-
Manually
-
Get an official docker image on Docker Hub
-
Install SonarQube with our Ansible-SonarQube role
For our purposes, we’ll explore installing SonarQube with our Ansible-SonarQube role. Look through the readme, get the playbook example and adjust it to your needs. The playbook will install SonarQube and everything required for it to work properly: Java (using our Ansible-Java role), PostgreSQL database and NGINX (for https).
The Java role can be used while installing SonarQube and in many other cases as well. It's the best role for a lean delivery project and the best Java role in the Ansible Galaxy.
To install SonarQube, you need an instance with at least 4GB memory (e.g. T3a.medium in AWS).
Note that, in addition to installation, the role can perform configuration actions, including:
-
Migrate the database (note: this is required if you need to make updates to SonarQube)
-
Add Jenkins webhook
-
Import custom quality profiles
-
Configure LDAP authentication
Configuration
The first step when configuring SonarQube is to change the password for the admin under Administration > Security > Users. We will add this configuration option to the role in the near future.
In addition to the password change, add a token for the admin user. You will need this later.
Now, unauthorized users won’t be able to log in with the default username and password, but they will still able to view your code as guest users. So, the next step is to close guest access under Administration > Configuration > Security > Force User Authentication. This feature will also be added to the role.
If other team members need to access SonarQube, configure LDAP authentication or authentication via GitHub, Bitbucket, GitLab, etc.
Next, let's set up quality profiles. Every language plugin provides a built-in quality profile, which is simply a set of active and inactive rules that your code is verified against. In addition to the rules, the profile may contain templates that you can use to create your own rules. This built-in Python profile is a good example.
If you have custom profiles, you can import them during the installation stage using our role and then manually set them as default. If you don’t have custom profiles, leave everything as is – built-in profiles will be used by default. Most likely, you will have to create custom profiles from built-in profiles when you need to activate or inactivate rules or change their settings.
For Java profiles, there are four up-to-date plugins:
-
An out-of-the-box Sonar-Java plugin with Sonar way profile, which is used by default
-
A third-party Sonar-FindBugs plugin with four profiles
-
A third-party Sonar-Checkstyle plugin without profiles
-
A third-party Sonar-PMD plugin without profiles
If you install all four plugins and make no changes to the Quality Profile settings, then Sonar Qube will only use the Sonar way profile for Java code verification. In other words, you will only be using—and getting the benefits of—the out-of-the-box plugin while the other three will go unused. To use all four plugins for verification, create a custom profile that includes the rules from all four plugins. We are planning to add this custom profile to the role.
It’s also important to note that when you update a plugin with new active rules, make sure the rules are activated in the custom profile as well, otherwise the update won’t make any difference. To do this once the plugin is updated, navigate to “Rules,” select the “Available Since” filter and set the current date. Then, in the “Quality Profile” filter, select “Built-in” and then select “Custom Profiles.” The number of new active rules should be the same. If there are no new rules in the custom profile, activate them manually.
Now it’s time to set up the quality gates, which are a set of metrics that determine if code verification is successful or failed. Default quality gates contain code coverage percentage and duplication percentage as well as maintainability, reliability and security ratings. It’s generally best to use a simpler custom set since not every project has the code coverage necessary and not every team has the capacity to fix non-critical issues. In such cases, ratings are not required, and it's enough to not miss blockers, criticals (or sometimes majors).
Then, you need to bind SonarQube to your Continuous Integration (CI) tool. For example, if you used Jenkins as your CI tool, you would first need to navigate to “Administration,” select “Configuration” and then select “Webhooks,” where you can add Jenkins webhook (this step can be done by the role). Next, install the SonarQube Scanner plugin in Jenkins and then add SonarQube Server by navigating to “Manage Jenkins” and then “Configure System” and set the following parameters:
-
Name (any name, it will be used later in the pipeline)
-
SonarQube URL
-
Token added for admin user
An important note about the URL: If you use “https,” there are two possible options. If you have a valid certificate, you’ll need to set it in the SonarQube playbook as the self-signed certificate is used by default. If there is no valid certificate and you use a self-signed one, you need to import it to the Java that Jenkins is running on.
When initially configuring Jenkins, I recommend using our Ansible-Jenkins role, which can also install the plugin and add SonarQube Server in the settings. In the future, we will publish a playbook that can install Jenkins and SonarQube together and set the certificate correctly.
In some cases, instead of the plugin, you can use a separately installed Sonar Scanner and pass scan parameters in the “sonar-project.properties” file. We find that it's more convenient to use the plugin and set scan parameters directly in the pipeline.
Pipeline
Let's explore what happens when you've got a repo with a code and use simple Git flow. There is the main branch (develop/master) where developers can add a new code to the feature branches and open pull requests to the main branch. In this case, you can use SonarQube for verification for both the main branch and pull requests and any additional branches that are important to your workflows. The free community SonarQube version lacks one important feature. However, the feature is available in its paid versions as well as in the paid version Sonar Cloud: Analysis of branches and pull requests in the same project. In other words, in the paid version of Sonar Cloud, a single project corresponds to one repo and contains info about all verified branches and pull requests. Below is an example:
In the free version, multiple projects correspond to one repo because users must create separate projects for the main branch and for every pull request. It's inconvenient for a number of reasons. First, new pull requests are constantly arising and, at some point, you’ll have to consider auto-deleting old projects. Second, if you need to verify more than one repo, it will be a complex process.
Fortunately, there are two convenient ways to organize pull request verification using special plugins.
To execute the first option, users don’t need to create projects for pull requests at all; instead, information on all the found issues will be displayed directly in the pull request. This feature is called pull request decoration. Below is an example of what this feature looks like in action:
This is convenient because a comment with the error message appears under every bad line of the code and there’s a link to the rule where users can learn how to fix the error, making the process much more efficient.
Pull request decoration only works for SonarQube 7.6 and lower, but not for all repositories:
-
Github: It doesn't work with GitHub, as the Sonar-GitHub plugin is no longer supported beyond SonarQube 7.2.
-
Bitbucket Server: It works with the Sonar-Stash plugin.
-
Bitbucket Cloud: It works with the Sonar-Bitbucket plugin.
-
GitLab: It works with the Sonar-GitLab plugin.
-
Azure DevOps: It doesn't work, and there is no plugin for it.
The second option is to use the new SonarQube-Community-Branch plugin, which analyzes branches and pull requests in the same project. Unfortunately, in the current version (version 1.2.0), the latest version of SonarQube (version 8.1) is not yet supported, and the pull requests decoration feature is not yet available. If you don’t want to wait and need the pull request decoration feature now, you can build a new plugin yourself.
Find the pipeline to run SonarQube analysis here, which contains stages for both ways.
How to Start Using it on Your Project
To start using it on your project, you first need to add the SonarQube analysis step to the main branch build and make sure it won’t fail by removing all metrics from the quality gates.
A project with the main branch analysis result will appear in SonarQube. Often, you might find many issues – it's impossible for developers to review all of them. This is especially true for large repositories of monolithic applications. In those cases, try to switch off the rules that generate issues for almost every file in the repo or try to change the threshold if there is one. To see what rules generate the majority of issues, go to the issues list in the project and open the “Rule” filter.
For example, if you have 1,000 source files in your repo and SonarQube shows the error message "line too long, more than 80 chars" on each line, it's unlikely that anyone will take the time to fix this. It's better to disable the rule or change its threshold. The point is to leave unique issues only, meaning those that relate to some repository files but not to all of them. Be sure to inform the development team of any rules that you switched off or changed in case they need them in the future.
Ask the development team to review found blockers and switch off the rules for those that won’t be fixed, then ask them to fix the rest. In addition, ask to review blocker rules switched off by default – the developers may want to switch some of them back on. Agree on what blockers are no longer allowed in the main branch. To do this, add the “Blocker issues is greater than 0” condition to the quality gates. If a blocker appears in the main branch, the build will fail. If a blocker is found in the pull request, its verification will fail as well. If possible, block the merge button in case of a failed check.
Once blockers are covered, you can run the same iteration for criticals, majors and so on. Then, you can suggest that the development team keep code coverage at a certain level by adding a respective condition to the quality gates.
If new active and inactive rules appear after an update of the plugins, don't forget to ask the development team to review them in case they need to turn any rules on or off.
In the pipeline, you might notice a “Comment_Severity” parameter. This parameter sets minimal severity of issues to be followed with inline comments (e.g. critical+ or major+). If you have many issues in the main branch, don’t set this parameter to “Minor” or “Info,” otherwise, there will be hundreds of minor issue comments in every pull request. For example, if you are using a blockers iteration, set this parameter to “Critical.” This will make sure blockers are commented and not allowed while the criticals will still be allowed and commented.
One final piece of advice: Use SonarQube to not only check the development team’s code in the backend and frontend, but also DevOps code as well. You can use Python, Groovy, Ansible and ShellCheck plugins with this.
Special thanks to Alena Kalionava and Ivan Bogomazov for contributing to this article.