Jenkins - abort running build if new one is started
Solution 1:
With Jenkins script security many of the solutions here become difficult since they are using non-whitelisted methods.
With these milestone steps at the start of the Jenkinsfile, this is working for me:
def buildNumber = env.BUILD_NUMBER as int
if (buildNumber > 1) milestone(buildNumber - 1)
milestone(buildNumber)
The result here would be:
- Build 1 runs and creates milestone 1
- While build 1 is running, build 2 fires. It has milestone 1 and milestone 2. It passes milestone 1, which causes build #1 to abort.
Solution 2:
enable job parallel run for your project with Execute concurrent builds if necessary
use execute system groovy script
as a first build step:
import hudson.model.Result
import jenkins.model.CauseOfInterruption
//iterate through current project runs
build.getProject()._getRuns().iterator().each{ run ->
def exec = run.getExecutor()
//if the run is not a current build and it has executor (running) then stop it
if( run!=build && exec!=null ){
//prepare the cause of interruption
def cause = { "interrupted by build #${build.getId()}" as String } as CauseOfInterruption
exec.interrupt(Result.ABORTED, cause)
}
}
and in the interrupted job(s) there will be a log:
Build was aborted
interrupted by build #12
Finished: ABORTED
Solution 3:
If anybody needs it in Jenkins Pipeline Multibranch, it can be done in Jenkinsfile like this:
def abortPreviousRunningBuilds() {
def hi = Hudson.instance
def pname = env.JOB_NAME.split('/')[0]
hi.getItem(pname).getItem(env.JOB_BASE_NAME).getBuilds().each{ build ->
def exec = build.getExecutor()
if (build.number != currentBuild.number && exec != null) {
exec.interrupt(
Result.ABORTED,
new CauseOfInterruption.UserInterruption(
"Aborted by #${currentBuild.number}"
)
)
println("Aborted previous running build #${build.number}")
} else {
println("Build is not running or is current build, not aborting - #${build.number}")
}
}
}
Solution 4:
Based on the idea by @C4stor I have made this improved version... I find it more readable from @daggett 's version
import hudson.model.Result
import hudson.model.Run
import jenkins.model.CauseOfInterruption.UserInterruption
def abortPreviousBuilds() {
Run previousBuild = currentBuild.rawBuild.getPreviousBuildInProgress()
while (previousBuild != null) {
if (previousBuild.isInProgress()) {
def executor = previousBuild.getExecutor()
if (executor != null) {
echo ">> Aborting older build #${previousBuild.number}"
executor.interrupt(Result.ABORTED, new UserInterruption(
"Aborted by newer build #${currentBuild.number}"
))
}
}
previousBuild = previousBuild.getPreviousBuildInProgress()
}
}