This is an automated email from the ASF dual-hosted git repository.

lukaszlenart pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/struts.git


The following commit(s) were added to refs/heads/main by this push:
     new e5fb8e91d build(ci): test once on JDK 17 in Jenkins, reserve Jetty 
ports for the showcase ITs (#1967)
e5fb8e91d is described below

commit e5fb8e91d7673792d77b661075e95e704991ccc4
Author: Lukasz Lenart <[email protected]>
AuthorDate: Sat Sep 19 07:50:15 2026 +0200

    build(ci): test once on JDK 17 in Jenkins, reserve Jetty ports for the 
showcase ITs (#1967)
    
    Jenkins ran the suite on JDK 21 and again on JDK 17 with -Pcoverage,
    then re-compiled the tree three more times for install, deploy and the
    nightlies. GitHub Actions already covers JDK 17, 21, 25 and the Jakarta
    EE 11 profile, and the JaCoCo data had no consumer on Jenkins. Jenkins
    now runs one verify on JDK 17 and keeps only what GitHub cannot do: the
    snapshot deploy and the nightlies upload. The deploy also passes
    -DskipITs: failsafe 3.6.0 has no skipTests parameter, so the showcase
    integration tests were booting Jetty on every "skipped" invocation. The
    nightlies step builds only the assembly module; the preceding deploy has
    already installed every other module and the descriptors read the
    sibling target/ directories of the same workspace.
    
    The old "Build Source & JavaDoc" stage ran in its own Maven session, so
    its jars were never attached to the deploy; the snapshot repository has
    only the main jar and pom. Dropping it changes nothing that is
    published.
    
    The showcase integration tests bound Jetty to a fixed 8090/8999.
    disableConcurrentBuilds() serialises only builds of the same branch
    job, so main and a pull request landing on one agent collided, and the
    pre-start "stop" goal with the shared stop key could shut down the
    neighbouring build's server. build-helper now reserves free ports for
    the start/stop executions; the plugin-level 8090/8999 stay in place for
    an interactive jetty:run. The port properties are deliberately not
    declared under <properties>: a declared property is interpolated into
    plugin configuration at model-build time, before build-helper runs, and
    the default would win everywhere.
    
    Co-authored-by: Claude Opus 5 (1M context) <[email protected]>
---
 Jenkinsfile           | 112 +++++++++++++++-----------------------------------
 apps/showcase/pom.xml |  33 +++++++++++++--
 2 files changed, 64 insertions(+), 81 deletions(-)

diff --git a/Jenkinsfile b/Jenkinsfile
index 5709b53f8..b58498fbb 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -31,10 +31,17 @@ pipeline {
     pollSCM 'H/15 * * * *'
   }
   stages {
-    stage('Prepare') {
+    stage('JDK 17') {
       agent {
         label 'ubuntu'
       }
+      tools {
+        jdk 'jdk_17_latest'
+        maven 'maven_3_latest'
+      }
+      environment {
+        MAVEN_OPTS = "-Xmx2048m"
+      }
       stages {
         stage('Clean up') {
           steps {
@@ -83,64 +90,16 @@ pipeline {
             }
           }
         }
-      }
-    }
-    stage('JDK 21') {
-      when {
-        expression { env.CODE_CHANGED != 'false' }
-      }
-      agent {
-        label 'ubuntu'
-      }
-      tools {
-        jdk 'jdk_21_latest'
-        maven 'maven_3_latest'
-      }
-      environment {
-        MAVEN_OPTS = "-Xmx1024m"
-      }
-      stages {
+        // Tests run once, on the baseline JDK. The other supported JDKs and
+        // the Jakarta EE 11 profile are covered by 
.github/workflows/maven.yml;
+        // Jenkins exists for what GitHub Actions cannot do: the snapshot 
deploy
+        // and the nightlies upload.
         stage('Test') {
-          steps {
-            sh './mvnw -B -DskipAssembly verify'
-          }
-          post {
-            always {
-              junit(testResults: '**/surefire-reports/*.xml', 
allowEmptyResults: true)
-              junit(testResults: '**/failsafe-reports/*.xml', 
allowEmptyResults: true)
-            }
-          }
-        }
-      }
-      post {
-        always {
-          cleanWs deleteDirs: true, patterns: [[pattern: '**/target/**', type: 
'INCLUDE']]
-        }
-      }
-    }
-    stage('JDK 17') {
-      when {
-        expression { env.CODE_CHANGED != 'false' }
-      }
-      agent {
-        label 'ubuntu'
-      }
-      tools {
-        jdk 'jdk_17_latest'
-        maven 'maven_3_latest'
-      }
-      environment {
-        MAVEN_OPTS = "-Xmx2048m"
-      }
-      stages {
-        stage('Install') {
-          steps {
-            sh './mvnw -B install -DskipTests -DskipAssembly'
+          when {
+            expression { env.CODE_CHANGED != 'false' }
           }
-        }
-        stage('Test') {
           steps {
-            sh './mvnw -B verify -Pcoverage -DskipAssembly'
+            sh './mvnw -B -DskipAssembly verify --no-transfer-progress'
           }
           post {
             always {
@@ -149,42 +108,39 @@ pipeline {
             }
           }
         }
-        stage('Build Source & JavaDoc') {
-          when {
-            anyOf {
-              branch 'main'
-              branch 'support/struts-6-x-x'
-            }
-          }
-          steps {
-            dir("local-snapshots-dir/") {
-              deleteDir()
-            }
-            sh './mvnw -B source:jar javadoc:jar -DskipTests -DskipAssembly'
-          }
-        }
+        // -DskipITs as well as -DskipTests: failsafe does not know skipTests,
+        // so without it the showcase integration tests boot Jetty again here.
         stage('Deploy Snapshot') {
           when {
-            anyOf {
-              branch 'main'
-              branch 'support/struts-6-x-x'
+            allOf {
+              expression { env.CODE_CHANGED != 'false' }
+              anyOf {
+                branch 'main'
+                branch 'support/struts-6-x-x'
+              }
             }
           }
           steps {
             withCredentials([file(credentialsId: 
'lukaszlenart-repository-access-token', variable: 'CUSTOM_SETTINGS')]) {
-              sh './mvnw -s \${CUSTOM_SETTINGS} deploy -DskipTests 
-DskipAssembly'
+              sh './mvnw -B -s \${CUSTOM_SETTINGS} deploy -DskipTests 
-DskipITs -DskipAssembly --no-transfer-progress'
             }
           }
         }
+        // The deploy above installed every module, so only the assembly
+        // module needs building; its descriptors read the sibling modules'
+        // target/ directories from this same workspace.
         stage('Upload nightlies') {
           when {
-            anyOf {
-              branch 'main'
-              branch 'support/struts-6-x-x'
+            allOf {
+              expression { env.CODE_CHANGED != 'false' }
+              anyOf {
+                branch 'main'
+                branch 'support/struts-6-x-x'
+              }
             }
           }
           steps {
-            sh './mvnw -B package -DskipTests'
+            sh './mvnw -B package -DskipTests -DskipITs -pl assembly 
--no-transfer-progress'
             sshPublisher(publishers: [
                 sshPublisherDesc(
                     configName: 'Nightlies',
diff --git a/apps/showcase/pom.xml b/apps/showcase/pom.xml
index 123b8ed89..43b87f580 100644
--- a/apps/showcase/pom.xml
+++ b/apps/showcase/pom.xml
@@ -230,7 +230,7 @@
                         <include>it.org.apache.struts2.showcase.*Test</include>
                     </includes>
                     <systemPropertyVariables>
-                        <http.port>8090</http.port>
+                        <http.port>${jetty.http.port}</http.port>
                     </systemPropertyVariables>
                 </configuration>
                 <executions>
@@ -248,6 +248,26 @@
                     </execution>
                 </executions>
             </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <version>3.6.1</version>
+                <executions>
+                    <execution>
+                        <id>reserve-jetty-ports</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>reserve-network-port</goal>
+                        </goals>
+                        <configuration>
+                            <portNames>
+                                <portName>jetty.http.port</portName>
+                                <portName>jetty.stop.port</portName>
+                            </portNames>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
@@ -279,10 +299,14 @@
                         <id>start-jetty</id>
                         <phase>pre-integration-test</phase>
                         <goals>
-                            <!-- stop any previous instance to free up the 
port -->
-                            <goal>stop</goal>
                             <goal>start</goal>
                         </goals>
+                        <configuration>
+                            <stopPort>${jetty.stop.port}</stopPort>
+                            <httpConnector>
+                                <port>${jetty.http.port}</port>
+                            </httpConnector>
+                        </configuration>
                     </execution>
                     <execution>
                         <id>stop-jetty</id>
@@ -290,6 +314,9 @@
                         <goals>
                             <goal>stop</goal>
                         </goals>
+                        <configuration>
+                            <stopPort>${jetty.stop.port}</stopPort>
+                        </configuration>
                     </execution>
                 </executions>
              </plugin>

Reply via email to