// Declarative // pipeline { agent any stages { stage('Test') { steps { sh 'make check' } } } post { always { junit '**/target/*.xml' } failure { mail to: team@example.com, subject: 'The Pipeline failed :(' } } } // Script // node { /* .. snip .. */ stage('Test') { try { sh 'make check' } finally { junit '**/target/*.xml' } } /* .. snip .. */ } Scripted Pipeline however relies on Groovy’s built-in  try / catch / finally  semantics for handling failures during execution of the Pipeline. In the [test] example above, the  sh  step was modified to never return a non-zero exit code ( sh 'make check || true' ). This approach, while valid, means the following stages need to check currentBuild.result  to know if there has been a test failure or not. An alternative way of handling this, which preserves the early-exit behavior of failures in Pipeline, while still giving  junit  the chance to capture test reports, is to use a series of  try / finally  blocks: In all the previous examples, only a single agent has been used. This means Jenkins will allocate an Using multiple agents 38