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.

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 define SONAR_TOKEN in your Repository Settings

Find 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

--

--