diff --git a/.ci/dev/nightly-regression/Jenkinsfile b/.ci/dev/nightly-regression/Jenkinsfile index bc03e6d76e..06b95b351a 100644 --- a/.ci/dev/nightly-regression/Jenkinsfile +++ b/.ci/dev/nightly-regression/Jenkinsfile @@ -1,89 +1,174 @@ +#!groovy +/** + * Jenkins pipeline to build Corda Opensource nightly regression for feature branches. + */ + @Library('corda-shared-build-pipeline-steps') import static com.r3.build.BuildControl.killAllExistingBuildsForJob killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger()) +/** + * Common Gradle arguments for all Gradle executions + */ +String COMMON_GRADLE_PARAMS = [ + '--no-daemon', + '--stacktrace', + '--info', + '-Pcompilation.warningsAsErrors=false', + '-Ptests.failFast=true', +].join(' ') + pipeline { - agent { label 'k8s' } + agent { label 'standard' } + + /* + * List options in alphabetical order + */ options { - timestamps() - overrideIndexTriggers(false) - timeout(time: 3, unit: 'HOURS') buildDiscarder(logRotator(daysToKeepStr: '14', artifactDaysToKeepStr: '14')) + overrideIndexTriggers(false) + parallelsAlwaysFailFast() + timeout(time: 6, unit: 'HOURS') + timestamps() } + triggers { pollSCM ignorePostCommitHooks: true, scmpoll_spec: '@midnight' } + /* + * List environment variables in alphabetical order + */ environment { - DOCKER_TAG_TO_USE = "${env.GIT_COMMIT.subSequence(0, 8)}" - EXECUTOR_NUMBER = "${env.EXECUTOR_NUMBER}" - BUILD_ID = "${env.BUILD_ID}-${env.JOB_NAME}" ARTIFACTORY_CREDENTIALS = credentials('artifactory-credentials') } stages { - stage('Deploy Nodes') { + stage('Compile') { steps { - sh "./gradlew --no-daemon jar deployNodes" + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'clean', + 'jar' + ].join(' ') } } - stage('Generate Build Image') { + stage('Stash') { steps { - withCredentials([string(credentialsId: 'container_reg_passwd', variable: 'DOCKER_PUSH_PWD')]) { - sh "./gradlew " + - "-Dkubenetize=true " + - "-Ddocker.push.password=\"\${DOCKER_PUSH_PWD}\" " + - "-Ddocker.work.dir=\"/tmp/\${EXECUTOR_NUMBER}\" " + - "-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\"" + - " clean pushBuildImage --stacktrace" - } - sh "kubectl auth can-i get pods" + stash name: 'compiled', useDefaultExcludes: false } } - stage('Testing phase') { + stage('All Tests') { parallel { - stage('Regression Test') { - steps { - sh "./gradlew " + - "-DbuildId=\"\${BUILD_ID}\" " + - "-Dkubenetize=true " + - "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + - "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + - "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + - "-Dgit.branch=\"\${GIT_BRANCH}\" " + - "-Dgit.target.branch=\"\${GIT_BRANCH}\" " + - " parallelRegressionTest --stacktrace" + stage('Another agent') { + agent { + label 'standard' + } + options { + skipDefaultCheckout true + } + post { + always { + archiveArtifacts artifacts: '**/*.log', fingerprint: false + junit testResults: '**/build/test-results/**/*.xml', keepLongStdio: true + } + cleanup { + deleteDir() /* clean up our workspace */ + } + } + stages { + stage('Unstash') { + steps { + unstash 'compiled' + } + } + stage('Recompile') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'jar' + ].join(' ') + } + } + stage('Unit Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'test' + ].join(' ') + } + } + stage('Proxy Integration Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'proxyIntegrationTest' + ].join(' ') + } + } + stage('Smoke Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'smokeTest' + ].join(' ') + } + } + stage('Slow Integration Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'slowIntegrationTest' + ].join(' ') + } + } } } - stage('Slow Integration Test') { - steps { - sh "./gradlew " + - "-DbuildId=\"\${BUILD_ID}\" " + - "-Dkubenetize=true " + - "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + - "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + - "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + - "-Dgit.branch=\"\${GIT_BRANCH}\" " + - "-Dgit.target.branch=\"\${GIT_BRANCH}\" " + - " allParallelSlowIntegrationTest --stacktrace" + stage('Same agent') { + post { + always { + archiveArtifacts artifacts: '**/*.log', fingerprint: false + junit testResults: '**/build/test-results/**/*.xml', keepLongStdio: true + } + } + stages { + stage('Integration Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'integrationTest' + ].join(' ') + } + } + + stage('Deploy Node') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'deployNode' + ].join(' ') + } + } } } } } } - post { - always { - archiveArtifacts artifacts: '**/pod-logs/**/*.log', fingerprint: false - junit testResults: '**/build/test-results-xml/**/*.xml', keepLongStdio: true - } cleanup { deleteDir() /* clean up our workspace */ } } } - diff --git a/.ci/dev/pr-code-checks/Jenkinsfile b/.ci/dev/pr-code-checks/Jenkinsfile index 20cf49f912..5cb1058811 100644 --- a/.ci/dev/pr-code-checks/Jenkinsfile +++ b/.ci/dev/pr-code-checks/Jenkinsfile @@ -11,20 +11,9 @@ pipeline { buildDiscarder(logRotator(daysToKeepStr: '14', artifactDaysToKeepStr: '14')) } - environment { - PR_CONTEXT_STRING = "PR Code Checks" - } - stages { stage('Detekt check') { steps { - script { - pullRequest.createStatus( - status: 'pending', - context: "${PR_CONTEXT_STRING}", - description: "Running code checks", - targetUrl: "${env.BUILD_URL}") - } sh "./gradlew --no-daemon clean detekt" } } @@ -50,25 +39,6 @@ pipeline { } post { - success { - script { - pullRequest.createStatus( - status: 'success', - context: "${PR_CONTEXT_STRING}", - description: 'Code checks passed', - targetUrl: "${env.BUILD_URL}") - } - } - - failure { - script { - pullRequest.createStatus( - status: 'failure', - context: "${PR_CONTEXT_STRING}", - description: 'Code checks failed', - targetUrl: "${env.BUILD_URL}") - } - } cleanup { deleteDir() /* clean up our workspace */ } diff --git a/Jenkinsfile b/Jenkinsfile index 5c9a1add5d..0b5a887f02 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,65 +1,124 @@ -import static com.r3.build.BuildControl.killAllExistingBuildsForJob +#!groovy +/** + * Jenkins pipeline to build Corda Opensource Pull Requests. + */ + @Library('corda-shared-build-pipeline-steps') import static com.r3.build.BuildControl.killAllExistingBuildsForJob killAllExistingBuildsForJob(env.JOB_NAME, env.BUILD_NUMBER.toInteger()) +/** + * Common Gradle arguments for all Gradle executions + */ +String COMMON_GRADLE_PARAMS = [ + '--no-daemon', + '--stacktrace', + '--info', + '-Pcompilation.warningsAsErrors=false', + '-Ptests.failFast=true', +].join(' ') + pipeline { - agent { label 'k8s' } + agent { label 'standard' } + + /* + * List options in alphabetical order + */ options { - timestamps() - timeout(time: 3, unit: 'HOURS') + ansiColor('xterm') buildDiscarder(logRotator(daysToKeepStr: '14', artifactDaysToKeepStr: '14')) + parallelsAlwaysFailFast() + timeout(time: 6, unit: 'HOURS') + timestamps() } + /* + * List environment variables in alphabetical order + */ environment { - DOCKER_TAG_TO_USE = "${env.GIT_COMMIT.subSequence(0, 8)}" - EXECUTOR_NUMBER = "${env.EXECUTOR_NUMBER}" - BUILD_ID = "${env.BUILD_ID}-${env.JOB_NAME}" ARTIFACTORY_CREDENTIALS = credentials('artifactory-credentials') } stages { - stage('Corda Pull Request - Generate Build Image') { + stage('Compile') { steps { - withCredentials([string(credentialsId: 'container_reg_passwd', variable: 'DOCKER_PUSH_PWD')]) { - sh "./gradlew --no-daemon " + - "-Dkubenetize=true " + - "-Ddocker.push.password=\"\${DOCKER_PUSH_PWD}\" " + - "-Ddocker.work.dir=\"/tmp/\${EXECUTOR_NUMBER}\" " + - "-Ddocker.build.tag=\"\${DOCKER_TAG_TO_USE}\"" + - " clean preAllocateForAllParallelUnitTest preAllocateForAllParallelIntegrationTest pushBuildImage --stacktrace" - } - sh "kubectl auth can-i get pods" + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'clean', + 'jar' + ].join(' ') } } - stage('Corda Pull Request - Run Tests') { + stage('Stash') { + steps { + stash name: 'compiled', useDefaultExcludes: false + } + } + + stage('All Tests') { parallel { - stage('Integration Tests') { - steps { - sh "./gradlew --no-daemon " + - "-DbuildId=\"\${BUILD_ID}\" " + - "-Dkubenetize=true " + - "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + - "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + - "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + - "-Dgit.branch=\"\${GIT_BRANCH}\" " + - "-Dgit.target.branch=\"\${CHANGE_TARGET}\" " + - " allParallelIntegrationTest --stacktrace" + stage('Another agent') { + agent { + label 'standard' + } + options { + skipDefaultCheckout true + } + post { + always { + archiveArtifacts artifacts: '**/*.log', fingerprint: false + junit testResults: '**/build/test-results/**/*.xml', keepLongStdio: true + } + cleanup { + deleteDir() /* clean up our workspace */ + } + } + stages { + stage('Unstash') { + steps { + unstash 'compiled' + } + } + stage('Recompile') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'jar' + ].join(' ') + } + } + stage('Unit Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'test' + ].join(' ') + } + } } } - stage('Unit Tests') { - steps { - sh "./gradlew --no-daemon " + - "-DbuildId=\"\${BUILD_ID}\" " + - "-Dkubenetize=true " + - "-Ddocker.run.tag=\"\${DOCKER_TAG_TO_USE}\" " + - "-Dartifactory.username=\"\${ARTIFACTORY_CREDENTIALS_USR}\" " + - "-Dartifactory.password=\"\${ARTIFACTORY_CREDENTIALS_PSW}\" " + - "-Dgit.branch=\"\${GIT_BRANCH}\" " + - "-Dgit.target.branch=\"\${CHANGE_TARGET}\" " + - " allParallelUnitTest --stacktrace" + stage('Same agent') { + post { + always { + archiveArtifacts artifacts: '**/*.log', fingerprint: false + junit testResults: '**/build/test-results/**/*.xml', keepLongStdio: true + } + } + stages { + stage('Integration Test') { + steps { + sh script: [ + './gradlew', + COMMON_GRADLE_PARAMS, + 'integrationTest' + ].join(' ') + } + } } } } @@ -67,10 +126,6 @@ pipeline { } post { - always { - archiveArtifacts artifacts: '**/pod-logs/**/*.log', fingerprint: false - junit testResults: '**/build/test-results-xml/**/*.xml', keepLongStdio: true - } cleanup { deleteDir() /* clean up our workspace */ }