Automate SonarQube analysis with Bitbucket Pipelines and Maven

Search for a command to run...

No comments yet. Be the first to comment.
In this series I'll explain everything you need to start a SonarQube static analysis of your code
How do we know if the code we write is good enough? Error free? Not vulnerable? Not smelly? There are some tools that can show you that, and today I'm writing about SonarQube. But, since I like the approach with minimum steps required, I'll write ju...
I transformed entries from multiple categories into ones with single category and multiple tags

Notion is more and more popular these days. Also, the number of people who are collecting and organizing resources is rising. So, if you have something valuable that people want, why not selling it? https://twitter.com/brunoraljic/status/138277860789...

You might ask yourself how writing blog posts can help you become a better colleague? Well, writing can help you with several things. First of all, it makes you think more about the topic. Upfront. Before communicating. It also helps you articulate y...

Junior developers will often tell you they are afraid of talking to a customer. They are aware of that and their personal development plan will often include this: 🗯 "I want to improve my communication with clients" But how can one "improve commun...

2020 was not that bad for me. This is one of those "years in recap" posts. Let's rewind and go back to Oct 2019. This is how the story starts... It's also a post for those who want to get to know me better. (very long wall of text ahead, be warned) ...

In this article we'll see how to set up automated SonarQube analysis, that will be executed every time we push to the remote. For the simplicity of the article, let's say we have a pipeline job with two steps, build and analyze.
If you followed previous two blog posts (links at the bottom) in this series, you'll see we are working with maven project, so the pipeline here will be to:
clean install andWe will make sure to apply some caching, but also to save some time by passing artifacts from one pipeline step to another.
We can do analysis manually on our machines. But it's better to set it up automatically. There are several reasons and I'll name only a few. The first one is -> Machine won't forget to do it. And if we agree on some level of quality, it will prevent us submitting bad code to the production.
Of course, it will free our machine from doing it, and in the end, we can centralize the output reports so everyone in the team can have easy access.
As stated above, we will be using a pipeline with two steps, build and analyze.
definitions:
steps:
- step: &build
name: Maven Build
caches:
- maven
script:
- mvn clean install
artifacts:
- target/site/**
- target/classes/**
Few things to mention here
&build, we can name a step and reference it on several places in your yml file. Build step is nice example, since it usually appears in both staging and production pipelines. Please note, this is under definitions->steps. This is where it's possible to define a step, give it a name and reuse it later. We'll see the pipeline part at the bottom of the articleartifacts -> target/site/** Artifacts can be stored and reused in another steps within the same pipeline. We put everything below target/site for one reason: this is the location of our line coverage report that Sonar will use in the next step.target/classes/** Sonar will use this directory to execute analysis based on the classes we have here. They will be created after our mvn clean install. Consider this and previous artifact as something that we will reuse in the next step. - step: &sonar
name: Analyze code with Sonarqube
caches:
- maven
script:
- mvn sonar:sonar -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_API_TOKEN
caches -> maven, Bitbucket implementation to speed up consequent maven builds. Same like in the previous step. $SONAR_HOST_URL and $SONAR_API_TOKENI want to show here something from a pipeline log that might not be obvious from this step alone.
Artifact "target/site/**": Downloading
Artifact "target/site/**": Downloaded 132.9 KiB in 0 seconds
Artifact "target/site/**": Extracting
Artifact "target/site/**": Extracted in 0 seconds
Artifact "target/classes/**": Downloading
Artifact "target/classes/**": Downloaded 9.4 KiB in 0 seconds
Artifact "target/classes/**": Extracting
Artifact "target/classes/**": Extracted in 0 seconds
Cache "maven": Downloading
Cache "maven": Downloaded 207.8 MiB in 3 seconds
Cache "maven": Extracting
Cache "maven": Extracted in 1 seconds
Artifact and cache are downloaded during the step setup phase at the very beginning. What does this mean for our mvn sonar:sonar? Well, we don't have to run mvn install or mvn test one more time for our sonar step. We already have files that are generated in the first step, and we saved ourselves some time on the Bitbucket pipeline execution.
<properties>
...
<sonar.projectKey>hashnode-blog-showcase</sonar.projectKey>
<sonar.java.binaries>target/classes</sonar.java.binaries>
</properties>
We can define sonar properties in the pom.xml file. Here we provided project key which is optional. In case it's missing, maven will use groupId or artifactId.
But the other one is important, sonar.java.binaries. Remember we didn't have maven install in our second step. This property will tell Sonar where to look for Java binaries to execute analysis against. Without this, your Sonar step will fail. It will complain it don't know what to analyze.
So, this works together with the artifact from the step one, target/classes.
Setting SonarQube to work with Bitbucket is easy, since we already have Maven. Sonar plugin will execute analysis with one line command. However, we need to setup things like where the binaries are, and we also set up few things that will reduce the amount of time the pipeline is running. Communication to the Sonar server is configured via Bitbucket repository variables.
This configuration will execute sonar analysis on every push to remote branch, which can then give you incremental reports on your code. I won't go into too much details about setting up the Bitbucket Pipeline, as it can be the topic for itself.
Also, the pipeline part of the yml file, as promised above:
pipelines:
default:
- step: *build
- step: *sonar
We can see how it's clear and simple, as we only need to reference the steps.
Alright, thanks for reading!