How do you prefer to set configurations?

Some analysis properties, such as sonar.projectVersion have to be set in a properties file (sonar-project.properties) or on the command line. Some, such as exclusions, can be set in the UI. And some, think Quality Profiles & Quality Gate, have to be set in the UI.

Where you have a choice, what do you choose, and why?

What’s your ideal state for setting analysis-level (project-level… global) properties?

1 Like

We have several repositories using Sonar. We prefer to use the UI for configuration the least possible and prefer Configuration as Code as much as possible. Things like Quality Gates and other Org level settings, we do configure from the UI, but for project specific stuff we absolutely avoid the UI.

Most of our repos will have a standard sonar-project.properties file on the command line and that property file has some values that can come from environment variables.

For example:

sonar.projectKey = ${env.SONAR_PROJECT_KEY}
sonar.organization = ${env.SONAR_ORGANIZATION}

sonar.projectVersion = ${env.PROJECT_VERSION}
sonar.projectBaseDir = ${env.WORKSPACE}
sonar.sources = ${env.WORKSPACE}
sonar.tests = ${env.WORKSPACE}
sonar.sourceEncoding =  UTF-8

sonar.exclusions = \
  ${env.SONAR_ADDITIONAL_EXCLUSIONS},\
  build/**,\
  **/vendor/**

sonar.coverage.exclusions = \
  ${env.SONAR_ADDITIONAL_COVERAGE_EXCLUSIONS},\
  test/**,\
  **/test/test_*.py

The script that calls sonar runner can then set these environment variables as needed per project and some of the values can be set automatically such as the project base on the current git information for example.

This is better than ending up with an extremely long list of command line options.

The shell script will typically be (assumes running from Jenkins):

#!/bin/bash

export TEST_REPORTS_DIR=build/test_reports
if [[ $CHANGE_ID ]]; then
    # For PRs the head of the branch before the local merge is what we are looking for.
    git log HEAD@{1} -1 -q | head -1 | cut -f 2 -d' '
    sonar_args=(
        "-Dsonar.pullrequest.key=$CHANGE_ID"
        "-Dsonar.pullrequest.base=$CHANGE_TARGET"
        "-Dsonar.pullrequest.branch=$CHANGE_BRANCH"
        "-Dsonar.scm.revision=$(git log HEAD@{1} -1 -q | head -1 | cut -f 2 -d' ')"
    )
else
    branch="$(echo $GIT_BRANCH | sed -e 's|^origin/||')"
    sonar_args=("-Dsonar.branch.name=$branch")
fi

# This assumes the url is in this format: https://github.com/<org>/<repo>.git
org="$(cut -d/ -f4 <<< "$GIT_URL")"
repo="$(cut -d/ -f5 <<< "$GIT_URL")"
export SONAR_ORGANIZATION="${org}"
export SONAR_PROJECT_KEY="${org}_${repo%.git}"

echo "GIT_URL: ${GIT_URL}"
echo "SONAR_ORGANIZATION: ${SONAR_ORGANIZATION}"
echo "SONAR_PROJECT_KEY: ${SONAR_PROJECT_KEY}"

export SONAR_SCANNER_OPTS='-Xms250m -Xmx250m -XX:+UseG1GC -XX:+CMSClassUnloadingEnabled -XX:+UseCompressedClassPointers -XshowSettings:vm'
sonar-scanner "${sonar_args[@]}"

This approach allows us to create new repos with sonar support with minimal manual tuning.

5 Likes