Answers: <p>I was <em>almost</em> able to accomplish this with declarative pipeline. This allows you to exit the before the pipeline starts based on the outcome of a shell script. I was not able to get this working within the pipeline itself (either within or between stages).</p>
  
  <pre><code>node('master'){
      env.status_code = sh(script: 'exit 0 # or 200 or other', returnStatus:true)
  }
  println 'status_code: ' + env.status_code
  if(env.status_code == '200'){
      println 'Now is not the time to run the pipeline.'
      println 'Exiting without running subsequent stages.'
      currentBuild.result = 'SUCCESS'
      return
  } else if(env.status_code == '0'){
      println 'Time to run. Let\'s go!'
  } else {
      error 'Unable to check if it\'s time to run.'
  }
  
  pipeline {
    agent any
    stages {
        stage('Run only if exit status for was 0'){
            steps{
               sh 'echo hi'
            }
        }
    }
  }
  </code></pre>
  
  <p><code>when</code> directive may help if you only want to skip certain stages, not exit entirely.</p>
  
  <p><a href="https://www.jenkins.io/doc/book/pipeline/syntax/#when" rel="nofollow noreferrer">https://www.jenkins.io/doc/book/pipeline/syntax/#when</a></p>
  
Answers: CC BY-SA 4.0
Answers: 2020-05-07T00:55:38.910Z
Answers: 2020-05-07T00:55:38.910Z
Answers: Katrina Brock
Answers: <p>The <a href="https://javadoc.jenkins-ci.org/hudson/model/Executor.html#interrupt-hudson.model.Result-" rel="noreferrer"><code>Executor.interrupt(Result)</code></a> method is the cleanest, most direct way I could find to stop a build prematurely <em>and</em> mark it as a success.</p>
  
  <pre><code>script {
      currentBuild.getRawBuild().getExecutor().interrupt(Result.SUCCESS)
      sleep(1)   // Interrupt is not blocking and does not take effect immediately.
  }
  </code></pre>
  
  <p><strong>Pros</strong>:</p>
  
  <ul>
  <li>Works in a declarative pipeline just as well as a scripted one.</li>
  <li>No try/catch or exceptions to handle.</li>
  <li>Marks the calling stage and any successive stages as green/passing in the UI.</li>
  </ul>
  
  <p><strong>Cons</strong>:</p>
  
  <ul>
  <li>Requires a number of in-process script approvals, including one that is <a href="https://github.com/jenkinsci/script-security-plugin/pull/69" rel="noreferrer">considered insecure</a>. Approve and use with caution.</li>
  </ul>
  
Answers: CC BY-SA 4.0
Answers: 2019-10-30T07:55:03.050Z
Answers: For me it doesn't work - consecutive stages are being executed.
Answers: Łukasz K
Answers: CC BY-SA 4.0
Answers: 2020-01-16T16:21:44.560Z
Answers: Can you put this before a stage in a declarative pipeline?
Answers: peetasan
Answers: CC BY-SA 4.0
Answers: 2020-01-16T22:30:34.357Z
Answers: In a declarative pipeline, script blocks are valid only inside of a stage's steps block. If you need to stop execution as described before a given stage, you will need to execute the script during a preceding stage.
Answers: Ben Amos
Answers: CC BY-SA 4.0
Answers: 2020-02-06T08:32:32.763Z
Answers: `org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild`
Answers: Devaroop
Answers: CC BY-SA 4.0
Answers: 2020-02-11T00:16:16.570Z
Answers: Yes, that is what I referred to in my "Cons" section.
Answers: Ben Amos
Answers: CC BY-SA 4.0
Answers: 2020-08-25T22:45:53.950Z
Answers: If you need to stop the build with a particular variable result, you can replace `Result.SUCCESS` with the fromString static method (such as `Result.fromString('UNSTABLE')` ). (Warning: requires an additional in-process script approval.)
Answers: Cameron Hudson
Answers: CC BY-SA 4.0
Answers: 2019-10-23T17:08:30.497Z
Answers: 2020-01-16T23:10:13.997Z
Answers: 2020-01-16T23:10:13.997Z
Answers: Ben Amos
Answers: <p>You can also use error to exit the current stage, then you don't have to consider the current stage hierarchy and similar stuff:</p>
  
  <pre><code>def autoCancelled = false
  
  try {
    stage('checkout') {
      ...
      if (your condition) {
        autoCancelled = true
        error('Aborting the build.')
      }
    }
  } catch (e) {
    if (autoCancelled) {
      currentBuild.result = 'SUCCESS'
      // return here instead of throwing error to keep the build "green"
      return
    }
    // normal error handling
    throw e
  }
  </code></pre>
  
  <p>But this would lead to a red stage, if the error occurs within a stage.</p>
  
  <p><a href="https://i.sstatic.net/Q9UDp.png" rel="noreferrer"><img src="https://i.sstatic.net/Q9UDp.png" alt="enter image description here"></a></p>
  
  <p>It depends on your requirements, which way you want to use.</p>
  
Answers: CC BY-SA 4.0
Answers: 2018-10-15T16:24:32.360Z
Answers: If you're going to do it this way, make a new subclass of `RuntimeException` to throw instead of needing to catch all exceptions and check a flag
Answers: Michael Mrozek
Answers: CC BY-SA 4.0
Answers: 2021-04-26T18:23:57.323Z
Answers: I could not get this to work with Jenkins 2.263.3. `WorkflowScript: 23: Expected a stage` at the line with the `try` and after that: `WorkflowScript: 22: No stages specified`
Answers: Peter V. Mørch
Answers: CC BY-SA 4.0
Answers: 2018-07-10T11:29:46.037Z
Answers: 2018-07-10T11:29:46.037Z
Answers: CSchulz
Answers: <p>If it is acceptable to set the build status to <code>ABORTED</code> instead of <code>SUCCESS</code>, the following snippet may be used within a pipeline stage to short-circuit the build:</p>
  <pre class="lang-groovy prettyprint-override"><code>steps {
      script {
          currentBuild.result = 'ABORTED'
          error(&quot;Aborting the build.&quot;)
      }
  }
  </code></pre>
  <p>I tested setting the result to <code>SUCCESS</code>, but doing so resulted in a failed build (using Jenkins 2.235.5). It seems that <code>ABORTED</code> is respected by the <code>error</code> step, while <code>SUCCESS</code> is overridden.</p>
  
Answers: CC BY-SA 4.0
Answers: 2020-11-16T23:02:59.800Z
Answers: 2021-09-19T12:06:11.897Z
Answers: 2021-09-19T12:06:11.897Z
Answers: kgriffs
Answers: <p>Honestly you shouldn't need to use the <code>exit</code> command specifically, but there is a <a href="https://wiki.jenkins-ci.org/display/JENKINS/Conditional+BuildStep+Plugin" rel="nofollow noreferrer">Conditional BuildStep Plugin</a> which may achieve the same end result (code that doesn't run).</p>
  <p>I haven't come up against this yet, so haven't used the plugin.</p>
  <p>There is also conditionals as found in this prior Stack Overflow post on Jenkins: <a href="https://stackoverflow.com/questions/37690920/jenkins-pipeline-conditional-step-stage">Jenkins Pipeline Conditional Step/Stage</a></p>
  
Answers: CC BY-SA 3.0
Answers: 2017-04-15T00:18:30.690Z
Answers: While your answer seems to be valid (haven't checked it live since I found another workaround), I don't think "Honestly you shouldn't exit" is a good way to start it; clearly the existence of these methods means it IS sometimes necessary to exit.
Answers: Alex
Answers: CC BY-SA 3.0
Answers: 2017-04-16T19:57:50.090Z
Answers: What would you suggest? Moving to an ending statement? Adding the qualifier "generally"? You've provided "feedback" but it's not easy for me to tell the intent or action it, please be less terse.
Answers: MrMesees
Answers: CC BY-SA 3.0
Answers: 2017-04-16T20:15:47.363Z
Answers: Hang on a bit. Is it your question? If it is, TBH you wouldn't want to hear you shouldn't exit, but neither method I've suggested provide exits, they circumvent code running... Directly supporting my position.
Answers: MrMesees
Answers: CC BY-SA 3.0
Answers: 2017-04-16T23:34:26.140Z
Answers: Ahh I see, I think I misinterpreted your statement as "doing something to end the job is bad" instead of "you shouldn't use the literal `exit` command" - if so I apologize, that's my misunderstanding.
Answers: Alex
Answers: CC BY-SA 3.0
Answers: 2017-04-17T08:46:54.560Z
Answers: I've tried to make it clearer, no need to apologize at all, language is a fickle beast, especially on the internet :)
Answers: MrMesees
Answers: CC BY-SA 4.0
Answers: 2017-04-14T21:30:00.663Z
Answers: 2023-07-11T15:44:45.563Z
Answers: 2023-07-11T15:44:45.563Z
Answers: MrMesees
Answers: <p>Please note: The following works for scripted pipelines only. For a solution for declarative pipelines see <a href="https://devops.stackexchange.com/a/12776/24991">@kgriffs' answer</a>.</p>
  <p>---</p>
  <p>Figured it out. <strong>Outside of any stages</strong> (otherwise this will just end the particular stage as a success) do the following;</p>
  <pre><code>if( $VALUE1 == $VALUE2 ) {
     currentBuild.result = 'SUCCESS'
     return
  }
  </code></pre>
  <p><code>return</code> <strong>will stop the stage or node you're running on</strong> which is why running it outside of a stage is important, while setting the <code>currentBuild.result</code> prevents it from failing.</p>
  
Answers: CC BY-SA 4.0
Answers: 2021-03-30T10:53:52.247Z
Answers: For delcarative pipeline when directive working good.
Answers: Ivan Cherviakov
Answers: CC BY-SA 3.0
Answers: 2017-10-28T18:47:59.070Z
Answers: just returning should leave the build with a grayed out status and no result... so not quite the same as a failed build.
Answers: drewish
Answers: CC BY-SA 3.0
Answers: 2017-11-13T22:30:12.537Z
Answers: How do you return and skip all remaining stages?
Answers: Jess Bowers
Answers: CC BY-SA 3.0
Answers: 2017-11-14T13:52:13.443Z
Answers: @JessBowers it's all about where you put the snippet. If you do it node-level rather than stage-level it'll finish the entire job.
Answers: Alex
Answers: CC BY-SA 3.0
Answers: 2018-03-28T11:01:42.900Z
Answers: Please note that it works only for scripted pipeline, not for declarative
Answers: kagarlickij
Answers: CC BY-SA 3.0
Answers: 2018-03-28T12:34:57.540Z
Answers: @kagarlickij - Correct, declarative pipelines didn't exist when this answer was written!
Answers: Alex
Answers: CC BY-SA 4.0
Answers: 2018-06-21T15:55:49.027Z
Answers: I don't think there's a good way to do this in declarative pipeline, is that right?
Answers: Tri Nguyen
Answers: CC BY-SA 4.0
Answers: 2018-06-21T16:11:50.400Z
Answers: @TriNguyen No idea sorry, we're still using scripted at my work. Ask a new question and reference this one?
Answers: Alex
Answers: CC BY-SA 4.0
Answers: 2018-08-10T11:07:20.917Z
Answers: Great, thanks. Btw, no need for `currentBuild.result='SUCCESS'` it's defaulted.
Answers: Lazyexpert
Answers: CC BY-SA 4.0
Answers: 2017-04-13T17:36:29.043Z
Answers: 2021-09-20T14:06:52.540Z
Answers: 2021-09-20T14:06:52.540Z
Answers: Alex
Body: <p>I have a job that will create files, unless one of the values being fed to it matches an older value. What's the cleanest way in Jenkins to abort or exit the job, <strong>without</strong> it being <code>FAILED</code>? It exiting is the correct behavior so I want the build marked <code>SUCCESS</code>.</p>
  
  <p>It'll end up in an if statement like so;</p>
  
  <pre><code>stage ('Check value') {
  
       if( $VALUE1 == $VALUE2 ) {
         //if they do match exit as a success, else continue with the rest of the job 
      }
  
  }
  </code></pre>
  
  <p>I don't want to throw an error code unless that can somehow translate into it being marked a successful build.</p>
  
Comments: CC BY-SA 3.0
Comments: 2017-04-13T15:33:49.047Z
Comments: Just `exit 0`...
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-04-13T15:35:11.040Z
Comments: I thought that marked the job a failure? If I'm wrong and you can show documentation, I'd be happy to accept that as an answer
Comments: Alex
Comments: CC BY-SA 3.0
Comments: 2017-04-13T15:36:08.557Z
Comments: Well, just bash scripts, exit 0 means success, exit non zero means failure...
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-04-13T15:36:47.663Z
Comments: This isn't within a bash script, this is the pipeline job itself, so Groovy. Does that change things?
Comments: Alex
Comments: CC BY-SA 3.0
Comments: 2017-04-13T16:04:01.167Z
Comments: In groovy I'd just try a `return 0`, all in all any end of the groovy code which doesn't throw an exception should do I think. I'll let someone with more background on jenkins 2 confirm or infirm
Comments: Tensibai
Comments: CC BY-SA 3.0
Comments: 2017-04-13T16:11:40.287Z
Comments: Could you not flip the logic around and `if ($VALUE1 != $VALUE2) { /* rest of job */ }` ? This should implicitly end the job (because there is no more code) if they **are** equal.
Comments: Aurora0001
Comments: CC BY-SA 3.0
Comments: 2017-04-13T16:12:52.567Z
Comments: @Aurora0001 Nope, there's multiple stages left; this comes almost first thing in a 7 step job.
Comments: Alex
Tags: <jenkins><jenkins-pipeline><groovy>
Title: Cleanest way to prematurely exit a Jenkins Pipeline job as a success?
UserDisplayName: Alex
ThreadText: # Cleanest way to prematurely exit a Jenkins Pipeline job as a success?
  
  (Asked by: username_0 on 2017-04-13)
  
  I have a job that will create files, unless one of the values being fed to it matches an older value. What's the cleanest way in Jenkins to abort or exit the job, **without** it being `FAILED`? It exiting is the correct behavior so I want the build marked `SUCCESS`.
  
  It'll end up in an if statement like so;
  
  ```
  stage ('Check value') {
  
       if( $VALUE1 == $VALUE2 ) {
         //if they do match exit as a success, else continue with the rest of the job 
      }
  
  }
  
  ```
  
  I don't want to throw an error code unless that can somehow translate into it being marked a successful build.
  
  **Tags:** jenkins, jenkins-pipeline, groovy
  
  > **Comments:**
  > **username_1**: Just `exit 0`...  
  > **username_0**: I thought that marked the job a failure? If I'm wrong and you can show documentation, I'd be happy to accept that as an answer  
  > **username_1**: Well, just bash scripts, exit 0 means success, exit non zero means failure...  
  > **username_0**: This isn't within a bash script, this is the pipeline job itself, so Groovy. Does that change things?  
  > **username_1**: In groovy I'd just try a `return 0`, all in all any end of the groovy code which doesn't throw an exception should do I think. I'll let someone with more background on jenkins 2 confirm or infirm  
  > **username_2**: Could you not flip the logic around and `if ($VALUE1 != $VALUE2) { /* rest of job */ }` ? This should implicitly end the job (because there is no more code) if they **are** equal.  
  > **username_0**: @username_2 Nope, there's multiple stages left; this comes almost first thing in a 7 step job.  
  
  ---
  
  ## 6 answers
  
  ### Answer by username_0 on 2017-04-13. Score: 97 | Accepted answer
  
  Please note: The following works for scripted pipelines only. For a solution for declarative pipelines see [@username_12' answer](https://devops.stackexchange.com/a/12776/24991).
  
  ---
  
  Figured it out. **Outside of any stages** (otherwise this will just end the particular stage as a success) do the following;
  
  ```
  if( $VALUE1 == $VALUE2 ) {
     currentBuild.result = 'SUCCESS'
     return
  }
  
  ```
  
  `return` **will stop the stage or node you're running on** which is why running it outside of a stage is important, while setting the `currentBuild.result` prevents it from failing.
  
  > **Comments:**
  > **username_15**: just returning should leave the build with a grayed out status and no result... so not quite the same as a failed build.  
  > **username_16**: How do you return and skip all remaining stages?  
  > **username_0**: @username_16 it's all about where you put the snippet. If you do it node-level rather than stage-level it'll finish the entire job.  
  > **username_17**: Please note that it works only for scripted pipeline, not for declarative  
  > **username_0**: @username_17 - Correct, declarative pipelines didn't exist when this answer was written!  
  > **username_18**: I don't think there's a good way to do this in declarative pipeline, is that right?  
  > **username_0**: @username_18 No idea sorry, we're still using scripted at my work. Ask a new question and reference this one?  
  > **username_19**: Great, thanks. Btw, no need for `currentBuild.result='SUCCESS'` it's defaulted.  
  > **username_14**: For delcarative pipeline when directive working good.  
  
  ---
  
  ### Answer by username_4 on 2019-10-23. Score: 26
  
  The [`Executor.interrupt(Result)`](https://javadoc.jenkins-ci.org/username_8/model/Executor.html#interrupt-username_8.model.Result-) method is the cleanest, most direct way I could find to stop a build prematurely *and* mark it as a success.
  
  ```
  script {
      currentBuild.getRawBuild().getExecutor().interrupt(Result.SUCCESS)
      sleep(1)   // Interrupt is not blocking and does not take effect immediately.
  }
  
  ```
  
  **Pros**:
  
  * Works in a declarative pipeline just as well as a scripted one.
  * No try/catch or exceptions to handle.
  * Marks the calling stage and any successive stages as green/passing in the UI.
  
  **Cons**:
  
  * Requires a number of in-process script approvals, including one that is [considered insecure](https://github.com/jenkinsci/script-security-plugin/pull/69). Approve and use with caution.
  
  > **Comments:**
  > **username_5**: For me it doesn't work - consecutive stages are being executed.  
  > **username_6**: Can you put this before a stage in a declarative pipeline?  
  > **username_4**: In a declarative pipeline, script blocks are valid only inside of a stage's steps block. If you need to stop execution as described before a given stage, you will need to execute the script during a preceding stage.  
  > **username_7**: `org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use method org.jenkinsci.plugins.workflow.support.steps.build.RunWrapper getRawBuild`  
  > **username_4**: Yes, that is what I referred to in my "Cons" section.  
  > **username_8**: If you need to stop the build with a particular variable result, you can replace `Result.SUCCESS` with the fromString static method (such as `Result.fromString('UNSTABLE')` ). (Warning: requires an additional in-process script approval.)  
  
  ---
  
  ### Answer by username_9 on 2018-07-10. Score: 23
  
  You can also use error to exit the current stage, then you don't have to consider the current stage hierarchy and similar stuff:
  
  ```
  def autoCancelled = false
  
  try {
    stage('checkout') {
      ...
      if (your condition) {
        autoCancelled = true
        error('Aborting the build.')
      }
    }
  } catch (e) {
    if (autoCancelled) {
      currentBuild.result = 'SUCCESS'
      // return here instead of throwing error to keep the build "green"
      return
    }
    // normal error handling
    throw e
  }
  
  ```
  
  But this would lead to a red stage, if the error occurs within a stage.
  
  [![enter image description here](https://i.sstatic.net/Q9UDp.png)](https://i.sstatic.net/Q9UDp.png)
  
  It depends on your requirements, which way you want to use.
  
  > **Comments:**
  > **username_10**: If you're going to do it this way, make a new subclass of `RuntimeException` to throw instead of needing to catch all exceptions and check a flag  
  > **username_11**: I could not get this to work with Jenkins 2.263.3. `WorkflowScript: 23: Expected a stage` at the line with the `try` and after that: `WorkflowScript: 22: No stages specified`  
  
  ---
  
  ### Answer by username_12 on 2020-11-16. Score: 13
  
  If it is acceptable to set the build status to `ABORTED` instead of `SUCCESS`, the following snippet may be used within a pipeline stage to short-circuit the build:
  
  ```groovy
  steps {
      script {
          currentBuild.result = 'ABORTED'
          error("Aborting the build.")
      }
  }
  
  ```
  
  I tested setting the result to `SUCCESS`, but doing so resulted in a failed build (using Jenkins 2.235.5). It seems that `ABORTED` is respected by the `error` step, while `SUCCESS` is overridden.
  
  
  ---
  
  ### Answer by username_3 on 2020-05-07. Score: 4
  
  I was *almost* able to accomplish this with declarative pipeline. This allows you to exit the before the pipeline starts based on the outcome of a shell script. I was not able to get this working within the pipeline itself (either within or between stages).
  
  ```
  node('master'){
      env.status_code = sh(script: 'exit 0 # or 200 or other', returnStatus:true)
  }
  println 'status_code: ' + env.status_code
  if(env.status_code == '200'){
      println 'Now is not the time to run the pipeline.'
      println 'Exiting without running subsequent stages.'
      currentBuild.result = 'SUCCESS'
      return
  } else if(env.status_code == '0'){
      println 'Time to run. Let\'s go!'
  } else {
      error 'Unable to check if it\'s time to run.'
  }
  
  pipeline {
    agent any
    stages {
        stage('Run only if exit status for was 0'){
            steps{
               sh 'echo hi'
            }
        }
    }
  }
  
  ```
  
  `when` directive may help if you only want to skip certain stages, not exit entirely.
  
  <https://www.jenkins.io/doc/book/pipeline/syntax/#when>
  
  
  ---
  
  ### Answer by username_13 on 2017-04-14. Score: 1
  
  Honestly you shouldn't need to use the `exit` command specifically, but there is a [Conditional BuildStep Plugin](https://wiki.jenkins-ci.org/display/JENKINS/Conditional+BuildStep+Plugin) which may achieve the same end result (code that doesn't run).
  
  I haven't come up against this yet, so haven't used the plugin.
  
  There is also conditionals as found in this prior Stack Overflow post on Jenkins: [Jenkins Pipeline Conditional Step/Stage](https://stackoverflow.com/questions/37690920/jenkins-pipeline-conditional-step-stage)
  
  > **Comments:**
  > **username_0**: While your answer seems to be valid (haven't checked it live since I found another workaround), I don't think "Honestly you shouldn't exit" is a good way to start it; clearly the existence of these methods means it IS sometimes necessary to exit.  
  > **username_13**: What would you suggest? Moving to an ending statement? Adding the qualifier "generally"? You've provided "feedback" but it's not easy for me to tell the intent or action it, please be less terse.  
  > **username_13**: Hang on a bit. Is it your question? If it is, TBH you wouldn't want to hear you shouldn't exit, but neither method I've suggested provide exits, they circumvent code running... Directly supporting my position.  
  > **username_0**: Ahh I see, I think I misinterpreted your statement as "doing something to end the job is bad" instead of "you shouldn't use the literal `exit` command" - if so I apologize, that's my misunderstanding.  
  > **username_13**: I've tried to make it clearer, no need to apologize at all, language is a fickle beast, especially on the internet :)  
  
  ---
  
  