Using SonarCloud with Travis CI to measure and continuously improve code quality
I installed SonarCloud recently on my local environment and started to use it for all my new projects. And then I decided to add it in my CI process.
It’s an online tool that analyzes the quality of your source code to detect bugs, vulnerabilities and code smells throughout the development process.
I appreciate the ease to install and run. It’s free for open source projects. The configuration is very simple with just a sonar-project.properties file to include in the root folder.
Following this tutorial requires a Github account.
Simplest example of sonar-project.properties
sonar.projectKey=your.project.key
sonar.projectName=Project Name
# =====================================================
# Meta-data for the project
# =====================================================
sonar.links.homepage=https://github.com/username/project-repo
sonar.links.ci=https://travis-ci.org/username/project-repo
sonar.links.scm=https://github.com/username/project-repo
sonar.links.issue=https://github.com/username/project-repo/issues
# =====================================================
# Properties that will be shared amongst all modules
# =====================================================
sonar.host.url=https://sonarcloud.io
sonar.organization=username-github
sonar.login=xxxxxxxxxxxxxxxxxxxxxx
sonar.sources=src
sonar.exclusions=node_modules/**/*
# =====================================================
# Java config
# =====================================================
sonar.java.source=1.8
sonar.java.binaries=.
- Be sure SonarQube Scanner is installed if you want to run it locally.
(You could have to export path with something likeexport PATH=/Users/Shared/sonar-scanner-3.0.3.778/bin:$PATH
) - Launch the analysis with
sonar-scanner -X -Dsonar.projectVersion=1.0.0
Note that -D
option defines a property. Here I decided to define it when I run the command because I update the version regularly . The -X
option executes debug output.
- More information about Sonarcloud configuration here.
- More information about analyzing with SonarQube Scanner here.
Lauching the analysis with Travis
Fortunately the documentation from Travis-ci is very clear. You need to add addons to your .travis.yml file and run sonar-scanner
in the ‘scripts’ part of the config to trigger the analysis. It requires a secure token you’ll get with travis encrypt
Create a user authentication token for your account on SonarCloud.
Encrypt this token
travis encrypt abcdef0123456789
or defineSONAR_TOKEN
in your Repository SettingsFind which SonarCloud.io organization you want to push your project on and get its key
Here is an example:
language: node_js
node_js: '8'
cache: yarn
addons:
sonarcloud:
organization: "proustibat-github"
token:
secure: "0.............="
install:
- yarn install
script:
- yarn build
- sonar-scanner
Isn’t simple? Tell me in the comments if you have any issues. I may have encountered the same than you.
Automatically getting the current project version
Launching analysis with the projectVersion property
This above example works if the projectVersion property is defined in the sonar-project.properties file. If you don’t want to define it in the properties file, you could just change the command to run by Travis in the .travis.yml as follows:
script:
- yarn build
- sonar-scanner -X -Dsonar.projectVersion=1.0.0
But wouldn’t it be better if we could automate that?
I mean something like using the version of our package.json file for example.
We know we can use custom scripts with Travis. So we can read the package.json file to get the current version of our project, then run sonar-scanner
with the right -Dsonar.projectVersion
value.
Here is a bash script that reads the package.json, gets the version and launch the sonar scanner:
#!/bin/bash
function readJson {
UNAMESTR=`uname`
if [[ "$UNAMESTR" == 'Linux' ]]; then
SED_EXTENDED='-r'
elif [[ "$UNAMESTR" == 'Darwin' ]]; then
SED_EXTENDED='-E'
fi;
VALUE=`grep -m 1 "\"${2}\"" ${1} | sed ${SED_EXTENDED} 's/^ *//;s/.*: *"//;s/",?//'`
if [ ! "$VALUE" ]; then
echo "Error: Cannot find \"${2}\" in ${1}" >&2;
exit 1;
else
echo $VALUE ;
fi;
}
VERSION=`readJson package.json version` || exit 1;
sonar-scanner -X -Dsonar.projectVersion=$VERSION
Just add it in a sonar.sh file then change the script part of your .travis.yml as follows to run this script rather than running directly the sonar-scanner command:
script:
- yarn build
- bash sonar.sh
That’s all. You now can push your project and just wait for the end of the Travis build to look at the results in your Sonarcloud dashboard at https://sonarcloud.io/dashboard?id=your.project.key.
Bonus
Display the Quality Gate badge on your Readme:
[![Quality Gate](https://sonarcloud.io/api/badges/gate?key=your.project.key)](https://sonarcloud.io/dashboard/index/your.project.key)
A lot of badges with different measures are available:
[![Comments (%)](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=comment_lines_density)](https://sonarcloud.io/component_measures?id=your.project.key&metric=comment_lines_density)[![Open issues](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=open_issues)](https://sonarcloud.io/component_measures?id=your.project.key&metric=open_issues)[![Code smells](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=code_smells)](https://sonarcloud.io/component_measures?id=your.project.key&metric=code_smells)[![Technical debt](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=sqale_index)](https://sonarcloud.io/component_measures?id=your.project.key&metric=sqale_index)[![Bugs](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=bugs)](https://sonarcloud.io/component_measures?id=your.project.key&metric=bugs)[![Reliability remediation effort](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=reliability_remediation_effort)](https://sonarcloud.io/component_measures?id=your.project.key&metric=reliability_remediation_effort)[![Coverage](https://sonarcloud.io/api/badges/measure?key=your.project.key&metric=coverage)](https://sonarcloud.io/component_measures?id=your.project.key&metric=coverage)
More information about the API: https://github.com/QualInsight/qualinsight-plugins-sonarqube-badges/wiki/Quality-Gate-status-badges