Properly suppress exceptions thrown in finally blocks in Jenkinsfile
This commit is contained in:
parent
bcbae00552
commit
2a8183371f
|
@ -132,7 +132,7 @@ stage('Build') {
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
checkout scm
|
checkout scm
|
||||||
}
|
}
|
||||||
try {
|
tryFinally({
|
||||||
stage('Start database') {
|
stage('Start database') {
|
||||||
switch (buildEnv.dbName) {
|
switch (buildEnv.dbName) {
|
||||||
case "edb":
|
case "edb":
|
||||||
|
@ -163,7 +163,7 @@ stage('Build') {
|
||||||
'ge.hibernate.org-access-key-pr' : 'ge.hibernate.org-access-key',
|
'ge.hibernate.org-access-key-pr' : 'ge.hibernate.org-access-key',
|
||||||
variable: 'GRADLE_ENTERPRISE_ACCESS_KEY')]) {
|
variable: 'GRADLE_ENTERPRISE_ACCESS_KEY')]) {
|
||||||
withGradle { // withDevelocity, actually: https://plugins.jenkins.io/gradle/#plugin-content-capturing-build-scans-from-jenkins-pipeline
|
withGradle { // withDevelocity, actually: https://plugins.jenkins.io/gradle/#plugin-content-capturing-build-scans-from-jenkins-pipeline
|
||||||
try {
|
tryFinally({
|
||||||
if (buildEnv.dbLockableResource == null) {
|
if (buildEnv.dbLockableResource == null) {
|
||||||
withCredentials([file(credentialsId: 'sybase-jconnect-driver', variable: 'jconnect_driver')]) {
|
withCredentials([file(credentialsId: 'sybase-jconnect-driver', variable: 'jconnect_driver')]) {
|
||||||
sh 'cp -f $jconnect_driver ./drivers/jconn4.jar'
|
sh 'cp -f $jconnect_driver ./drivers/jconn4.jar'
|
||||||
|
@ -182,16 +182,14 @@ stage('Build') {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, {
|
||||||
finally {
|
|
||||||
junit '**/target/test-results/test/*.xml,**/target/test-results/testKitTest/*.xml'
|
junit '**/target/test-results/test/*.xml,**/target/test-results/testKitTest/*.xml'
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, { // Finally
|
||||||
finally {
|
|
||||||
if ( state[buildEnv.tag]['containerName'] != null ) {
|
if ( state[buildEnv.tag]['containerName'] != null ) {
|
||||||
sh "docker rm -f ${state[buildEnv.tag]['containerName']}"
|
sh "docker rm -f ${state[buildEnv.tag]['containerName']}"
|
||||||
}
|
}
|
||||||
|
@ -199,7 +197,7 @@ stage('Build') {
|
||||||
if ( !env.CHANGE_ID && buildEnv.notificationRecipients != null ) {
|
if ( !env.CHANGE_ID && buildEnv.notificationRecipients != null ) {
|
||||||
handleNotifications(currentBuild, buildEnv)
|
handleNotifications(currentBuild, buildEnv)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -230,16 +228,13 @@ class BuildEnvironment {
|
||||||
void runBuildOnNode(String label, Closure body) {
|
void runBuildOnNode(String label, Closure body) {
|
||||||
node( label ) {
|
node( label ) {
|
||||||
pruneDockerContainers()
|
pruneDockerContainers()
|
||||||
try {
|
tryFinally(body, { // Finally
|
||||||
body()
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
// If this is a PR, we clean the workspace at the end
|
// If this is a PR, we clean the workspace at the end
|
||||||
if ( env.CHANGE_BRANCH != null ) {
|
if ( env.CHANGE_BRANCH != null ) {
|
||||||
cleanWs()
|
cleanWs()
|
||||||
}
|
}
|
||||||
pruneDockerContainers()
|
pruneDockerContainers()
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void pruneDockerContainers() {
|
void pruneDockerContainers() {
|
||||||
|
@ -314,4 +309,34 @@ String getParallelResult( RunWrapper build, String parallelBranchName ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return branch.status.result
|
return branch.status.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try-finally construct that properly suppresses exceptions thrown in the finally block.
|
||||||
|
static def tryFinally(Closure main, Closure ... finallies) {
|
||||||
|
def mainFailure = null
|
||||||
|
try {
|
||||||
|
main()
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
mainFailure = t
|
||||||
|
throw t
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
finallies.each {it ->
|
||||||
|
try {
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
if ( mainFailure ) {
|
||||||
|
mainFailure.addSuppressed( t )
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainFailure = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( mainFailure ) { // We may reach here if only the "finally" failed
|
||||||
|
throw mainFailure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ stage('Build') {
|
||||||
stage('Checkout') {
|
stage('Checkout') {
|
||||||
checkout scm
|
checkout scm
|
||||||
}
|
}
|
||||||
try {
|
tryFinally({
|
||||||
stage('Start database') {
|
stage('Start database') {
|
||||||
switch (buildEnv.dbName) {
|
switch (buildEnv.dbName) {
|
||||||
case "hsqldb_2_6":
|
case "hsqldb_2_6":
|
||||||
|
@ -175,7 +175,7 @@ stage('Build') {
|
||||||
stage('Test') {
|
stage('Test') {
|
||||||
String cmd = "./ci/build.sh ${buildEnv.additionalOptions ?: ''} ${state[buildEnv.tag]['additionalOptions'] ?: ''}"
|
String cmd = "./ci/build.sh ${buildEnv.additionalOptions ?: ''} ${state[buildEnv.tag]['additionalOptions'] ?: ''}"
|
||||||
withEnv(["RDBMS=${buildEnv.dbName}"]) {
|
withEnv(["RDBMS=${buildEnv.dbName}"]) {
|
||||||
try {
|
tryFinally({
|
||||||
if (buildEnv.dbLockableResource == null) {
|
if (buildEnv.dbLockableResource == null) {
|
||||||
withCredentials([file(credentialsId: 'sybase-jconnect-driver', variable: 'jconnect_driver')]) {
|
withCredentials([file(credentialsId: 'sybase-jconnect-driver', variable: 'jconnect_driver')]) {
|
||||||
sh 'cp -f $jconnect_driver ./drivers/jconn4.jar'
|
sh 'cp -f $jconnect_driver ./drivers/jconn4.jar'
|
||||||
|
@ -194,14 +194,12 @@ stage('Build') {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, { // Finally
|
||||||
finally {
|
|
||||||
junit '**/target/test-results/test/*.xml,**/target/test-results/testKitTest/*.xml'
|
junit '**/target/test-results/test/*.xml,**/target/test-results/testKitTest/*.xml'
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, { // Finally
|
||||||
finally {
|
|
||||||
if ( state[buildEnv.tag]['containerName'] != null ) {
|
if ( state[buildEnv.tag]['containerName'] != null ) {
|
||||||
sh "docker rm -f ${state[buildEnv.tag]['containerName']}"
|
sh "docker rm -f ${state[buildEnv.tag]['containerName']}"
|
||||||
}
|
}
|
||||||
|
@ -209,7 +207,7 @@ stage('Build') {
|
||||||
if ( !env.CHANGE_ID && buildEnv.notificationRecipients != null ) {
|
if ( !env.CHANGE_ID && buildEnv.notificationRecipients != null ) {
|
||||||
handleNotifications(currentBuild, buildEnv)
|
handleNotifications(currentBuild, buildEnv)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -239,16 +237,13 @@ class BuildEnvironment {
|
||||||
void runBuildOnNode(String label, Closure body) {
|
void runBuildOnNode(String label, Closure body) {
|
||||||
node( label ) {
|
node( label ) {
|
||||||
pruneDockerContainers()
|
pruneDockerContainers()
|
||||||
try {
|
tryFinally(body, {
|
||||||
body()
|
// If this is a PR, we clean the workspace at the end
|
||||||
}
|
if ( env.CHANGE_BRANCH != null ) {
|
||||||
finally {
|
cleanWs()
|
||||||
// If this is a PR, we clean the workspace at the end
|
}
|
||||||
if ( env.CHANGE_BRANCH != null ) {
|
pruneDockerContainers()
|
||||||
cleanWs()
|
})
|
||||||
}
|
|
||||||
pruneDockerContainers()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void pruneDockerContainers() {
|
void pruneDockerContainers() {
|
||||||
|
@ -323,4 +318,34 @@ String getParallelResult( RunWrapper build, String parallelBranchName ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return branch.status.result
|
return branch.status.result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// try-finally construct that properly suppresses exceptions thrown in the finally block.
|
||||||
|
def tryFinally(Closure main, Closure ... finallies) {
|
||||||
|
def mainFailure = null
|
||||||
|
try {
|
||||||
|
main()
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
mainFailure = t
|
||||||
|
throw t
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
finallies.each {it ->
|
||||||
|
try {
|
||||||
|
it()
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
if ( mainFailure ) {
|
||||||
|
mainFailure.addSuppressed( t )
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mainFailure = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( mainFailure ) { // We may reach here if only the "finally" failed
|
||||||
|
throw mainFailure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue