Table of Contents

SonarQube Code Quality

Author : Paddy Murphy
Date : 2017-05-03

What is it?

SonarQube is an open source tool which gives a snapshot of code quality. It uses the following quality metrics:

It consists of two components a SonarQube server which displays the the results and a SonarQube scanner which carries out the code analysis.

Where is it installed?

The SonarQube server is currently installed on the erato server. View dashboard at: http://10.91.100.111:9000/sonar/dashboard/

Log in with the usual credentials, the home page displays a list of projects that have been analysed.

How to Install SonarQube Server on Ubuntu

SonarQube requires Java 8 and MySQL – 5.6 or greater


#sonar.web.host=0.0.0.0
#sonar.web.context=
#sonar.web.port=9000

Add the following values:
sonar.web.host=<server ip address>
sonar.web.context=/sonar
sonar.web.port=9000

Start Application

Add sonar database
By default SonarQube uses the H2 database engine. This is not suitable for a production instance.
Ensure that a MySQl version 5.6 or greater is installed.


#sonar.jdbc.username=
#ssonar.jdbc.password=

Change values:
#sonar.jdbc.username=root
#ssonar.jdbc.password=ozzrules

If everything is configured correctly the dashboard page should display when SonarQube is restarted.

Troubleshooting on erato server

Logs can be viewed at: /opt/sonar/sonarqube-5.6.4/logs/sonar.log

Stop application

Restart Application

Sonarqube won't start with ElasticSearch exceptions in the log

Jenkins 2 Integration

Install the Jenkins SonarQube plugin

Add SonarQube Server

See Setting up SonarQube in Jenkins 2

Add SonarQube scanner

Add SonarQube Scanner build step to Grails 2 Project

As this build step can take some time on larger projects this build step should be last.

# must be unique in a given SonarQube instance
sonar.projectKey=com.errigal.reporting-manager
# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=reporting-manager
sonar.projectVersion=1.0
 
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# Since SonarQube 4.2, this property is optional if sonar.modules is set. 
# If not set, SonarQube starts looking for source code from the directory containing 
# the sonar-project.properties file.
sonar.sources=.
 
# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8

# Exclude files from SonarQube analysis
sonar.exclusions=src/templates/artifacts/**, web-app/js/prototype/**
# Language
#sonar.language=grvy

SonarQube Scanner Build Example

# Groovy 
sonar.language=grvy

# Java 
sonar.language=java

# JavaScript
sonar.language=js

Grails 3 Projects
Grails 3 projects use the Gradle build system.
See the Alarm-cache Project for an example of grails 3 and SonarQube integration (http://10.91.100.112:8080/job/alarm-cache/):

build.gradle

  dependencies {
    classpath "org.grails:grails-gradle-plugin:$grailsVersion"
    classpath "org.grails.plugins:hibernate5:${gormVersion - ".RELEASE"}"
    classpath "org.grails.plugins:views-gradle:1.1.6"
    classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.3"
  }
}
... 

apply plugin: "jacoco"
if (JavaVersion.current() == JavaVersion.VERSION_1_8) {
  apply plugin: "org.sonarqube"
  //Define sonar url and login token for all sub project
  //https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Gradle#AnalyzingwithSonarQubeScannerforGradle-AnalyzingMulti-ProjectBuilds
  sonarqube {
    properties {
      property "sonar.host.url", "http://10.91.100.110:9000/sonar"
      property "sonar.login", "cf6a76dc8f93946096c8c21e746e249e53d619dc"
    }
  }
}

Jenkinsfile.groovy

#!groovy
// Define versioning strategy
versionNumber = "0.1.0." + currentBuild.number
currentBuild.displayName = versionNumber
// ID of the Jenkins credentials for interaction with BitBucket
bitbucketCredentialsId = 'bitbucket'
// The hostname/path part of the git URL
repoLocation = 'bitbucket.org/errigal/alarm-cache.git'

...

stage('Unit Test') {
    try {
      sh './gradlew test --continue'
    } finally {
      // Archive test result so they are browsable from Jenkins
      step([$class: 'JUnitResultArchiver', testResults: '**/build/test-results/test/*.xml'])
    }
  }

  stage('Integration Test') {
    try {
      sh './gradlew integrationTest --continue'
    } finally {
      // Archive test result so they are browsable from Jenkins
      step([$class: 'JUnitResultArchiver', testResults: '**/build/test-results/integrationTest/*.xml'])
    }
  }

  stage('Coverage') {
    try {
      sh './gradlew jacocoTestReport'
    } finally {
      // Archive coverage result so they are browsable from Jenkins
      step([$class: 'JacocoPublisher'])
    }
  }

  stage('SonarQube') {
    sh "./gradlew sonarqube -Dsonar.projectVersion=$versionNumber"
  }
}

Jenkins 2 & Grails 3 integration