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.
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.
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
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"
}
}