Repository: jhipster/jhipster-lite
Pull request #12683 (2025-05-31 16:27:44)

Upgrade Sonarqube to 25.4
Following https://github.com/jhipster/jhipster-lite/pull/12289

pascalgrimaud: Forgot to update the CI part, I'll do it later

Patch:
diff --git a/.github/workflows/github-actions.yml b/.github/workflows/github-actions.yml
index 023e368bd..4d337403e 100644
--- a/.github/workflows/github-actions.yml
+++ b/.github/workflows/github-actions.yml
@@ -448,8 +448,8 @@ jobs:
         working-directory: /tmp/jhlite/${{ matrix.app }}/
         run: |
           if [ -f 'src/main/docker/sonar.yml' ]; then
-            docker compose -f src/main/docker/sonar.yml up -d
-            ${{ github.workspace }}/current-branch/tests-ci/wait_sonar.sh
+            docker compose -f src/main/docker/sonar.yml up -d \
+              && docker logs -f sonar-token && SONAR_TOKEN=$(docker logs sonar-token)
             docker ps -a
           fi
       - name: 'Install jhlite snapshot jar in local maven repository'
@@ -464,10 +464,11 @@ jobs:
         if: steps.tests-requirement-check.outputs.execute_tests == 'true'
         working-directory: /tmp/jhlite/${{ matrix.app }}/
         run: |
+          SONAR_TOKEN=$(docker logs sonar-token)
           if [ -f 'mvnw' ]; then
-            ./mvnw clean verify -Dsonar.qualitygate.wait=true sonar:sonar
+            ./mvnw clean verify -Dsonar.qualitygate.wait=true sonar:sonar -Dsonar.token=$SONAR_TOKEN
           elif [ -f 'gradlew' ]; then
-            ./gradlew clean build sonar --no-daemon --info
+            ./gradlew clean build sonar --no-daemon --info -Dsonar.token=$SONAR_TOKEN
           else
             npm install
             npm test
diff --git a/README.md b/README.md
index e8776a581..334ceb875 100644
--- a/README.md
+++ b/README.md
@@ -179,7 +179,7 @@ docker compose -f src/main/docker/sonar.yml up -d
 You need to wait for Sonar to be up before getting the Sonar token:
 
 ```bash
-SONAR_TOKEN=$(docker logs sonar-token)
+docker logs -f sonar-token && SONAR_TOKEN=$(docker logs sonar-token)
 ```
 
 Then:
@@ -188,6 +188,14 @@ Then:
 ./mvnw clean verify sonar:sonar -Dsonar.token=$SONAR_TOKEN
 ```
 
+You can use a single command:
+
+```bash
+docker compose -f src/main/docker/sonar.yml up -d \
+  && docker logs -f sonar-token && SONAR_TOKEN=$(docker logs sonar-token) \
+  && ./mvnw clean verify sonar:sonar -Dsonar.token=$SONAR_TOKEN
+```
+
 So you can check the result at http://localhost:9001
 
 ## Run the project
diff --git a/src/main/docker/sonar/Dockerfile b/src/main/docker/sonar/Dockerfile
index f98cc9b13..b0de2ed4f 100644
--- a/src/main/docker/sonar/Dockerfile
+++ b/src/main/docker/sonar/Dockerfile
@@ -1,11 +1,11 @@
 FROM ubuntu:24.04
 RUN \
-    apt update && \
-    apt --no-install-recommends install -y curl jq && \
-    groupadd jhipster && \
-    useradd jhipster -s /bin/bash -m -g jhipster -G sudo && \
-    echo 'jhipster:jhipster'|chpasswd && \
-    apt clean
+  apt update && \
+  apt --no-install-recommends install -y curl jq && \
+  groupadd jhipster && \
+  useradd jhipster -s /bin/bash -m -g jhipster -G sudo && \
+  echo 'jhipster:jhipster'|chpasswd && \
+  apt clean
 ENV \
   JHIPSTER_SONAR_URL=http://sonar:9000 \
   JHIPSTER_SONAR_PASSWORD=JHipsterLite-7471 \
diff --git a/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactory.java b/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactory.java
index 75ae910a8..49f6753f1 100644
--- a/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactory.java
+++ b/src/main/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactory.java
@@ -66,6 +66,12 @@ public class SonarQubeModuleFactory {
         .and()
       .files()
         .add(SOURCE.template("sonar.yml"), toSrcMainDocker().append("sonar.yml"))
+        .and()
+      .files()
+        .add(SOURCE.append("sonar/Dockerfile"), toSrcMainDocker().append("sonar/Dockerfile"))
+        .and()
+      .files()
+        .add(SOURCE.append("sonar/sonar_generate_token.sh"), toSrcMainDocker().append("sonar/sonar_generate_token.sh"))
         .and();
     // @formatter:on
   }
diff --git a/src/main/resources/generator/dependencies/Dockerfile b/src/main/resources/generator/dependencies/Dockerfile
index 047044924..f62e0c2d4 100644
--- a/src/main/resources/generator/dependencies/Dockerfile
+++ b/src/main/resources/generator/dependencies/Dockerfile
@@ -1,4 +1,4 @@
-FROM sonarqube:10.7.0-community
+FROM sonarqube:25.4.0.105899-community
 FROM consul:1.15.4
 FROM jhipster/consul-config-loader:v0.4.1
 FROM jhipster/jhipster-registry:v7.4.0
diff --git a/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache b/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache
index c518fda1b..743aa7b6e 100644
--- a/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache
+++ b/src/main/resources/generator/server/sonar/sonar-fullstack-project.properties.mustache
@@ -1,8 +1,5 @@
 sonar.projectKey={{baseName}}
 sonar.projectName={{projectName}}
-# used for local sonarqube Docker image
-sonar.login=admin
-sonar.password=admin
 
 sonar.sources=src/main/
 sonar.tests=src/test/
diff --git a/src/main/resources/generator/server/sonar/sonar-project.properties.mustache b/src/main/resources/generator/server/sonar/sonar-project.properties.mustache
index e09e1535f..fa8ab4920 100644
--- a/src/main/resources/generator/server/sonar/sonar-project.properties.mustache
+++ b/src/main/resources/generator/server/sonar/sonar-project.properties.mustache
@@ -1,8 +1,5 @@
 sonar.projectKey={{baseName}}
 sonar.projectName={{projectName}}
-# used for local sonarqube Docker image
-sonar.login=admin
-sonar.password=admin
 
 sonar.sources=src/main/
 sonar.tests=src/test/
diff --git a/src/main/resources/generator/server/sonar/sonar.md.mustache b/src/main/resources/generator/server/sonar/sonar.md.mustache
index 15ad83045..e51d3ee58 100644
--- a/src/main/resources/generator/server/sonar/sonar.md.mustache
+++ b/src/main/resources/generator/server/sonar/sonar.md.mustache
@@ -6,12 +6,26 @@ Start a local Sonar server with:
 docker compose -f src/main/docker/sonar.yml up -d
 ```
 
+You need to wait for Sonar to be up before getting the Sonar token:
+
+```bash
+docker logs -f sonar-token && SONAR_TOKEN=$(docker logs sonar-token)
+```
+
 Then, run a Sonar analysis:
 
 For Maven
 
 ```bash
-./mvnw clean verify sonar:sonar
+./mvnw clean verify sonar:sonar -Dsonar.token=$SONAR_TOKEN
+```
+
+You can use a single command:
+
+```bash
+docker compose -f src/main/docker/sonar.yml up -d && \
+docker logs -f sonar-token && SONAR_TOKEN=$(docker logs sonar-token) && \
+./mvnw clean verify sonar:sonar -Dsonar.token=$SONAR_TOKEN
 ```
 
 or
@@ -19,7 +33,15 @@ or
 For Gradle
 
 ```bash
-./gradlew clean build sonar --info
+./gradlew clean build sonar --info -Dsonar.token=$SONAR_TOKEN
+```
+
+You can use a single command:
+
+```bash
+docker compose -f src/main/docker/sonar.yml up -d && \
+docker logs -f sonar-token && SONAR_TOKEN=$(docker logs sonar-token) && \
+./gradlew clean build sonar --info -Dsonar.token=$SONAR_TOKEN
 ```
 
 You can see the result at [http://localhost:9001/](http://localhost:9001/)
diff --git a/src/main/resources/generator/server/sonar/sonar.yml.mustache b/src/main/resources/generator/server/sonar/sonar.yml.mustache
index e325c9ded..e0644c7dc 100644
--- a/src/main/resources/generator/server/sonar/sonar.yml.mustache
+++ b/src/main/resources/generator/server/sonar/sonar.yml.mustache
@@ -11,3 +11,12 @@ services:
     # remove the "127.0.0.1:" prefix
     ports:
       - '127.0.0.1:9001:9000'
+  sonar-token:
+    build:
+      context: .
+      dockerfile: sonar/Dockerfile
+    container_name: sonar-token
+    environment:
+      - JHIPSTER_SONAR_URL=http://sonar:9000
+    depends_on:
+      - sonar
diff --git a/src/main/resources/generator/server/sonar/sonar/Dockerfile b/src/main/resources/generator/server/sonar/sonar/Dockerfile
new file mode 100644
index 000000000..b0de2ed4f
--- /dev/null
+++ b/src/main/resources/generator/server/sonar/sonar/Dockerfile
@@ -0,0 +1,16 @@
+FROM ubuntu:24.04
+RUN \
+  apt update && \
+  apt --no-install-recommends install -y curl jq && \
+  groupadd jhipster && \
+  useradd jhipster -s /bin/bash -m -g jhipster -G sudo && \
+  echo 'jhipster:jhipster'|chpasswd && \
+  apt clean
+ENV \
+  JHIPSTER_SONAR_URL=http://sonar:9000 \
+  JHIPSTER_SONAR_PASSWORD=JHipsterLite-7471 \
+  JHIPSTER_SONAR_TOKENNAME=jhlitetoken
+COPY sonar/sonar_generate_token.sh /usr/local/bin/sonar_generate_token
+RUN chmod 755 /usr/local/bin/sonar_generate_token
+USER jhipster
+CMD ["sonar_generate_token"]
diff --git a/src/main/resources/generator/server/sonar/sonar/sonar_generate_token.sh b/src/main/resources/generator/server/sonar/sonar/sonar_generate_token.sh
new file mode 100755
index 000000000..b7c056c5e
--- /dev/null
+++ b/src/main/resources/generator/server/sonar/sonar/sonar_generate_token.sh
@@ -0,0 +1,12 @@
+#!/usr/bin/env bash
+
+until [ "$(curl -s $JHIPSTER_SONAR_URL/api/system/status | jq -r .status)" = "UP" ]; do
+  sleep 5
+done
+
+curl -sS -u admin:admin -X POST \
+  "$JHIPSTER_SONAR_URL/api/users/change_password" \
+  -d "login=admin&previousPassword=admin&password=$JHIPSTER_SONAR_PASSWORD"
+
+SONAR_TOKEN=$(curl -sS -u admin:$JHIPSTER_SONAR_PASSWORD -X POST "$JHIPSTER_SONAR_URL/api/user_tokens/generate" -d "name=$JHIPSTER_SONAR_TOKENNAME" | jq -r .token)
+echo $SONAR_TOKEN


Test patch:
diff --git a/src/main/resources/generator/server/springboot/dbmigration/liquibase/test/SpringLiquibaseUtilTest.java.mustache b/src/main/resources/generator/server/springboot/dbmigration/liquibase/test/SpringLiquibaseUtilTest.java.mustache
index 5e37f79df..62d3d07fc 100644
--- a/src/main/resources/generator/server/springboot/dbmigration/liquibase/test/SpringLiquibaseUtilTest.java.mustache
+++ b/src/main/resources/generator/server/springboot/dbmigration/liquibase/test/SpringLiquibaseUtilTest.java.mustache
@@ -31,7 +31,7 @@ class SpringLiquibaseUtilTest {
   private static String datasourceUrl;
 
   @BeforeAll
-  public static void setup() {
+  static void setup() {
     datasourceUrl = testProperties().getProperty("spring.datasource.url");
   }
 
diff --git a/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactoryTest.java b/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactoryTest.java
index 9bee3d7d0..b5f630947 100644
--- a/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactoryTest.java
+++ b/src/test/java/tech/jhipster/lite/generator/server/sonarqube/domain/SonarQubeModuleFactoryTest.java
@@ -1,7 +1,12 @@
 package tech.jhipster.lite.generator.server.sonarqube.domain;
 
-import static org.mockito.Mockito.*;
-import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.*;
+import static org.mockito.Mockito.when;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.JHipsterModuleAsserter;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.assertThatModuleWithFiles;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.gradleBuildFile;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.gradleLibsVersionFile;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.pomFile;
+import static tech.jhipster.lite.module.infrastructure.secondary.JHipsterModulesAssertions.readmeFile;
 
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
@@ -106,6 +111,10 @@ class SonarQubeModuleFactoryTest {
         .hasFile("src/main/docker/sonar.yml")
         .containing("sonarqube:1.1.1")
         .and()
+        .hasFile("src/main/docker/sonar/Dockerfile")
+        .and()
+        .hasFile("src/main/docker/sonar/sonar_generate_token.sh")
+        .and()
         .hasFile("documentation/sonar.md")
         .containing("docker compose -f src/main/docker/sonar.yml up -d")
         .containing("./gradlew clean build sonar --info")