Every app that we develop at Macoscope is built on CI, while Code Review is an inherent part of our creative process. This allows every member of the team to quickly figure out how some new portion of code was implemented and point out what’s wrong with the code and how it can be improved. Another thing that helps produce high quality code is static code analysis. It looks for patterns in code (using a pre-defined set of rules) that can cause bugs and result in security vulnerabilities.

For developers, static code analysis is most helpful when it is an essential part of the code review process. Under such an approach, every pull request is automatically analyzed and potentially incorrect parts of the code are commented. In this short blogpost, we describe how you can implement that approach by integrating SonarQube with Jenkins CI and GitHub for an Android project.

We assume that a Jenkins instance, the Android project, and a GitHub repository are already configured. We will be running both the Jenkins and the SonarQube servers on our local machine.

Installing the SonarQube Server and Plugins

Installation and Configuration

Download the SonarQube archive and extract it. We only need SonarQube’s analysis capabilities to check pull requests, so we’re fine with an embedded database. (Instruction on how to configure SonarQube with other databases, like MySQL, can be found here). Open the $SONAR_HOME/conf/sonar.properties file and uncomment the embedded database:

#----- Embedded Database (default) #H2 embedded database server listening port, defaults to 9092 sonar.embeddedDatabase.port=9092

Starting the Server

Now we can run the SonarQube server:

$SONAR_HOME/bin/macosx-universal-64/./sonar.sh start

By default, it’s launched on port 9000 and the Web panel is available at localhost:9000 . The Java analysis plugin is installed by default, but we also want to check for Android-specific rules, so we have to install the Lint plugin. To do so, go to Administration -> System -> Update Center , then search for and install the Android plugin.

Configure Quality Profiles

The next thing to do is to define the Quality Gate that will include both default SonarQube Java and Android Lint quality rules. This step is necessary because SonarQube doesn’t support analyzing with multiple profiles. As described in a Stack Overflow thread, the fastest way of doing that looks something like this:

Go to the Quality Profiles tab, Back up both Sonar Way and Android Lint profiles. This will download an .xml file for each profile, Create a new XML file containing rules from both profiles. We can modify all rules to fit our individual needs for the project, In the SonarQube Quality Profiles tab, click Restore Profile and upload the newly created XML file,

Set the restored profile as the default one so it will be used for every new project.

Configure Jenkins

We want to use Jenkins CI to trigger code analysis for new pull requests and to publish the results of the analysis as comments in the GitHub code review flow. To do that, we first need to configure a couple of things.

Build Project on Pull Request

We want to build our project and run the analysis on every pull request, so we have to start by configuring the GitHub Pull Request Builder plugin. When configuring a new Job, the first order of business is checking GitHub project and setting the GitHub Project URL . Then, under Source Control Management, you should set following parameters:

GitHub Repository URL (.git)

Name

Refspec -> +refs/pull/*:refs/remotes/origin/pr/*

Branch Specifier -> ${sha1}

Under Build Triggers, enable GitHub Pull Requests Builder . In Admin List , we can specify accounts whose pull requests will trigger the Jenkins build. But if we want to run the Job for every pull request, we can check Build every pull request automatically without asking instead.

Configure the SonarQube Plugin

After installing the SonarQube plugin, go to the SonarQube servers section in Manage Jenkins -> Configure System and provide the Name and the Server URL (in our case http://localhost:9000 ).

Configure the Job Build

If we want SonarQube to use Android Lint, we have to call the proper gradle task. In the Job Build section, add an Execute shell build step with the parameter:1

./gradlew lintDebug

Instead of lintDebug , you can use any other build type name ( lintBuildTypeName ) defined in project build.gradle .

The next step is to add SonarQube scanner and set Analysis properties

sonar.projectName="Project Name" sonar.version="1.0" sonar.sources=path to java sources, eg. app/src/main/java/ sonar.java.binaries=path to java binaries, eg. app/build/intermediates/classes/dev/ sonar.android.lint.report=path to lint-results.xml, eg. app/build/outputs/lint-results.xml sonar.scm.provider= git sonar.java.source=7 sonar.projectVersion=1.0 sonar.github.repository=organisation/ProjectName (Github repository) sonar.github.pullRequest=${ghprbPullId} sonar.analysis.mode=preview sonar.github.oauth=Insert Github oAtuh token here

${ghprbPullId} is a pull request id variable returned by the Pull Request Builder plugin. An OAuth token for sonar.github.oauth can be generated in the GitHub account settings, as described on GitHub’s help page. It’s a good idea to use Jenkins’s Mask Password Plugin for storing this token, so it won’t be visible in logs.

Now, every new pull request should be automatically analyzed and portions of the code that don’t meet the pre-defined rules should be commented. Below is an example of a pull request analysis result.

Static Code Analysis as a Time-Saver Method

In this post we described how to integrate SonarQube, a static code analysis tool with Jenkins CI and GitHub to improve the Code Review process. It automatically checks the code for faults like code repetition, unhandled exceptions, empty methods, etc. Using this approach, developers tasked with checking pull requests can focus more on how the code actually works instead of looking for every little mistake that appeared in the code along the way.

Got inspired? E-mail us and we’ll get in touch to find out how our design and development services can drive business value for you.