Jenkins Pipeline currentBuild duration time returns always 0

13,138

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.

Share:
13,138

Related videos on Youtube

Tomas
Author by

Tomas

Updated on June 04, 2022

Comments

  • Tomas
    Tomas almost 2 years

    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 (?)

  • Tomas
    Tomas about 7 years
    Defining global library did the trick and is useful for other stuff. Thank you
  • Jon S
    Jon S about 7 years
    Yes. global libraries is the best thing since sliced bread or maybe Jenkins is that, anyway, GPL is a great feature...
  • Tomas
    Tomas about 7 years
    It will definitely slim down some of my pipelines - eq sending slack notifications etc. Jenkins is great, I just wish there would be more and clearer documentation...
  • Vadim Kotov
    Vadim Kotov about 6 years
    Take a look at this resolved issue, looks like it was fixed.
  • FooBar
    FooBar over 3 years
    I tried doing this @JonS but got error: Scripts not permitted to use staticMethod