Cleanest way to prematurely exit a Jenkins Pipeline job as a success?

59

10

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.

Alex

Posted 2017-04-13T15:31:13.043

Reputation: 3 120

1Just exit 0...Tensibai 2017-04-13T15:33:49.047

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 answerAlex 2017-04-13T15:35:11.040

Well, just bash scripts, exit 0 means success, exit non zero means failure...Tensibai 2017-04-13T15:36:08.557

This isn't within a bash script, this is the pipeline job itself, so Groovy. Does that change things?Alex 2017-04-13T15:36:47.663

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 infirmTensibai 2017-04-13T16:04:01.167

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.Aurora0001 2017-04-13T16:11:40.287

@Aurora0001 Nope, there's multiple stages left; this comes almost first thing in a 7 step job.Alex 2017-04-13T16:12:52.567

Answers

50

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.

Alex

Posted 2017-04-13T15:31:13.043

Reputation: 3 120

just returning should leave the build with a grayed out status and no result... so not quite the same as a failed build.drewish 2017-10-28T18:47:59.070

1How do you return and skip all remaining stages?Jess Bowers 2017-11-13T22:30:12.537

1@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.Alex 2017-11-14T13:52:13.443

4Please note that it works only for scripted pipeline, not for declarativekagarlickij 2018-03-28T11:01:42.900

@kagarlickij - Correct, declarative pipelines didn't exist when this answer was written!Alex 2018-03-28T12:34:57.540

I don't think there's a good way to do this in declarative pipeline, is that right?Tri Nguyen 2018-06-21T15:55:49.027

@TriNguyen No idea sorry, we're still using scripted at my work. Ask a new question and reference this one?Alex 2018-06-21T16:11:50.400

Great, thanks. Btw, no need for currentBuild.result='SUCCESS' it's defaulted.Lazyexpert 2018-08-10T11:07:20.917

11

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

It depends on your requirements, which way you want to use.

CSchulz

Posted 2017-04-13T15:31:13.043

Reputation: 211

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 flagMichael Mrozek 2018-10-15T16:24:32.360

1

Honestly you shouldn't need to use exit command specifically, but there is a 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

MrMesees

Posted 2017-04-13T15:31:13.043

Reputation: 111

1While 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.Alex 2017-04-15T00:18:30.690

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.MrMesees 2017-04-16T19:57:50.090

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.MrMesees 2017-04-16T20:15:47.363

1Ahh 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.Alex 2017-04-16T23:34:26.140

3I've tried to make it clearer, no need to apologize at all, language is a fickle beast, especially on the internet :)MrMesees 2017-04-17T08:46:54.560

0

The Executor.interrupt(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)
}

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. Approve and use with caution.

Ben Amos

Posted 2017-04-13T15:31:13.043

Reputation: 101

For me it doesn't work - consecutive stages are being executed.Łukasz K 2019-10-30T07:55:03.050