SonarCloud merge request decoration on GitLab.com
Sonarcloud.io is the cloud offering of SonarQube.org. It offers code quality and security scanning, to help developers build maintainable and secure applications. Typically developers install a SonarLint.org plugin in their IDE, for direct feedback. Merge request decoration acts as second line of defence, to ensure no new findings make it past the merge or pull request review.
This blogpost walks you through the steps to setting up Merge request decoration on GitLab.com for Apache Maven projects. There’s a few gotcha’s around setting up merge request decoration, which could lead you to threads like these to debug what you did wrong.
Import projects into SonarCloud
You will want to import your projects through the import option for GitLab organizations. You likely need to login to SonarCloud through GitLab, if you haven’t already.
Most importantly, do not import your projects by hand, or through a (too early) Sonar analysis, as analysis will then still work, but merge request decoration will not.
If you imported your project correctly, they should show up in SonarCloud as being bound to GitLab.
Configure project pom.xml
You will want to configure your SonarScanner plugin for Maven.
You can define the plugin group in our Maven settings.xml
, to allow you to use the shorthand sonar:sonar
goal, rather than the longer org.sonarsource.scanner.maven:sonar-maven-plugin:<version>:sonar
variant.
<settings xmlns="http://maven.apache.org/SETTINGS/1.1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.1.0 http://maven.apache.org/xsd/settings-1.1.0.xsd">
<pluginGroups>
<pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
</pluginGroups>
<servers>
<server>
<id>gitlab-maven</id>
<configuration>
<httpHeaders>
<property>
<name>Job-Token</name>
<value>${CI_JOB_TOKEN}</value>
</property>
</httpHeaders>
</configuration>
</server>
</servers>
</settings>
By adding the sonar.organization
to the project pom.xml
file, the SonarScanner for Maven will pass this parameter to SonarCloud.
If you add this property to a shared parent pom.xml
, then any projects that inherit from this shared parent will not have to redefine the property.
<properties>
<sonar.organization>acme</sonar.organization>
</properties>
Onboard main project branches
Before SonarCloud can analyze branches or merge requests, it first needs to analyze the main project branch. You can run the below command for any project you want to onboard.
export SONAR_TOKEN=paste_token_here (1)
export SONAR_HOST_URL=https://sonarcloud.io (2)
./mvnw compile sonar:sonar -Dsonar.projectKey=ACME_pending-deployments (3)
1 | Generate a personal access token for SonarCloud |
2 | Ensure the scanner connects to SonarCloud, not the default localhost |
3 | Substitute your sonar.projectKey , which is shown in the SonarCloud project URL, and composed of your top level GitLab organization and project name. |
After running the above command you should see some preliminary analysis of your projects in SonarCloud.
Configure GitLab CI environment variables
Once the main branch has been analyzed, you can configure GitLab CI environment variables.
We will use three environment variables, which for ease of use are added to the GitLab organization at: https://gitlab.com/groups/ACME/-/settings/ci_cd
That way we only have to define these once for the entire organization, rather than per project.
First add an environment variable for the Maven settings.xml
named SETTINGS_XML
.
The Type will be set to File
, and there’s no need to protect or mask the value.
The value is the full settings.xml
content shown above.
Secondly add a SONAR_HOST_URL
environment variable.
The Type will be set to Variable
, and the value will be set to https://sonarcloud.io
.
Thirdly add a SONAR_TOKEN
environment variable.
The Type will be set to Variable
, and the value is the same as the personal SonarCloud token added above.
Then enable the option to mask the variable in the job logs, but do not protect the variable, as it is needed on all branches.
Configure project CI pipeline
With the environment variables in place, we can now add the required CI step to actually invoke the SonarScanner for Maven.
Add the below step to your project .gitlab-ci.yml
, or preferably to a shared CI template file that you import.
variables:
# https://docs.sonarcloud.io/advanced-setup/ci-based-analysis/gitlab-ci/
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
GIT_DEPTH: "0"
# Sonar analysis for main/master branch and pull request based on environment variables
sonar_analysis:
stage: test
only:
refs:
- master
- main
- merge_requests (1)
changes: (2)
- src/**/*
cache:
key: "${CI_JOB_NAME}"
paths:
- .sonar/cache
script:
- './mvnw $MAVEN_CLI_OPTS verify sonar:sonar -Dsonar.projectKey=ACME_$CI_PROJECT_NAME -s $SETTINGS_XML' (3)
There’s a number of small tweaks as compared to the reference documentation.
1 | This is where the magic happens; Merge request pipelines contain additional environment variables. These are picked up by the SonarScanner to allow for merge request decoration. |
2 | Only run this step when there are changes to the application sources; that way Renovate or Dependabot merge requests are not analyzed, as they are unlikely to produce new SonarCloud findings. |
3 | Define the sonar.projectKey as part of the command, rather than inside the pom.xml file. This allows for less duplication, especially when using a shared parent pom.xml and CI templates. |
Configure SonarCloud connectivity token
For SonarCloud to be able to post merge request decorations back to GitLab, it needs a token with the appropriate access. Follow the instructions in SonarCloud to add a proper token with the correct project access and scope.
Merge request decoration
With all of the above in place, you should now start to see merge request decoration comments added to your merge requests.
This ensures your projects do not pick up any new findings as your team makes further changes.
Versions
Tested with
-
GitLab 15.1
-
SonarScanner 3.9.1
-
Maven 3.8.6
-
Java 17