This is an automated email from the ASF dual-hosted git repository. benw pushed a commit to branch javax in repository https://gitbox.apache.org/repos/asf/tapestry-5.git
commit b74c304c455de0dcb51f3c413b9220d2e2c14b14 Author: Ben Weidig <[email protected]> AuthorDate: Sat Apr 4 16:39:26 2026 +0200 TAP5-2819: Jenkinsfile matrix build --- Jenkinsfile | 125 +++++++++++++++++++++ Jenkinsfile.integration-variants | 122 ++++++++++++++++++++ .../groovy/tapestry.testing-base-convention.gradle | 14 ++- 3 files changed, 255 insertions(+), 6 deletions(-) diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..7f2b4a95c --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,125 @@ +pipeline { + agent none + + environment { + GRADLE_OPTS = '-Dci=true -Dfile.encoding=UTF-8 -Dselenium.wait.timeout=30' + } + + options { + timeout(time: 90, unit: 'MINUTES') + skipStagesAfterUnstable() + } + + stages { + stage('Matrix') { + matrix { + axes { + axis { + name 'JDK_VERSION' + values 'jdk_1.8_latest', 'jdk_21_latest' + } + } + + agent { node { label 'ubuntu' } } + + tools { + jdk "${JDK_VERSION}" + } + + stages { + + // -- 01: Clean + Assemble --------------------------------------------- + + stage('Assemble') { + steps { + sh './gradlew clean assemble' + } + } + + // -- 02: Test + Coverage ---------------------------------------------- + + stage('Test: Check') { + steps { + // This will run unit tests and the default integration variant (jQuery + RequireJS). + // We include the coverage report in this step, as modifying the test results with + // sed would trigger a test rerun if it would be its own stage. + sh './gradlew check combinedJacocoReport --continue' + } + post { + always { + // Prefix the JUnit classnames so the Test UI shows which JDK ran which test + sh """ + find . -path '*/build/test-results/test/*.xml' -exec \ + sed -i 's/classname="/classname="${JDK_VERSION}./g' {} + + """ + + junit( + testResults: '**/build/test-results/test/**/*.xml', + allowEmptyResults: true + ) + + // Copy reports into a JDK-named folder to avoid overwriting between matrix cells + sh """ + find . \\( -path '*/build/reports' -o -path '*/build/test-results' \\) -type d | while IFS= read -r src; do + dest="matrix-artifacts/${JDK_VERSION}/\${src#./}" + mkdir -p -- "\$dest" + cp -r -- "\$src/." "\$dest/" + done + """ + + archiveArtifacts( + artifacts: "matrix-artifacts/${JDK_VERSION}/**/*", + allowEmptyArchive: true + ) + } + } + } + } + } + + // -- 03: JavaDoc Generation ------------------------------------------- + + stage('Aggregate Javadoc') { + agent { node { label 'ubuntu' } } + tools { + jdk 'jdk_21_latest' + } + steps { + sh './gradlew aggregateJavadoc' + } + post { + always { + publishHTML(target: [ + reportDir: 'build/documentation/javadocs', + reportFiles: 'index.html', + reportName: 'Aggregate Javadoc', + keepAll: true + ]) + } + } + } + } + } + + post { + failure { + emailext ( + to: "${env.MAIL_NOTIFICATION}", + subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", + body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p> + <p>Check console output at "<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>"</p>""", + recipientProviders: [[$class: 'DevelopersRecipientProvider']] + ) + } + + unstable { + emailext ( + to: "${env.MAIL_NOTIFICATION}", + subject: "UNSTABLE: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", + body: """<p>UNSTABLE: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p> + <p>Check console output at "<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>"</p>""", + recipientProviders: [[$class: 'DevelopersRecipientProvider']] + ) + } + } +} diff --git a/Jenkinsfile.integration-variants b/Jenkinsfile.integration-variants new file mode 100644 index 000000000..633dddf98 --- /dev/null +++ b/Jenkinsfile.integration-variants @@ -0,0 +1,122 @@ +pipeline { + // Don't set an agent, or it won't parallelize correctly. + // Each stage should ask for it's own agent + agent none + + environment { + // Disable the daemon to prevent parallal issues + GRADLE_OPTS = '-Dci=true -Dfile.encoding=UTF-8 -Dorg.gradle.daemon=false' + } + + tools { + jdk 'jdk_8_latest' + } + + options { + timeout(time: 1, unit: 'HOURS') + skipStagesAfterUnstable() + } + + stages { + stage('Integration Test Variants') { + parallel { + stage('Test: Prototype + RequireJS Disabled') { + agent { + node { + label 'ubuntu' + } + } + steps { + sh './gradlew tapestry-core:testWithPrototypeAndRequireJsDisabled --continue' + } + post { + always { + sh ''' + if [ -d "tapestry-core/build/test-results/testWithPrototypeAndRequireJsDisabled" ]; then + find tapestry-core/build/test-results/testWithPrototypeAndRequireJsDisabled -name "*.xml" -type f -exec sed -i 's/classname="/classname="Prototype./g' {} + + fi + ''' + + junit( + testResults: 'tapestry-core/build/test-results/testWithPrototypeAndRequireJsDisabled/**/*.xml', + allowEmptyResults: true + ) + } + } + } + + stage('Test: jQuery + RequireJS Disabled') { + agent { + node { + label 'ubuntu' + } + } + steps { + sh './gradlew tapestry-core:testWithJqueryAndRequireJsDisabled --continue' + } + post { + always { + sh ''' + if [ -d "tapestry-core/build/test-results/testWithJqueryAndRequireJsDisabled" ]; then + find tapestry-core/build/test-results/testWithJqueryAndRequireJsDisabled -name "*.xml" -type f -exec sed -i 's/classname="/classname="Jquery./g' {} + + fi + ''' + + junit( + testResults: 'tapestry-core/build/test-results/testWithJqueryAndRequireJsDisabled/**/*.xml', + allowEmptyResults: true + ) + } + } + } + + stage('Test: Prototype + RequireJS Enabled') { + agent { + node { + label 'ubuntu' + } + } + steps { + sh './gradlew tapestry-core:testWithPrototypeAndRequireJsEnabled --continue' + } + post { + always { + sh ''' + if [ -d "tapestry-core/build/test-results/testWithPrototypeAndRequireJsEnabled" ]; then + find tapestry-core/build/test-results/testWithPrototypeAndRequireJsEnabled -name "*.xml" -type f -exec sed -i 's/classname="/classname="PrototypeRjs./g' {} + + fi + ''' + + junit( + testResults: 'tapestry-core/build/test-results/testWithPrototypeAndRequireJsEnabled/**/*.xml', + allowEmptyResults: true + ) + } + } + } + } + } + } + + post { + failure { + emailext ( + to: "${env.MAIL_NOTIFICATION}", + subject: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", + body: """<p>FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p> + <p>Check console output at "<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>"</p>""", + recipientProviders: [[$class: 'DevelopersRecipientProvider']] + ) + } + + unstable { + emailext ( + to: "${env.MAIL_NOTIFICATION}", + subject: "UNSTABLE: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'", + body: """<p>UNSTABLE: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]':</p> + <p>Check console output at "<a href='${env.BUILD_URL}'>${env.JOB_NAME} [${env.BUILD_NUMBER}]</a>"</p>""", + recipientProviders: [[$class: 'DevelopersRecipientProvider']] + ) + } + } +} diff --git a/buildSrc/src/main/groovy/tapestry.testing-base-convention.gradle b/buildSrc/src/main/groovy/tapestry.testing-base-convention.gradle index 7a3efcd79..35dd0f937 100644 --- a/buildSrc/src/main/groovy/tapestry.testing-base-convention.gradle +++ b/buildSrc/src/main/groovy/tapestry.testing-base-convention.gradle @@ -9,15 +9,17 @@ dependencies { tasks.withType(Test).configureEach { testTask -> maxHeapSize = '600M' - systemProperties['tapestry.service-reloading-enabled'] = 'false' - systemProperties['java.io.tmpdir'] = temporaryDir.absolutePath + systemProperties( + 'tapestry.service-reloading-enabled': 'false', + 'java.io.tmpdir': temporaryDir.absolutePath, + 'file.encoding': 'UTF-8', + 'user.language': 'en', // TAP5-2722 + 'ci': System.getProperty('ci', 'false'), // TAP5-2819: Propagate 'ci' from possible GRADLE_OPTS to forked test workers + 'selenium.wait.timeout': System.getProperty('selenium.wait.timeout', '15') + ) - jvmArgs '-Dfile.encoding=UTF-8' environment.LANG = 'en_US.UTF-8' - // TAP5-2722 - systemProperty 'user.language', 'en' - testLogging { exceptionFormat 'full' events 'passed', 'skipped', 'failed'
