This is an automated email from the ASF dual-hosted git repository.
lprimak pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shiro.git
The following commit(s) were added to refs/heads/main by this push:
new 579060599 Build CI artifacts on only once, and reuse the builds in the
matrix (#2937)
579060599 is described below
commit 57906059917a7e0fa6b86141d86758439996b687
Author: Lenny Primak <[email protected]>
AuthorDate: Sat Nov 7 14:18:59 2026 -0600
Build CI artifacts on only once, and reuse the builds in the matrix (#2937)
---
.github/dependabot.yml | 3 +
.github/workflows/maven.yml | 82 ++++---
.jenkins.groovy | 266 ++++++++++-----------
.jenkins_maven_args | 1 -
.../apache/shiro/aop/AnnotationHierarchyTest.java | 16 --
integration-tests/jaxrs/openliberty/pom.xml | 2 +
pom.xml | 5 +
7 files changed, 192 insertions(+), 183 deletions(-)
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index b9136a27e..3252f79b5 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -41,6 +41,9 @@ updates:
patterns:
- '*'
ignore:
+ # RAT 0.18+ requires Java 17; 2.x supports Java 11.
+ - dependency-name: "org.apache.rat:apache-rat-plugin"
+ versions: [ ">=0.18" ]
- dependency-name: "jakarta.platform:*"
update-types: [ "version-update:semver-major" ]
- dependency-name: "jakarta.activation:jakarta.activation-api"
diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 022741274..75030c6b1 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -43,66 +43,82 @@ jobs:
with:
java-version: 25
distribution: temurin
-
- - name: License Check
- run: ./mvnw apache-rat:check "-Drat.consoleOutput"
+ cache: maven
- name: Build with Maven
- # zizmor: ignore[template-injection]
run: >-
./mvnw verify --show-version --errors --batch-mode
--no-transfer-progress -Pdocs
- -Dgh_user=${{ github.actor }} -Dgh_token=${{ secrets.GITHUB_TOKEN }}
+ -DskipTests -DskipITs
+
+ - name: Bundle build output
+ run: find . -path './.mvn' -prune -o -type d -name target -prune
-print0 | tar --null -T - -czf ci-build.tar.gz
+
+ - name: Upload build output
+ uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
# v7.0.2
+ with:
+ name: ci-build
+ path: ci-build.tar.gz
+ retention-days: 1
- build-all:
+ test:
needs: build
strategy:
matrix:
os: [ 'ubuntu-latest', 'windows-latest', 'macOS-latest' ]
- jdk: [ 21, 25 ]
+ jdk: [ 17, 21, 25 ]
dist: [ 'temurin', 'semeru', 'zulu' ]
exclude:
- # was already built
- - os: 'ubuntu-latest'
- jdk: 25
- dist: 'temurin'
- # exclude temurin on MacOS. zulu (also hotspot) and Semeru are
sufficient.
- - os: 'macOS-latest'
- dist: 'temurin'
- # no Temurin 21
- - dist: 'temurin'
- jdk: 21
- # no Semeru 21
- - dist: 'semeru'
- jdk: 21
+ # Older supported JDKs are covered on Linux.
+ - { os: 'macOS-latest', jdk: 17 }
+ - { os: 'macOS-latest', jdk: 21 }
+ - { os: 'windows-latest', jdk: 17 }
+ - { os: 'windows-latest', jdk: 21 }
+ # Zulu covers HotSpot on macOS and Windows; Semeru covers OpenJ9.
+ - { os: 'macOS-latest', dist: 'temurin' }
+ - { os: 'windows-latest', dist: 'temurin' }
fail-fast: false
runs-on: ${{ matrix.os }}
+ defaults:
+ run:
+ shell: bash
+
steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #
v7.0.1
with:
persist-credentials: false
- - name: Set up JDK
+ - name: Set up test JDK
uses: actions/setup-java@b843ebf9b913146b38da2eaa7aeddf76074ae1ad #
v6.1.0
with:
java-version: ${{ matrix.jdk }}
distribution: ${{ matrix.dist }}
+ cache: maven
- - name: Build with Maven (Linux)
- if: matrix.os == 'ubuntu-latest' && matrix.jdk >= 21
- # zizmor: ignore[template-injection]
- run: >-
- ./mvnw verify --show-version --errors --batch-mode
--no-transfer-progress
- -Dgh_user=${{ github.actor }} -Dgh_token=${{ secrets.GITHUB_TOKEN }}
-
- - name: Build with Maven (non-Linux)
- if: matrix.os != 'ubuntu-latest' || matrix.jdk < 21
- run: >-
- ./mvnw verify --show-version --errors --batch-mode
--no-transfer-progress
- -Pskip_jakarta_ee_tests
+ - name: Download build output
+ uses:
actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8
+ with:
+ name: ci-build
+
+ - name: Restore build output
+ run: tar -xzf ci-build.tar.gz
+
+ - name: Test with Maven
+ env:
+ JAKARTA_EE_TESTS: ${{ matrix.os == 'ubuntu-latest' && matrix.jdk ==
25 }}
+ GH_USER: ${{ github.actor }}
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ args=(--show-version --errors --batch-mode --no-transfer-progress
+ -Dmaven.main.skip=true -Dmaven.test.compile.skip=true
-Daspectj.skip=true
+ -Dcheckstyle.skip -DminimalJavaBuildVersion=17
"-Dgh_user=$GH_USER" "-Dgh_token=$GH_TOKEN")
+ if [ "$JAKARTA_EE_TESTS" != true ]; then
+ args+=(-Pskip_jakarta_ee_tests)
+ fi
+ ./mvnw verify "${args[@]}"
- name: Archive test run logs
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9
# v7.0.2
diff --git a/.jenkins.groovy b/.jenkins.groovy
index 866615b04..6510068ef 100644
--- a/.jenkins.groovy
+++ b/.jenkins.groovy
@@ -21,12 +21,17 @@ def deployableBranch = env.BRANCH_NAME ==~ /(main|4.x)/
def latestSupportedJDK = 'jdk_25_latest'
def builtinVersion = '999-SNAPSHOT'
def nextVersion
+def mavenArgs = '--show-version --errors --batch-mode --no-transfer-progress'
+def skipCompilation = '-Dmaven.main.skip=true -Dmaven.test.compile.skip=true
-Daspectj.skip=true'
pipeline {
agent none
options {
+ // Configure an overall timeout for the build of one hour.
+ timeout(time: 1, unit: 'HOURS')
+ skipDefaultCheckout()
// When we have test-fails e.g. we don't need to run the remaining
steps
skipStagesAfterUnstable()
buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr:
'5', daysToKeepStr: '30'))
@@ -34,12 +39,91 @@ pipeline {
stages {
stage('Build') {
+ agent {
+ node {
+ //
https://cwiki.apache.org/confluence/display/INFRA/ci-builds.apache.org
+ label 'ubuntu'
+ customWorkspace "workspace/${JOB_NAME}/BuildCheckout/"
+ }
+ }
+
+ tools {
+ //
https://cwiki.apache.org/confluence/display/INFRA/Maven+Installation+Matrix
+ maven 'maven_3_latest'
+ jdk "${latestSupportedJDK}"
+ }
+
+ stages {
+ stage('Checkout and Initialization') {
+ steps {
+ echo 'Cleaning up the workspace'
+ cleanBeforeCheckout()
+ echo 'Checking out branch ' + env.BRANCH_NAME
+ checkout scm
+ echo 'Building Branch: ' + env.BRANCH_NAME
+ echo 'Using PATH = ' + env.PATH
+ echo 'Slave Node = ' + env.NODE_NAME
+ }
+ }
+
+ stage('Use next -SNAPSHOT version') {
+ when {
+ expression { deployableBranch }
+ // is not a PR (GitHub) / MergeRequest (GitLab) /
Change (Gerrit)?
+ not { changeRequest() }
+ }
+
+ steps {
+ echo 'Setting next -SNAPSHOT version'
+ script {
+ def latestRelease = sh(script: """
+ curl -sf
https://repo.maven.apache.org/maven2/org/apache/shiro/shiro-root/maven-metadata.xml
\
+ | xmllint --xpath
'//metadata/versioning/versions/version/text()' - 2>/dev/null \
+ | egrep -vi "alpha|beta|RC"|tail -n1 \
+ || echo '$builtinVersion'
+ """, returnStdout: true
+ ).trim()
+
+ def parts = latestRelease.tokenize('.')
+ def nextPatch = parts[2].toInteger() + 1
+ nextVersion =
"${parts[0]}.${parts[1]}.${nextPatch}-SNAPSHOT"
+ if (env.BRANCH_NAME == '4.x') {
+ nextVersion = '4.0.0-SNAPSHOT'
+ } else if (parts[0].toInteger() < 3) {
+ nextVersion = '3.0.0-SNAPSHOT'
+ }
+
+ echo "Latest release: ${latestRelease}, next
SNAPSHOT: ${nextVersion}"
+ }
+
+ sh "./mvnw -B versions:set -DprocessAllModules=true
-DgenerateBackupPoms=false \
+ -DoldVersion=${builtinVersion}
-DnewVersion=${nextVersion}"
+ }
+ }
+
+ stage('Compile and package') {
+ steps {
+ echo 'Building'
+ sh "./mvnw verify ${mavenArgs} -Pdocs -DskipTests
-DskipITs"
+ stash name: 'ci-build', includes:
'**/target/**,**/pom.xml', excludes: '.mvn/**'
+ }
+ }
+ }
+
+ post {
+ success {
+ cleanBeforeCheckout()
+ }
+ }
+ }
+
+ stage('Test') {
matrix {
axes {
axis {
//
https://cwiki.apache.org/confluence/display/INFRA/JDK+Installation+Matrix
name 'MATRIX_JDK'
- values 'jdk_26_latest', 'jdk_25_latest',
'jdk_21_latest'
+ values 'jdk_27_latest', 'jdk_25_latest',
'jdk_21_latest'
}
// Additional axes, like OS and maven version can be
configured here.
}
@@ -52,11 +136,6 @@ pipeline {
}
}
- options {
- // Configure an overall timeout for the build of one hour.
- timeout(time: 1, unit: 'HOURS')
- }
-
tools {
//
https://cwiki.apache.org/confluence/display/INFRA/Maven+Installation+Matrix
maven 'maven_3_latest'
@@ -64,76 +143,26 @@ pipeline {
}
stages {
- stage('Initialization') {
- steps {
- echo 'Building Branch: ' + env.BRANCH_NAME
- echo 'Using PATH = ' + env.PATH
- echo 'Slave Node = ' + env.NODE_NAME
- }
- }
-
- stage('Cleanup') {
+ stage('Checkout and Restore build') {
steps {
echo 'Cleaning up the workspace'
cleanBeforeCheckout()
- }
- }
-
- stage('Checkout') {
- steps {
echo 'Checking out branch ' + env.BRANCH_NAME
checkout scm
+ echo 'Building Branch: ' + env.BRANCH_NAME
+ echo 'Using PATH = ' + env.PATH
+ echo 'Slave Node = ' + env.NODE_NAME
+ unstash 'ci-build'
}
}
- stage('Use next -SNAPSHOT version') {
- when {
- expression { deployableBranch }
- expression { MATRIX_JDK == latestSupportedJDK }
- // is not a PR (GitHub) / MergeRequest (GitLab) /
Change (Gerrit)?
- not { changeRequest() }
- }
- steps {
- echo 'Setting next -SNAPSHOT version'
- script {
- def latestRelease = sh(script: """
- curl -sf
https://repo.maven.apache.org/maven2/org/apache/shiro/shiro-root/maven-metadata.xml
\
- | xmllint --xpath
'//metadata/versioning/versions/version/text()' - 2>/dev/null \
- | egrep -vi "alpha|beta|RC"|tail -n1 \
- || echo '$builtinVersion'
- """, returnStdout: true
- ).trim()
-
- def parts = latestRelease.tokenize('.')
- def nextPatch = parts[2].toInteger() + 1
- nextVersion =
"${parts[0]}.${parts[1]}.${nextPatch}-SNAPSHOT"
- if (env.BRANCH_NAME == '4.x') {
- nextVersion = '4.0.0-SNAPSHOT'
- } else if (parts[0].toInteger() < 3) {
- nextVersion = '3.0.0-SNAPSHOT'
- }
-
- echo "Latest release: ${latestRelease}, next
SNAPSHOT: ${nextVersion}"
- }
-
- sh "./mvnw -B versions:set
-DprocessAllModules=true -DgenerateBackupPoms=false \
- -DoldVersion=${builtinVersion}
-DnewVersion=${nextVersion}"
- }
- }
-
- stage('License check') {
+ stage('Run tests') {
steps {
- echo 'License check'
- sh './mvnw --batch-mode -Drat.consoleOutput=true
apache-rat:check'
+ sh "./mvnw verify ${mavenArgs} ${skipCompilation} \
+ -Pskip_jakarta_ee_tests -Dcheckstyle.skip
-DminimalJavaBuildVersion=17 \
+ -Dmaven.test.failure.ignore=true"
}
- }
- stage('Build') {
- steps {
- echo 'Building'
- sh './mvnw verify --show-version --errors
--batch-mode --no-transfer-progress \
- -Dmaven.test.failure.ignore=true
-Pskip_jakarta_ee_tests -DjavaVersion=17'
- }
post {
always {
junit(testResults:
'**/surefire-reports/*.xml', allowEmptyResults: true)
@@ -145,92 +174,63 @@ pipeline {
stage('Deploy') {
when {
- allOf {
- expression { deployableBranch }
- expression { MATRIX_JDK == latestSupportedJDK }
- // is not a PR (GitHub) / MergeRequest
(GitLab) / Change (Gerrit)?
- not { changeRequest() }
- }
+ expression { deployableBranch }
+ expression { MATRIX_JDK == latestSupportedJDK }
+ // is not a PR (GitHub) / MergeRequest (GitLab) /
Change (Gerrit)?
+ not { changeRequest() }
}
+
steps {
echo 'Deploying'
- sh './mvnw --batch-mode deploy -Pdocs -DskipTests
-DskipITs'
+ sh "./mvnw deploy ${mavenArgs} ${skipCompilation} \
+ -Pdocs -DskipTests -DskipITs
-Dmaven.install.skip=true -Dcheckstyle.skip"
}
}
} // end of stages
- // Do any post build stuff ... such as sending emails
depending on the overall build result.
post {
- // If this build failed, send an email to the list.
- failure {
- script {
- if (deployableBranch) {
- emailext(
- subject: "[BUILD-FAILURE]: Job
'${env.JOB_NAME} [${env.BRANCH_NAME}] [${env.BUILD_NUMBER}]'",
- body: """
-BUILD-FAILURE: Job '${env.JOB_NAME} [${env.BRANCH_NAME}]
[${env.BUILD_NUMBER}]':
-Check console output at "<a href="${env.BUILD_URL}">${env.JOB_NAME}
[${env.BRANCH_NAME}] [${env.BUILD_NUMBER}]</a>"
-""",
- to: "[email protected]",
- recipientProviders: [[$class:
'DevelopersRecipientProvider']]
- )
- }
- }
- }
-
- // If this build didn't fail, but there were failing
tests, send an email to the list.
- unstable {
- script {
- if (deployableBranch) {
- emailext(
- subject: "[BUILD-UNSTABLE]: Job
'${env.JOB_NAME} [${env.BRANCH_NAME}] [${env.BUILD_NUMBER}]'",
- body: """
-BUILD-UNSTABLE: Job '${env.JOB_NAME} [${env.BRANCH_NAME}]
[${env.BUILD_NUMBER}]':
-Check console output at "<a href="${env.BUILD_URL}">${env.JOB_NAME}
[${env.BRANCH_NAME}] [${env.BUILD_NUMBER}]</a>"
-""",
- to: "[email protected]",
- recipientProviders: [[$class:
'DevelopersRecipientProvider']]
- )
- }
- }
- }
-
- // Send an email, if the last build was not successful and
this one is.
success {
// Cleanup the build directory if the build was
successful
// (in this case we probably don't have to do any
post-build analysis)
cleanBeforeCheckout()
- script {
- // remove MatrixCheckout directories older than 30
days to save disk space
- sh '''
- set -eu
- base_dir="../../../.."
- if [ -d "$base_dir" ]; then
- find "$base_dir" -name MatrixCheckout
-mindepth 3 -maxdepth 3 -type d -mtime +30 -exec rm -rf {} +
- fi
- '''
-
- // If this build was successful, and the previous
build was not successful, send a "back to normal" email.
- if (deployableBranch
- && (currentBuild.previousBuild != null) &&
(currentBuild.previousBuild.result != 'SUCCESS')) {
- emailext(
- subject: "[BUILD-STABLE]: Job
'${env.JOB_NAME} [${env.BRANCH_NAME}] [${env.BUILD_NUMBER}]'",
- body: """
-BUILD-STABLE: Job '${env.JOB_NAME} [${env.BRANCH_NAME}] [${env.BUILD_NUMBER}]':
-Is back to normal.
-""",
- to: "[email protected]",
- recipientProviders: [[$class:
'DevelopersRecipientProvider']]
- )
- }
- }
+ // remove MatrixCheckout directories older than 30
days to save disk space
+ sh '''
+ set -eu
+ base_dir="../../../.."
+ if [ -d "$base_dir" ]; then
+ find "$base_dir" -name MatrixCheckout
-mindepth 3 -maxdepth 3 -type d -mtime +30 -exec rm -rf {} +
+ fi
+ '''
}
} // end of post
} // end of matrix
- } // main stage ('Build')
+ } // main stage ('Test')
} // main stages
+
+ // Do any post build stuff ... such as sending emails depending on the
overall build result.
+ post {
+ always {
+ script {
+ def result = currentBuild.currentResult
+ // If this build was successful, and the previous build was
not successful, send a "back to normal" email.
+ def recovered = result == 'SUCCESS' &&
currentBuild.previousBuild != null \
+ && currentBuild.previousBuild.result != 'SUCCESS'
+ if (deployableBranch && (result in ['FAILURE', 'UNSTABLE'] ||
recovered)) {
+ def status = recovered ? 'STABLE' : result
+ def job = "${env.JOB_NAME} [${env.BRANCH_NAME}]
[${env.BUILD_NUMBER}]"
+ emailext(
+ subject: "[BUILD-${status}]: Job '${job}'",
+ body: recovered ? "BUILD-STABLE: Job '${job}': Is
back to normal."
+ : "BUILD-${status}: Job '${job}': Check
console output at <a href='${env.BUILD_URL}'>${job}</a>",
+ to: '[email protected]',
+ recipientProviders: [[$class:
'DevelopersRecipientProvider']]
+ )
+ }
+ }
+ }
+ }
}
diff --git a/.jenkins_maven_args b/.jenkins_maven_args
deleted file mode 100644
index c7750edfb..000000000
--- a/.jenkins_maven_args
+++ /dev/null
@@ -1 +0,0 @@
--Dmaven.compiler.release=17 -Djapicmp.skip=true
diff --git
a/core/src/test/java/org/apache/shiro/aop/AnnotationHierarchyTest.java
b/core/src/test/java/org/apache/shiro/aop/AnnotationHierarchyTest.java
index a5f4e7b6d..6e92a1e2f 100644
--- a/core/src/test/java/org/apache/shiro/aop/AnnotationHierarchyTest.java
+++ b/core/src/test/java/org/apache/shiro/aop/AnnotationHierarchyTest.java
@@ -40,7 +40,6 @@ import org.apache.shiro.authz.annotation.RequiresRoles;
import org.apache.shiro.authz.annotation.RequiresUser;
import org.junit.jupiter.api.Test;
-import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
@@ -49,8 +48,6 @@ import java.util.Arrays;
import static org.assertj.core.api.Assertions.assertThat;
class AnnotationHierarchyTest {
- private static final long MAX_BYTES_PER_CALL = 10_000;
-
@RequiresRoles("interface")
interface Closer {
}
@@ -215,17 +212,4 @@ class AnnotationHierarchyTest {
assertThat(AnnotationHierarchy.isPresent(JdkParents.class,
Deprecated.class)).isFalse();
}
- /**
- * Supertypes from the JDK can't hold a ClassValue entry, so their results
are kept elsewhere.
- * Without that, every call searches the methods of all of them again,
which allocates over 100 KB per call.
- */
- @Test
- void classesOutsideTheLoaderChainDoNotRepeatTheSearch() {
- var threads = (com.sun.management.ThreadMXBean)
ManagementFactory.getThreadMXBean();
- AnnotationHierarchy.isPresent(JdkParents.class, RequiresRoles.class);
- long before = threads.getCurrentThreadAllocatedBytes();
- AnnotationHierarchy.isPresent(JdkParents.class, RequiresRoles.class);
- assertThat(threads.getCurrentThreadAllocatedBytes() -
before).as("bytes allocated by the second call")
- .isLessThan(MAX_BYTES_PER_CALL);
- }
}
diff --git a/integration-tests/jaxrs/openliberty/pom.xml
b/integration-tests/jaxrs/openliberty/pom.xml
index bd6f11990..ad27e4d53 100644
--- a/integration-tests/jaxrs/openliberty/pom.xml
+++ b/integration-tests/jaxrs/openliberty/pom.xml
@@ -34,6 +34,7 @@
<properties>
<module.name>its.jaxrs.openliberty</module.name>
+ <liberty.start.skip>${skipITs}</liberty.start.skip>
<liberty.var.default.http.port>9080</liberty.var.default.http.port>
<liberty.var.default.https.port>9443</liberty.var.default.https.port>
<liberty.var.app.filename>shiro-its-jaxrs-app-${project.version}</liberty.var.app.filename>
@@ -62,6 +63,7 @@
<artifactId>liberty-maven-plugin</artifactId>
<version>3.12.4</version>
<configuration>
+ <skip>${liberty.start.skip}</skip>
<serverName>shiro-its-jaxrs-openliberty</serverName>
<features>
<acceptLicense>true</acceptLicense>
diff --git a/pom.xml b/pom.xml
index 8b5586890..74e9c42d5 100644
--- a/pom.xml
+++ b/pom.xml
@@ -76,6 +76,7 @@
<japicmp.skip>${japicmp-skip}</japicmp.skip>
<!-- workaround for gmavenplus plugin until maven 4 is being used -->
<maven.project.sourceRoots.warningsDisabled>true</maven.project.sourceRoots.warningsDisabled>
+ <maven.test.compile.skip>${maven.test.skip}</maven.test.compile.skip>
<!--suppress CheckTagEmptyBody -->
<surefire.argLine/>
<!--suppress CheckTagEmptyBody -->
@@ -616,6 +617,7 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
+ <skip>${maven.test.compile.skip}</skip>
<showWarnings>true</showWarnings>
<parameters>true</parameters>
<compilerArgs>
@@ -703,6 +705,9 @@
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
+ <configuration>
+ <skipTests>${maven.test.compile.skip}</skipTests>
+ </configuration>
<executions>
<execution>
<goals>