is the cloud offering of It offers code quality and security scanning, to help developers build maintainable and secure applications. Typically developers install a 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 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.

analyze projects
Figure 1. Analyze projects from GitLab organization

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.

Figure 2. SonarCloud project 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.

Listing 1. Add pluginGroup to Maven settings.xml
<settings xmlns="" xmlns:xsi=""

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.

Listing 2. Define sonar.organization in pom.xml

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.

Listing 3. Analyze main project branch
export SONAR_TOKEN=paste_token_here (1)
export SONAR_HOST_URL= (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:

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

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.

Listing 4. GitLab CI build step for Sonar analysis
  GIT_DEPTH: "0"

# Sonar analysis for main/master branch and pull request based on environment variables
  stage: test
      - master
      - main
      - merge_requests (1)
    changes: (2)
      - src/**/*
    key: "${CI_JOB_NAME}"
      - .sonar/cache
    - './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.

connectivity management
Figure 3. GitLab Connectivity management

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.

Figure 4. Merge request decoration example

This ensures your projects do not pick up any new findings as your team makes further changes.


Tested with

  • GitLab 15.1

  • SonarScanner 3.9.1

  • Maven 3.8.6

  • Java 17