Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-41239

Error during always block skips execution of remaining steps

      Here's a trivial example of a general problem:

      pipeline {
          agent any
          stages {
              stage ("Example") {
                  steps {
                      // Install dependencies
                      sh 'npm install'
                      echo 'Execute build that creates artifacts'
                      echo 'Execute step that fails to create the expected junit test file'
                  }
              }
          }
          post {
              always {
                  junit 'reports/**'
                  echo 'This step and everything after it won't run.'
                  archive '**'
                  echo "send email to people with final build status"
              }
          }
      }
      

      I have an always block, but I can't actually guarantee that all steps in that always block will all always attempt to run.

      In Scripted Pipeline I could wrap each of these in a try-catch, but I can't do that in Declarative.

      I can reorder these steps to put the ones that I know won't fail earlier, but what about the email step? I want that to be last, so it gets the proper build status in the email.

      abayer suggested a catchError block. But depending on which step fails, that doesn't get the right behavior either. I want each step in the always to run exactly once no matter the build status. If the second step fails the catchError can't tell which one failed and not to run the first step again.

      Logically what I would expect to work:

      pipeline {
          agent any
          stages {
              stage ("Example") {
                  steps {
                      // Install dependencies
                      sh 'npm install'
                      echo 'Execute build that creates artifacts'
                      echo 'Execute step that fails to create the expected junit test file'
                  }
              }
          }
          post {
              always {
                  junit 'reports/**'
              }
              always {
                  echo 'This step and everything after it won't run.'
              }
              always {
                  archive '**
              }
              always {
                  echo "send email to people with final build status"
              }
          }
      }
      

      However, I'm not allowed to have more than one always block.

          [JENKINS-41239] Error during always block skips execution of remaining steps

          Liam Newman added a comment - - edited

          Oh, stages can have post steps. I forgot about that. That gives a workaround and also some guidance about structure.

          It might go something like this:

          pipeline {
              agent any
              stages {
                  stage ("Prepare Dependencies") {
                      steps {
                          // Install dependencies
                          sh 'npm install'
                      }
                  }
                  stage ("Build") {
                      steps {
                          echo 'Execute build that creates artifacts'
                      }
                      post {
                         success {
                              archive 'output/**'
                          }
                         always {
                              archive 'logs/**'
                          }
                      }
                  }
                  stage ("Test") {
                      steps {
                          echo 'Execute build that creates artifacts'
                      }
                      post {
                         always {
                              junit 'reports/**'
                          }
                      }
                  }
              }
              post {
                  always {
                      echo "send email to people with final build status"
                  }
              }
          }
          

          Cool, I can live with this.

          Liam Newman added a comment - - edited Oh, stages can have post steps. I forgot about that. That gives a workaround and also some guidance about structure. It might go something like this: pipeline { agent any stages { stage ( "Prepare Dependencies" ) { steps { // Install dependencies sh 'npm install' } } stage ( "Build" ) { steps { echo 'Execute build that creates artifacts' } post { success { archive 'output/**' } always { archive 'logs/**' } } } stage ( "Test" ) { steps { echo 'Execute build that creates artifacts' } post { always { junit 'reports/**' } } } } post { always { echo "send email to people with final build status" } } } Cool, I can live with this.

          The workaround mentioned here doesn't work for me. Are there any plans to address this issue?

          Currently, I have to use

          post { always { catchError { ... } cleanWs() } }

          everywhere to make sure I always clean up my workspaces. This workaround introduces another bug, though: Incorrect archiveArtifacts configurations in the catchError block will be completely ignored.

          Moritz Baumann added a comment - The workaround mentioned here doesn't work for me. Are there any plans to address this issue? Currently, I have to use post { always { catchError { ... } cleanWs() } } everywhere to make sure I always clean up my workspaces. This workaround introduces another bug, though: Incorrect archiveArtifacts configurations in the catchError block will be completely ignored.

          Moritz Baumann added a comment - - edited

          When I discovered this problem, my first instinct was to add a second always closure, but Jenkins didn't accept that. Maybe allowing this would be a good solution to the underlying problem?

          Edit: Sorry, completely missed that this is already mentioned above.

          Moritz Baumann added a comment - - edited When I discovered this problem, my first instinct was to add a second always closure, but Jenkins didn't accept that. Maybe allowing this would be a good solution to the underlying problem? Edit : Sorry, completely missed that this is already mentioned above.

          Andrew Bayer added a comment -

          I've got a PR up at https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/258 that adds a new post condition, currently called cleanup, which runs regardless of build status but after all the other conditions have resolved.

          Andrew Bayer added a comment - I've got a PR up at https://github.com/jenkinsci/pipeline-model-definition-plugin/pull/258 that adds a new post condition, currently called cleanup , which runs regardless of build status but after all the other conditions have resolved.

          abayer thank you very much! While it doesn't fix the original issue, it very much fixes my use case. Especially the fact that `always` ran before `success` was giving me headaches.

          Moritz Baumann added a comment - abayer thank you very much! While it doesn't fix the original issue, it very much fixes my use case. Especially the fact that `always` ran before `success` was giving me headaches.

          Code changed in jenkins
          User: Andrew Bayer
          Path:
          pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/conditions/Cleanup.groovy
          pipeline-model-definition/src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/model/conditions/Messages.properties
          pipeline-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/BuildConditionResponderTest.java
          pipeline-model-definition/src/test/resources/postChecksAllConditions.groovy
          http://jenkins-ci.org/commit/pipeline-model-definition-plugin/83abd0ec35960c1f2a37b6a66b2d26385b2962e2
          Log:
          [FIXED JENKINS-41239] Add new cleanup post condition

          The new `cleanup` condition will always run regardless of build
          status, like `always`, but runs after all other `post` conditions
          have been evaluated, rather than before.

          I wanted to call this `finally` but that actually breaks Groovy
          parsing because `finally` is a reserved word. Dang. So for now, I'm
          calling it `cleanup`, but am open to suggestions.

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Andrew Bayer Path: pipeline-model-definition/src/main/groovy/org/jenkinsci/plugins/pipeline/modeldefinition/model/conditions/Cleanup.groovy pipeline-model-definition/src/main/resources/org/jenkinsci/plugins/pipeline/modeldefinition/model/conditions/Messages.properties pipeline-model-definition/src/test/java/org/jenkinsci/plugins/pipeline/modeldefinition/BuildConditionResponderTest.java pipeline-model-definition/src/test/resources/postChecksAllConditions.groovy http://jenkins-ci.org/commit/pipeline-model-definition-plugin/83abd0ec35960c1f2a37b6a66b2d26385b2962e2 Log: [FIXED JENKINS-41239] Add new cleanup post condition The new `cleanup` condition will always run regardless of build status, like `always`, but runs after all other `post` conditions have been evaluated, rather than before. I wanted to call this `finally` but that actually breaks Groovy parsing because `finally` is a reserved word. Dang. So for now, I'm calling it `cleanup`, but am open to suggestions.

          Andrew Bayer added a comment -

          Merged, releasing later today in Declarative 1.2.9

          Andrew Bayer added a comment - Merged, releasing later today in Declarative 1.2.9

          Code changed in jenkins
          User: Andrew Bayer
          Path:
          content/doc/book/pipeline/syntax.adoc
          http://jenkins-ci.org/commit/jenkins.io/c8c7bce2e7c5955d5176f0791800156cf0c087a2
          Log:
          JENKINS-41239 Add doc for new cleanup post condition.

          This was just released in Declarative 1.2.9 so this should be ready to
          go whenever works for you.

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: Andrew Bayer Path: content/doc/book/pipeline/syntax.adoc http://jenkins-ci.org/commit/jenkins.io/c8c7bce2e7c5955d5176f0791800156cf0c087a2 Log: JENKINS-41239 Add doc for new cleanup post condition. This was just released in Declarative 1.2.9 so this should be ready to go whenever works for you.

          Code changed in jenkins
          User: R. Tyler Croy
          Path:
          content/doc/book/pipeline/syntax.adoc
          http://jenkins-ci.org/commit/jenkins.io/5c434e826c79dc06f837a6d244c9ddf5df1fa382
          Log:
          Merge pull request #1504 from abayer/jenkins-41239

          JENKINS-41239 Add doc for new cleanup post condition.

          Compare: https://github.com/jenkins-infra/jenkins.io/compare/92e468e7f66b...5c434e826c79

          SCM/JIRA link daemon added a comment - Code changed in jenkins User: R. Tyler Croy Path: content/doc/book/pipeline/syntax.adoc http://jenkins-ci.org/commit/jenkins.io/5c434e826c79dc06f837a6d244c9ddf5df1fa382 Log: Merge pull request #1504 from abayer/jenkins-41239 JENKINS-41239 Add doc for new cleanup post condition. Compare: https://github.com/jenkins-infra/jenkins.io/compare/92e468e7f66b...5c434e826c79

          Liam Newman added a comment -

          Bulk closing resolved issues.

          Liam Newman added a comment - Bulk closing resolved issues.

            abayer Andrew Bayer
            bitwiseman Liam Newman
            Votes:
            1 Vote for this issue
            Watchers:
            8 Start watching this issue

              Created:
              Updated:
              Resolved: