Skip to content

Commit cb2e678

Browse files
committed
Merge branch 'release/4.2.0'
2 parents 6728b4e + f4dff8f commit cb2e678

File tree

7 files changed

+85
-67
lines changed

7 files changed

+85
-67
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
## [Unreleased]
1010

11+
## [4.2.0](https://github.com/cloudogu/ces-build-lib/releases/tag/4.2.0) - 2025-04-02
12+
### Changed
13+
- Removes the default legacy behavior which created a new project in SonarQube for every analyzed branch.
14+
This change uses the [community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin) as default
15+
to create a project for the single artifact id. In this project all analyses of branches and pull requests will be stored.
16+
17+
### Fixed
18+
- [#147] Use dogu v2 api for applying dogus in k3d.
19+
1120
## [4.1.1](https://github.com/cloudogu/ces-build-lib/releases/tag/4.1.1) - 2025-03-11
1221
### Fixed
1322
- [#143] Fix IllegalAccessError when using `GradleWrapperInDocker(..)`

README.md

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -817,13 +817,11 @@ Note that
817817
should be easy, however.
818818

819819
## Branches
820+
By default, the [sonarqube-community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin) is required and used.
821+
The reason for this is that since SonarQube version > 25 analysis with the legacy logic (creating one project per branch) fails
822+
on pull request because SonarQube requires the target branch (e.g. main) in the same project.
820823

821-
By default, the `SonarQube` legacy logic, of creating one project per branch in a Jenkins Multibranch Pipeline project.
822-
823-
A more convenient alternative is the paid-version-only [Branch Plugin](https://docs.sonarqube.org/display/PLUG/Branch+Plugin)
824-
or the [sonarqube-community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin), which has
825-
similar features but is difficult to install, not supported officially and does not allow for migration to the official
826-
branch plugin later on.
824+
A more convenient alternative is the paid-version-only [Branch Plugin](https://docs.sonarqube.org/display/PLUG/Branch+Plugin).
827825

828826
You can enable either branch plugins like so:
829827

@@ -891,17 +889,8 @@ Note that SonarCloud uses the Branch Plugin, so the first analysis has to be don
891889

892890
## Pull Requests in SonarQube
893891

894-
As described above, SonarCloud can annotate PullRequests using the SonarCloud Application for GitHub.
895-
It is no longer possible to do this from a regular community edition SonarQube, as the
896-
[GitHub Plugin for SonarQube](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin) is deprecated.
897-
898-
So a PR build is treated just like any other. That is,
899-
900-
* without branch plugin: A new project using the `BRANCH_NAME` from env is created.
901-
* with Branch Plugin: A new branch is analysed using the `BRANCH_NAME` from env.
902-
903-
The Jenkins GitHub Plugin sets `BRANCH_NAME` to the PR Name, e.g. `PR-42`.
904-
892+
As described above, SonarCloud can annotate PullRequests using the SonarCloud Application for GitHub.
893+
For the regular community edition the [community-branch-plugin](https://github.com/mc1arke/sonarqube-community-branch-plugin) is required.
905894

906895
# Changelog
907896
Provides the functionality to read changes of a specific version in a changelog that is

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
<groupId>com.cloudogu.ces</groupId>
2020
<artifactId>ces-build-lib</artifactId>
2121
<name>ces-build-lib</name>
22-
<version>4.1.1</version>
22+
<version>4.2.0</version>
2323

2424

2525
<properties>

src/com/cloudogu/ces/cesbuildlib/K3d.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,7 @@ class K3d {
403403
void applyDoguResource(String doguName, String doguNamespace, String doguVersion) {
404404
def filename = "target/make/k8s/${doguName}.yaml"
405405
def doguContentYaml = """
406-
apiVersion: k8s.cloudogu.com/v1
406+
apiVersion: k8s.cloudogu.com/v2
407407
kind: Dogu
408408
metadata:
409409
name: ${doguName}

src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,7 @@ class SonarQube implements Serializable {
100100
if (isIgnoringBranches) {
101101
return
102102
}
103-
104-
// Run SQ analysis in specific project for feature, hotfix, etc.
105-
// Note that -Dsonar.branch is deprecated from SQ 6.6: https://docs.sonarqube.org/display/SONAR/Analysis+Parameters
106-
// However, the alternative (the branch plugin is paid version only)
107-
// See https://docs.sonarqube.org/display/PLUG/Branch+Plugin
108-
// An alternative could be this:
109-
// https://github.com/mc1arke/sonarqube-community-branch-plugin
103+
def artifactId = mvn.artifactId.trim()
110104
if (isUsingBranchPlugin) {
111105
mvn.additionalArgs += " -Dsonar.branch.name=${script.env.BRANCH_NAME} "
112106

@@ -116,39 +110,29 @@ class SonarQube implements Serializable {
116110
// Avoid exception "The main branch must not have a target" on master branch
117111
mvn.additionalArgs += " -Dsonar.branch.target=${targetBranch} "
118112
}
119-
} else if (script.env.BRANCH_NAME) {
120-
// From SonarQube 7.9 "-Dsonar.branch" leads to an exception, because it's deprecated.
121-
//mvn.additionalArgs += " -Dsonar.branch=${script.env.BRANCH_NAME} "
122-
// In order to not break behavior of ces-build-lib, we re-implement similar behavior in ces-build-lib.
123-
124-
// Note that the legacy "-Dsonar.branch" resulted in the display name "<maven name> <branch name>"
125-
// We can't do that because the blank sends us to jenkis-shell-quoting-hell.
126-
// Even this didn't help: https://gist.github.com/Faheetah/e11bd0315c34ed32e681616e41279ef4
127-
// So change it to "<maven artifact>:<branch name>", as artifact is not allowed to consist spaces
128-
129-
// We also apply this logic to PRs, since GitHub Plugin is deprecated from 7.2+.
130-
// From SonarQube 6.6 "-Dsonar.analysis.mode" leads to an exception, because it's deprecated.
131-
// There seems to be no replacement in the community version.
132-
// See https://docs.sonarqube.org/display/PLUG/GitHub+Plugin
133-
// Some examples for Env Vars when building PRs.
113+
// Use -Dsonar.branch.name with following plugin:
114+
// https://github.com/mc1arke/sonarqube-community-branch-plugin
115+
// Some examples for Env Vars when building PRs.
134116
// BRANCH_NAME=PR-26
135-
// CHANGE_BRANCH=feature/simpify_git_push
117+
// CHANGE_BRANCH=feature/simplify_git_push
136118
// CHANGE_TARGET=develop
137-
138-
def artifactId = mvn.artifactId.trim()
139-
// Malformed key for Project: 'groupId:artifactId:feature/something'.
140-
// Allowed characters are alphanumeric, '-', '_', '.' and ':', with at least one non-digit.
141-
String projectKey = replaceCharactersNotAllowedInProjectKey(script.env.BRANCH_NAME)
142-
String projectName = script.env.BRANCH_NAME
143-
mvn.additionalArgs += " -Dsonar.projectKey=${mvn.groupId}:${artifactId}:${projectKey}" +
144-
" -Dsonar.projectName=${artifactId}:${projectName} "
119+
} else if (script.env.CHANGE_TARGET) {
120+
mvn.additionalArgs += "-Dsonar.projectKey=${replaceCharactersNotAllowedInProjectKey(artifactId)} " +
121+
" -Dsonar.projectName=${artifactId} " +
122+
" -Dsonar.pullrequest.key=${script.env.CHANGE_ID} " +
123+
" -Dsonar.pullrequest.branch=${script.env.CHANGE_BRANCH} " +
124+
" -Dsonar.pullrequest.base=${script.env.CHANGE_TARGET} "
125+
} else if (script.env.BRANCH_NAME) {
126+
mvn.additionalArgs += "-Dsonar.projectKey=${replaceCharactersNotAllowedInProjectKey(artifactId)} " +
127+
" -Dsonar.projectName=${artifactId} " +
128+
" -Dsonar.branch.name=${script.env.BRANCH_NAME} "
145129
}
146130
}
147131

148-
protected String replaceCharactersNotAllowedInProjectKey(String potentialProjectKey) {
149-
return potentialProjectKey.replaceAll("[^a-zA-Z0-9-_.:]", "_");
132+
protected static String replaceCharactersNotAllowedInProjectKey(String potentialProjectKey) {
133+
return potentialProjectKey.replaceAll("[^a-zA-Z0-9-_.:]", "_")
150134
}
151-
135+
152136
protected String determineIntegrationBranch() {
153137
if (config['integrationBranch']) {
154138
return config['integrationBranch']
@@ -221,7 +205,7 @@ class SonarQube implements Serializable {
221205
}
222206

223207
analyzeWith(mvn, script.env.SONAR_MAVEN_GOAL, script.env.SONAR_HOST_URL, script.env.SONAR_AUTH_TOKEN,
224-
sonarExtraProps)
208+
sonarExtraProps)
225209
}
226210
}
227211
}
@@ -257,9 +241,9 @@ class SonarQube implements Serializable {
257241

258242
def executeWith(Maven mvn) {
259243
script.withCredentials([script.usernamePassword(credentialsId: usernameAndPasswordCredential,
260-
passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
244+
passwordVariable: 'PASSWORD', usernameVariable: 'USERNAME')]) {
261245
analyzeWith(mvn, 'sonar:sonar', host, script.env.USERNAME,
262-
"-Dsonar.password=${script.env.PASSWORD} ")
246+
"-Dsonar.password=${script.env.PASSWORD} ")
263247
}
264248
}
265249
}

test/com/cloudogu/ces/cesbuildlib/K3dTest.groovy

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ class K3dTest {
358358
scriptMock.expectedShRetValueForScript.put("echo 'test' | grep 'test'", "test")
359359

360360
String doguYaml = """
361-
apiVersion: k8s.cloudogu.com/v1
361+
apiVersion: k8s.cloudogu.com/v2
362362
kind: Dogu
363363
metadata:
364364
name: nginx-ingress
@@ -384,7 +384,7 @@ spec:
384384
assertThat(scriptMock.allActualArgs[10].trim()).isEqualTo("yq -oj '.Image=\"myIP.local:5000/test/myimage:0.1.2\"' dogu.json > leWorkspace/target/dogu.json")
385385
assertThat(scriptMock.allActualArgs[11].trim()).isEqualTo("sudo KUBECONFIG=leK3dWorkSpace/.k3d/.kube/config kubectl create configmap test-descriptor --from-file=leWorkspace/target/dogu.json")
386386
assertThat(scriptMock.allActualArgs[12].trim()).isEqualTo("sudo KUBECONFIG=leK3dWorkSpace/.k3d/.kube/config kubectl apply -f \n" +
387-
"apiVersion: k8s.cloudogu.com/v1\n" +
387+
"apiVersion: k8s.cloudogu.com/v2\n" +
388388
"kind: Dogu\n" +
389389
"metadata:\n" +
390390
" name: nginx-ingress\n" +
@@ -532,7 +532,7 @@ spec:
532532

533533
def filename = "target/make/k8s/testName.yaml"
534534
def doguContentYaml = """
535-
apiVersion: k8s.cloudogu.com/v1
535+
apiVersion: k8s.cloudogu.com/v2
536536
kind: Dogu
537537
metadata:
538538
name: testName

test/com/cloudogu/ces/cesbuildlib/SonarQubeTest.groovy

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class SonarQubeTest {
4747

4848
assert mavenMock.args ==
4949
'sonar:sonar -Dsonar.host.url=http://ces/sonar -Dsonar.login=auth '
50-
assertBranchName(branchName, branchName)
50+
assertBranchName(branchName, mavenMock)
5151
assert scriptMock.actualStringArgs['credentialsId'] == 'secretTextCred'
5252
}
5353

@@ -75,7 +75,7 @@ class SonarQubeTest {
7575

7676
assert mavenMock.args ==
7777
'sonar:sonar -Dsonar.host.url=http://ces/sonar -Dsonar.login=usr -Dsonar.password=pw '
78-
assertBranchName('develop', 'develop')
78+
assertBranchName('develop', mavenMock)
7979
assert scriptMock.actualUsernamePasswordArgs[0]['credentialsId'] == 'usrPwCred'
8080
}
8181

@@ -128,7 +128,7 @@ class SonarQubeTest {
128128

129129
assert mavenMock.args ==
130130
'sonar:sonar -Dsonar.host.url=host -Dsonar.login=auth -DextraKey=extraValue'
131-
assertBranchName('develop', 'develop')
131+
assertBranchName('develop', mavenMock)
132132
assert scriptMock.actualSonarQubeEnv == 'sqEnv'
133133
}
134134

@@ -157,8 +157,13 @@ class SonarQubeTest {
157157
@Test
158158
void analyzeWithBranchContainCharsNotValidForProjectKey() throws Exception {
159159
String branchName = 'feature/abc'
160-
String projectKey = 'feature_abc'
161-
String projectName = branchName
160+
// Use custom maven mock because the attributes are read only
161+
def mavenMock = new MavenMock(scriptMock)
162+
mavenMock.mockedArtifactId = "ces/build/lib"
163+
mavenMock.mockedGroupId = "com.cloudogu.ces"
164+
mavenMock.mockedName = "ces build lib"
165+
String projectKey = 'ces_build_lib'
166+
String projectName = "ces/build/lib"
162167

163168
def sonarQube = new SonarQube(scriptMock, [usernamePassword: 'usrPwCred', sonarHostUrl: 'http://ces/sonar'])
164169
scriptMock.env = [
@@ -168,7 +173,9 @@ class SonarQubeTest {
168173

169174
sonarQube.analyzeWith(mavenMock)
170175

171-
assertBranchName(projectKey, projectName)
176+
assertBranchName(branchName, mavenMock)
177+
assertProjectKey(projectKey, mavenMock)
178+
assertProjectName(projectName, mavenMock)
172179
}
173180

174181
@Test
@@ -251,6 +258,27 @@ class SonarQubeTest {
251258
assert mavenMock.additionalArgs.endsWith(' -Dsonar.branch.target=develop ')
252259
}
253260

261+
@Test
262+
void analyzeWithBranchCommunityBranchPluginOnPullRequest() throws Exception {
263+
def branchName = "PR-42"
264+
def changeID = "123"
265+
def changeTarget = "develop"
266+
scriptMock.env = [
267+
CHANGE_BRANCH: branchName,
268+
CHANGE_TARGET: changeTarget,
269+
CHANGE_ID: changeID,
270+
]
271+
272+
def sonarQube = new SonarQube(scriptMock, ["sonarQubeEnv": "env"])
273+
sonarQube.analyzeWith(mavenMock)
274+
275+
assertProjectName(mavenMock.artifactId, mavenMock)
276+
assertProjectKey(mavenMock.artifactId, mavenMock)
277+
assert mavenMock.additionalArgs.contains("-Dsonar.pullrequest.key=${changeID}")
278+
assert mavenMock.additionalArgs.contains("-Dsonar.pullrequest.branch=${branchName}")
279+
assert mavenMock.additionalArgs.contains("-Dsonar.pullrequest.base=${changeTarget}")
280+
}
281+
254282
@Test
255283
void waitForQualityGate() throws Exception {
256284
scriptMock.expectedQGate = [status: 'OK']
@@ -321,7 +349,15 @@ class SonarQubeTest {
321349
assert exception.message == "Missing required 'sonarHostUrl' parameter."
322350
}
323351

324-
void assertBranchName(String projectKey, String projectName) {
325-
assert mavenMock.additionalArgs.contains("-Dsonar.projectKey=com.cloudogu.ces:ces-build-lib:${projectKey} -Dsonar.projectName=ces-build-lib:${projectName}")
352+
static void assertProjectKey(String projectKey, MavenMock mavenMock) {
353+
assert mavenMock.additionalArgs.contains("-Dsonar.projectKey=${projectKey}")
354+
}
355+
356+
static void assertProjectName(String projectName, MavenMock mavenMock) {
357+
assert mavenMock.additionalArgs.contains("-Dsonar.projectName=${projectName}")
358+
}
359+
360+
static void assertBranchName(String branchName, MavenMock mavenMock) {
361+
assert mavenMock.additionalArgs.contains("-Dsonar.branch.name=${branchName}")
326362
}
327363
}

0 commit comments

Comments
 (0)