Hello,
I’m trying to configure a project on SonarQube, it works for the majority of what I expect but for some cases, I can’t manage to make it work as expected.
The project is a Java project, using maven and we also use Gitlab + Jenkins, with Jenkins launching the sonar analysis. On SonarQube side, we are using Enterprise Edition v9.9.7 (build 96285) (no idea how it is deployed, it is managed by our devops team).
We can here consider that we are running something like a GitlabFlow (feature branches are merged into the main branch and we have long-living branches for our different releases)
How I wish it would work:
if the pipeline is running on the main branch (for example called “develop”), the new code should be defined as all the code modified since the last release. For example, the branch of the last released branch could be something like “release/6.0.0”. (note: I find it easier to specify the reference branch in order to not rely on the version number in our pom.xml)
if the pipeline is running on any another branch, the sonar analysis should be on the new code, the reference being the main branch
if the pipeline is running on a Merge Request, the analysis should be on the new code, the new code being only the files modified in the MR
My issue is that it does not work like this today. The results I have now are:
For the MR, it seems to work well: I’m providing the MR key, the pullRequestBase, the pullRequestBranch and I get the analysis on the code modified/added in the MR (+ the comment on the MR with the analysis results)
For the main branch (called “develop” here), I get the analysis and the comment telling me that it was “Compared to release/6.0.0”. However, the new code corresponds only to the new code since the previous similar analysis: the code added in MR that were merged before the previous analysis are not considered any more as “new code”!
For the last case, I’m not even sure how to test it… Just by pushing a new feature branch not linked to any MR yet?
The issue is then probably somewhere between the parameters of the project and branches on SonarQube and the parameters of the call to the sonar maven plugin in my Jenkinsfile.
On SonarQube side, all is configured to use the previous version option.
I tried many options but the current configuration (not considering the MR) in the Jenkinsfile is the following:
String sonarOptions = "-Dsonar.newCode.referenceBranch=${targetBranch} " +
"-Dsonar.scm.provider=git"
if (currentBranch == MAIN_BRANCH) {
// On the main branch, we specify the current version
sonarOptions += " -Dsonar.projectVersion=${pomVersion}"
}
echo "Sonar analysis on branch ${currentBranch} (target=${targetBranch})"
sonar {
branch = currentBranch
jdk = JDK_VERSION
mavenVersion = MAVEN_VERSION
options = sonarOptions
}
targetBranch is defined as the last release branch (for example “release/6.0.0”) found in the repository using a pattern in the case of the main branch, or the main branch in the case of any other branch.
The sonar method then calls the sonar maven plugin with the specified options and with -Dsonar.branch.name=${branch}.
I feel like I should not have to provide any version number since I want sonar to compare the main branch to a specific branch regardless of its pom version but I didn’t find the right way to make it work. I also feel like some parameters might be useless (like “-Dsonar.scm.provider=git”).
My question is: how can I fix my Jenkinsfile and SonarQube configuration to make it work as expected, with a Jenkinsfile as clean as possible?
Thanks in advance for you help! And I hope this issue is in the right place
This is correct for how you want the main New Code definition to work.
What’s in the pomVersion? Does it include the build number? If so, you’re resetting New Code with each new analysis.
In the UI, at the project level, edit main’s New Code definition to be previousVersion, and then set the project-level New Code definition to be relative to main. And that’s it. You don’t have to juggle a lot of extra settings.
What’s in the pomVersion? Does it include the build number? If so, you’re resetting New Code with each new analysis.
The version specified in our pom is “only” the X.Y.Z-SNAPSHOT version (the -SNAPSHOT being optional but almost always present). There is no build number specified in the pom.
Should I just remove this option and let SonarQube handle everything?
By any chance, is there any way to “fix” where the new code should start/new version is defined for SonarQube, by giving it a commit id or something like this? Maybe on SonarQube directly?
Since I used the sonar.projectVersion option before, it might have interfered in SonarQube’s usual operations
In the UI, at the project level, edit main’s New Code definition to be previousVersion, and then set the project-level New Code definition to be relative to main. And that’s it. You don’t have to juggle a lot of extra settings.
Ok, I’ll do this
Then I just have to call sonar:
without a sonar.branch.name specification for the main branch
To be super-explicit: that value does not change from build to build to build?
If it’s 4.8.32-SNAPSHOT in the morning, it’s still 4.8.32-SNAPSHOT in the evening after 30 builds or so?
It’s possible to fix a specific analysis as the baseline using the API. Alternately, you can use the UI to alter analyses’ versions (version event). But assuming your sonar.projectVersion string doesn’t change with each build it may be easier to just stick with the previousVersion setting.
You shouldn’t need to do that either. It should be picked up automatically from the build env.
Then I’ll try to just call sonar via the mvn method with only the jdk and mavenVersion parameters specified.
Honestly it’s still a work in progress because our workflow git and how SonarQube was configured wasn’t coherent.
Historically, the project followed the “traditional” GitFlow, so it had a master branch (with each commit being a release merged into the branch) and a developpement branch (were all feature branches were merged). However on SonarQube, master was still configured as the main branch while developpement wasn’t even configured as a long-living branch.
Moreover, master has been abandoned since 2022 and for some reason no more analysis were launch on developpement until recently so the history on develop analysis was lost on SonarQube.
And all of this happened before I arrived on the project so it’s a bit complicated to sort everything out!
Here is the left panel of the Analysis tab for the master branch:
What I don’t understand, is that no commit has been made on master since 2022 so no idea how these analysis appeared.
If I go back in the history, it gets even more complicated with some back and forth version changes:
We are going to clean our workflow git tomorrow, probably by merging developpement into master and using master as our unique long-living branch in order to simplify things.
By any chance, is there a way to change the main branch on SonarQube? If so, we would use a main branch but if not, we’ll stay on master. I searched a bit and found that the feature might be available in the UI since SonarQube v10.2? However we are waiting for the LTS version (10.9 probably?) to update so if there is any other way, I’ll take it
sorry for this mess, it’s not easy to clean a whole pipeline
Yes, I’ll let you know as soon as some tests are done
Hum I don’t find this option
When I click on the gear button on the right, I only get “delete branch” option
(I’m on Enterprise Edition v9.9.7 (build 96285))
Or should I use the “rename branch” option that I have on master?
Yesterday, we decided as I expected to change our main branch back to master. Therefore, we merged developpement into master and rebased our existing MR branches + changed the MR target branches from developpement to master.
On SonarQube side, I change the properties this way:
The problem is: since we merged, the analysis on Merge Requests seems to be incorrect again (while it was ok before the merge).
For example, I made a MR with a fix in the pom.xml (and only this) by creating a new branch from master (after the merge).
I wonder if SonarQube bases its analysis on the last analysis made on the target branch?
If so, that’s a bit strange since, in the MR, we can be a bit late compared to the target branch (as in new commits could have been made on it and not yet ported back in the MR) Is it not supposed to get only the files modified in the MR somehow?