1

I am using Jenkins integration server for my CI/CD. I am working with freestyle projects. I want to get build duration once finished (in seconds) using RESTFUL API (JSON).

This is what i tried:

"duration=$(curl -g -u login:token--silent "$BUILD_URL/api/json?pretty=true&tree=duration" | jq -r '.duration')" 

Duration is always equel to 0 even though i did this shell script in a post buil task.

Youssef Boudaya
  • 887
  • 2
  • 17
  • 29

2 Answers2

2

There are a few reasons why this may not work for you, but the most probable reason is that the build hasn't finished when you make the API call.

I tried it on our instance and for finished jobs it works fine and for running jobs it always returns 0. If your post build task is executed as part of the job, then the job has probably not finished executing yet, which is why you are always getting 0.

Erik B
  • 40,889
  • 25
  • 119
  • 135
  • isn't the post build task supposed to run after the build is finished ? – Youssef Boudaya Aug 19 '21 at 17:55
  • I'm assuming you're using this plugin: https://plugins.jenkins.io/postbuild-task/ It's not very popular and I've never tried it, but based on the description it seems like they are mostly concerned with parsing logs. There's nothing indicating that it would run outside the actual job. It seems like it will run after everything else, but it's still part of the job. – Erik B Aug 20 '21 at 01:57
  • @YoussefBoudaya I can't tell you what the best solution is for you, but you have a few options. You can have your jobs trigger another job like Noam suggested or you could could have your post build task call an API on your dashboard that queues a task to check the duration and update the database. I think either solution is fine and mostly depends on what you're comfortable with. Another solution is to have your dashboard use Jenkins as the data source directly, rather than storing in a database what is already stored in Jenkins. – Erik B Aug 20 '21 at 02:05
  • Also, I think there are dashboards that have this functionality built in. Jenkins integration is a quite common feature. You might save yourself a lot of trouble that way, compared to implementing your own custom solution. – Erik B Aug 20 '21 at 02:07
  • i used a database because jenkins data are stored in filesystem which is complicated to me.In the jenkins post build task, i call the API to get the status (success or failure) which i assume can only be retrieved once the job is finished so naturally i tried there also to get the duration. – Youssef Boudaya Aug 20 '21 at 07:56
  • @YoussefBoudaya Try calling the API on a job you know has finished. If that returns a valid duration, then it's a timing issue. If it returns 0, then I would assume that there is a bug in the version of Jenkins you are using. Most likely your post build task is executed inside the job and not after it has finished. – Erik B Aug 20 '21 at 10:07
1

The Api call for the build will not contain the duration attribute as long as the build is running, and therefore you cannot use that mechanism during the build duration.
However you have a nice alternative for achieving what you want using Freestyle jobs.

The solution, which still uses the Api method, is to create a separate generic job for updating your data base with the results, this jobs will receive as parameters the project name and the build number, run the curl command for receiving the duration, update your database and run any other logic you need.
This job can now be called from any freestyle job using the Parameterized Trigger plugin post task with the relevant build environment parameters.
This has the additional benefit that the duration update mechanism is controlled in a single job and if updates are needed they can be made in a single location avoiding the need to update all separate jobs.
Assuming your job is called Update-Duration and it receives two parameters Project and Build the post trigger can look like the following:

enter image description here

And thats it, just add this tigger to any job that needs it, and in the future you can update the logic without changing the calling jobs.
Small thing, in order to avoid a race condition that can be caused if the caller job has not yet finished the execution you can increase the quite period of your data base updater job to allow enough time for the caller jobs to finish so the duration will be populated.

Noam Helmer
  • 5,310
  • 1
  • 9
  • 29
  • i have plenty jobs in jenkins won't this be a problem ? – Youssef Boudaya Aug 19 '21 at 17:58
  • Why should it be a problem? you are just extracting shared logic into a separate job. it is a similar concept to what is done with shared libraries when using pipeline jobs. – Noam Helmer Aug 20 '21 at 09:54
  • ah now i get it this parameterized triggered job will be generic for all those jobs to update database i will try it and let you know – Youssef Boudaya Aug 20 '21 at 10:15
  • You can add any parameters needed to this job according to your needs, maybe the database table or server and so, some can be with default values. Think of it like a function implemented as a freestyle job. – Noam Helmer Aug 20 '21 at 10:21
  • 1
    i did a generic job (freestyle project) in which i put all my post build actions , it took a bit of time but i was able to create it successfully and now i get duration correctly thanks a lot – Youssef Boudaya Aug 20 '21 at 10:59