Preventing a scheduled build if a user has manually started the job within 24 hours

100 views
Skip to first unread message

Mark Sinclair

unread,
Jan 6, 2015, 4:38:14 PM1/6/15
to jenkins...@googlegroups.com
All my jobs run on a schedule, typically once per day. 

Sometimes a bug is found and we initiate an immediate build at some point during the day.  I'm interested in cancelling the next timer based build when the user has initiated a build within a certain time period.  This saves some compute resources by avoiding running the job twice in a day.

What is the cleanest way to do this?  Ideally, I want Jenkins to not schedule the next build.  Once the build starts, aborting it based on checking previous build start time does not seem pretty.

Thanks!

Daniel Beck

unread,
Jan 6, 2015, 4:52:19 PM1/6/15
to jenkins...@googlegroups.com
Without relying on plugins, I'd make sure there's a longer quiet period for the job so you can cleanly cancel the build while still in the queue.

Other than that, there's an extension point -- Queue.QueueDecisionHandler -- that plugins can implement to deny queueing of a build. It should be fairly easy to implement a plugin that can optionally prevent build scheduling if a build was started within the last x hours or so. As far as existing plugins, I only know of Skip Next Build Plugin, which is part of the commercial Jenkins Enterprise by Cloudbees.
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/44f05d86-00b2-4ef2-9e46-9bce317c6e81%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Marc MacIntyre

unread,
Jan 6, 2015, 4:55:34 PM1/6/15
to jenkins...@googlegroups.com
Stop using the cron scheduler and use a wrapper job to kick off your builds, and have the wrapper job determine if the job needs to be run or not.  You should be able to just grab the json/python/xml from the lastSuccessfulBuild and do some simple date math - a shell script would suffice.


For more options, visit https://groups.google.com/d/optout.



--
Marc MacIntyre

Daniel Beck

unread,
Jan 6, 2015, 5:10:26 PM1/6/15
to jenkins...@googlegroups.com
Good idea. With the Script Trigger plugin, you don't even need an additional job.

https://wiki.jenkins-ci.org/display/JENKINS/ScriptTrigger+Plugin
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/CA%2BWW-ybq5Ozz95SOma%3DVjkevs3xPjMGu0Mh8R_1CWMEW608MEQ%40mail.gmail.com.

Mark Sinclair

unread,
Jan 6, 2015, 5:32:02 PM1/6/15
to jenkins...@googlegroups.com
Thanks a lot guys. Looks like Script Trigger is just what I need.

How do I get the time of last build? Is there a fancy way or should I use curl with $JOB_URL/api/xml?depth=1 to dig that up?

Thanks
You received this message because you are subscribed to a topic in the Google Groups "Jenkins Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-users/qHHD0krSuUA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/8571E269-4229-4FF4-9657-C761D2CBB1FB%40beckweb.net.

Marc MacIntyre

unread,
Jan 6, 2015, 5:34:13 PM1/6/15
to jenkins...@googlegroups.com
.../lastSuccessfulBuild/api/json?tree=timestamp would do it, but catch the 404 if there are no successful builds found.


For more options, visit https://groups.google.com/d/optout.



--
Marc MacIntyre

Mark Sinclair

unread,
Jan 6, 2015, 5:35:44 PM1/6/15
to jenkins...@googlegroups.com

Marc MacIntyre

unread,
Jan 6, 2015, 5:39:43 PM1/6/15
to jenkins...@googlegroups.com
I should have looked more closely at the trigger plugin; if you are using a groovy script, you can probably just look for the builds using hudson.model.Jenkins - it's probably cleaner than the network call, but I don't have code for that handy.


For more options, visit https://groups.google.com/d/optout.



--
Marc MacIntyre

Mark Sinclair

unread,
Jan 6, 2015, 5:42:18 PM1/6/15
to jenkins...@googlegroups.com

Was going to use a shell script, but maybe it’s a good time to learn some Groovy.

Mark Sinclair

unread,
Jan 7, 2015, 4:38:08 PM1/7/15
to jenkins...@googlegroups.com

Here’s my groovy script to run with script trigger.  Looks like everything works, except I assumed the return value of 0 would schedule a build (this seems to be the way it works when a shell script is used).  I’m guessing that when groovy is used with script trigger, I need to call the build command from within the groovy script?

 

println("Checking time of last successful run to determine if regression is needed")

def item = hudson.model.Hudson.instance.getItem("$JOB_NAME")

def build = item.getLastSuccessfulBuild()

def last_success_time = build.getTime()

println(last_success_time.time)

def today = new Date()

 

def hours_since_run = (today.time - last_success_time.time) / (60 * 60 * 1000)

println hours_since_run

 

if (hours_since_run < 20)

{

println("Ran successfully $hours_since_run ago, skipping automatic regression")

return 1

}

else

{

println("Running regression")

return 0

Mark Sinclair

unread,
Jan 7, 2015, 5:36:14 PM1/7/15
to Mark Sinclair, jenkins...@googlegroups.com

I didn’t notice that the return value should be ‘true’ for groovy scripts.  This script works great.  The only drawback I’ve seen of using script trigger vs the built in scheduling is script trigger is not compatible with next executions, you will not see the next time the script will be evaluated.

 

Thanks again for the help!

 

println("Checking time of last successful run to determine if regression is needed")

def item = hudson.model.Hudson.instance.getItem("$JOB_NAME")

def build = item.getLastSuccessfulBuild()

def last_success_time = build.getTime()

println(last_success_time.time)

def today = new Date()

 

def hours_since_run = (today.time - last_success_time.time) / (60 * 60 * 1000)

println hours_since_run

 

if (hours_since_run < 20)

{

println("Ran successfully $hours_since_run ago, skipping automatic regression")

return false

}

else

{

println("Running regression")

return true

}

 

Reply all
Reply to author
Forward
0 new messages