Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jenkins Pipeline currentBuild duration time returns always 0

I am trying to get build duration for our report but it always returns 0.

From reading docs, going through Slack plugin source and reading other resources I should be able to do one of the following:

def duration = currentBuild.duration
def duration = currentBuild.durationString
def duration = currentBuild.durationString()
def duration = currentBuild.getDurationString()

none of which works. From my understanding this might be because I am calling this before the build actually finished and so th duration is not available yet.

Structure of the pipeline looks something like this:

node {
    try {
        stage("Stage 1"){}
        stage("Stage 2"){}
    } catch (e) {
        currentBuild.result = "FAILED"
        throw e
    } finally {
        notifyBuild(currentBuild.result)
    }
}

def notifyBuild(String buildStatus = 'STARTED') {
    def duration = currentBuild.duration;
}

My question is:

  1. Why don't I get the duration
  2. Is there a way in pipeline to specify "after build" step? From what I read try-catching should work that way

My temporary solution is to use:

int jobDuration = (System.currentTimeMillis() - currentBuild.startTimeInMillis)/1000;

Which works fine, but always gives time in seconds and I think the currentBuild.duration should be smart enough to give different units (?)

like image 454
Tomas Avatar asked Feb 07 '17 10:02

Tomas


People also ask

How do I get build duration in Jenkins?

Use ${currentBuild. durationString} . Navigate to https://<your-jenkins-instance>/pipeline-syntax/globals#currentBuild for the complete list. Many pages in Jenkins expose json if you append /api/json.

What is currentBuild in Jenkins?

currentBuild is a global variable that may be used to refer to the currently running build.

How do I stop Jenkins pipeline if stage fails?

Alternatively you can call error(String message) step to stop the pipeline and set its status to FAILED . For example, if your stage 1 calls error(msg) step like: stage("Stage 1") { steps { script { error "This pipeline stops here!" } } }


1 Answers

Update 2018-02-19, this was fixed with 2.14 release of Pipeline Support API Plugin, see this issue

In unable to find any documentation about when duration is expected to be valid. But judging from the implementation it seems like it's set directly after the run/build completes. I'm guessing that it is available on the currentBuild object since it's the same object that is used for representing currentBuild.previousBuild, which may have completed.

So to answer your questions:

  1. The duration field is only valid after the build has completed.
  2. No, there is no way of specifying an "after build" step.

With that said, I think your workaround is a good solution (may be wrap it in a function and put it in an GPL (Global Public Library).

As for your final bonus question I think the currentBuild.duration should be smart enough to give different units (?). If you are referring to the nicely formatted string, like Took 10min 5sec, currentBuild.duration won't give you any nice formatting since it simply returns a long value with the number of seconds that has elapsed. Instead, what you can do is call hudson.Util#getTimeSpanString(long duration). Like this:

import hudson.Util;

...

echo "Took ${Util.getTimeSpanString(System.currentTimeMillis() - currentBuild.startTimeInMillis)}"

This will return a nicely formatted string with the current build duration.

like image 134
Jon S Avatar answered Nov 12 '22 03:11

Jon S