From dcd192047138b5b11a5ef58a3e09020423f60254 Mon Sep 17 00:00:00 2001 From: Philipp Pixel Date: Thu, 13 Nov 2025 13:47:13 +0100 Subject: [PATCH 1/3] #154 Use property sonar.token when providing SQ auth tokens With SonarQube 25.x, the property `-Dsonar.login` no longer works. Instead, an authentication token must be used as singular authentication information (that is, no username). This commit uses respective property for maven sonar goals which provide a token via the configuration map. --- CHANGELOG.md | 5 +++++ README.md | 2 +- src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy | 7 ++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 261ddd7d..60953e3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Changed +- SonarQube's `analyzeWith(mvn)` credential usage for tokens changed to avoid authentication errors + - With SonarQube 25.x the regular maven goal `sonar:sonar` changed the used authentication style because username/password no longer work. + - Instead, a SonarQube authentication token must be generated on the personal security profile page and used without username. This works best with setting the used credential to the config map entry `token` + ## [4.3.0](https://github.com/cloudogu/ces-build-lib/releases/tag/4.3.0) - 2025-08-21 ### Changed - Updates the BATS shell test image to 1.12 which supports the `--report-formatter` switch diff --git a/README.md b/README.md index de733e9c..43634f34 100644 --- a/README.md +++ b/README.md @@ -850,7 +850,7 @@ sonarQube.analyzeWith(mvn) Recommendation: Use Jenkins' replay feature for this. Then commit the `Jenkinsfile` with `isUsingBranchPlugin`. An alternative is running the first analysis locally, e.g. with maven -`mvn clean install sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=YOUR-ORG -Dsonar.login=YOUR-TOKEN` +`mvn clean install sonar:sonar -Dsonar.host.url=https://sonarcloud.io -Dsonar.organization=YOUR-ORG -Dsonar.token=YOUR-TOKEN` ## SonarCloud diff --git a/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy b/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy index b8e86378..a496c4a8 100644 --- a/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy +++ b/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy @@ -184,7 +184,12 @@ class SonarQube implements Serializable { protected analyzeWith(Maven mvn, String sonarMavenGoal, String sonarHostUrl, String sonarLogin, String sonarExtraProps = '') { - mvn "${sonarMavenGoal} -Dsonar.host.url=${sonarHostUrl} -Dsonar.login=${sonarLogin} ${sonarExtraProps}" + String sonarAuthProperty = "-Dsonar.login=${sonarLogin}" + if (config['token'] != "") { + sonarAuthProperty = "-Dsonar.token=${sonarLogin}" + } + + mvn "${sonarMavenGoal} -Dsonar.host.url=${sonarHostUrl} ${sonarAuthProperty} ${sonarExtraProps}" } } From 55b9330004636afa9e77bed75a1e9c451510212b Mon Sep 17 00:00:00 2001 From: Philipp Pixel Date: Thu, 13 Nov 2025 13:57:34 +0100 Subject: [PATCH 2/3] #154 Fix compile error, use bool instead The static abstract class construct does not allow to read the config map from the outer class. Unless there is more need to use full config map values, this commit relies on an ugly boolean. --- src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy b/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy index a496c4a8..bd1b1931 100644 --- a/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy +++ b/src/com/cloudogu/ces/cesbuildlib/SonarQube.groovy @@ -174,9 +174,11 @@ class SonarQube implements Serializable { private static abstract class AnalysisStrategy { def script + def useTokenAuth - AnalysisStrategy(script) { + AnalysisStrategy(script, useTokenAuth=false) { this.script = script + this.useTokenAuth = useTokenAuth } abstract executeWith(Maven mvn) @@ -185,7 +187,7 @@ class SonarQube implements Serializable { String sonarExtraProps = '') { String sonarAuthProperty = "-Dsonar.login=${sonarLogin}" - if (config['token'] != "") { + if (useTokenAuth) { sonarAuthProperty = "-Dsonar.token=${sonarLogin}" } @@ -221,7 +223,7 @@ class SonarQube implements Serializable { String host TokenAnalysisStrategy(script, String tokenCredential, String host) { - super(script) + super(script, true) this.token = tokenCredential this.host = host } From 39261eeccd77b294e2dd6cbef4f3d023be8a8f84 Mon Sep 17 00:00:00 2001 From: Philipp Pixel Date: Thu, 13 Nov 2025 14:04:08 +0100 Subject: [PATCH 3/3] #154 Fix unit test --- test/com/cloudogu/ces/cesbuildlib/SonarQubeTest.groovy | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/com/cloudogu/ces/cesbuildlib/SonarQubeTest.groovy b/test/com/cloudogu/ces/cesbuildlib/SonarQubeTest.groovy index 85fcf605..48921814 100644 --- a/test/com/cloudogu/ces/cesbuildlib/SonarQubeTest.groovy +++ b/test/com/cloudogu/ces/cesbuildlib/SonarQubeTest.groovy @@ -39,14 +39,14 @@ class SonarQubeTest { def branchName = 'develop.Or:somehing-completely_.different' scriptMock.env = [ - SONAR_AUTH_TOKEN: 'auth', + SONAR_AUTH_TOKEN: 'sqa_b8a90ec...', BRANCH_NAME : branchName ] sonarQube.analyzeWith(mavenMock) assert mavenMock.args == - 'sonar:sonar -Dsonar.host.url=http://ces/sonar -Dsonar.login=auth ' + 'sonar:sonar -Dsonar.host.url=http://ces/sonar -Dsonar.token=sqa_b8a90ec... ' assertBranchName(branchName, mavenMock) assert scriptMock.actualStringArgs['credentialsId'] == 'secretTextCred' }