Я использую Jenkins для выполнения тестов всякий раз, когда создается или обновляется PR.
Тесты занимают около 20 минут, и довольно часто PR создается, но через 4-5 минут обновляется другой фиксацией. В этом случае я хочу отменить предыдущий тестовый прогон, поскольку он больше не представляет ценности.
Я попытался реализовать его с помощью groovy скрипта
import hudson.model.Result
import jenkins.model.CauseOfInterruption
import hudson.model.ParametersAction
import hudson.model.Job
import jenkins.model.Jenkins
//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) {
def other_run_params = run.actions.find{ it instanceof ParametersAction }?.parameters
def current_build_params = build.actions.find{ it instanceof ParametersAction }?.parameters
def should_cancel = true
other_run_params.each { other_run_param ->
current_build_params.each { current_build_param ->
if (other_run_param.name == current_build_param.name && other_run_param.dump() != current_build_param.dump()) {
should_cancel = false
}
}
}
// Cancelling all subprojects. If I skip this loop and just cancel 'exec', the subprojects continue to run
if (should_cancel) {
println("Attempting to cancel previous build!")
// prepare the cause of interruption
def cause = { "interrupted by build #${build.getId()}" as String } as CauseOfInterruption
// Cancel all child objects
def buildingJobs = Jenkins.instance.getAllItems(Job.class).findAll { it.isBuilding() }
buildingJobs.each { job ->
allRuns = job._getRuns().iterator().each { child_run ->
upstream = child_run.getCause(hudson.model.Cause.UpstreamCause.class)?.upstreamRun
while (upstream != null) {
if (upstream == run) {
def child_exec = child_run.getExecutor()
if (child_exec != null) {
println("Cancelling child job!")
child_exec.interrupt(Result.ABORTED, cause)
}
}
upstream = upstream.getCause(hudson.model.Cause.UpstreamCause.class)?.upstreamRun
}
}
}
// Cancel the root
exec.interrupt(Result.ABORTED, cause)
}
}
}
Но в настоящее время у меня есть Дженкинс около 30 заданий, каждое с историей около 5 КБ, поэтому выполнение этого задания занимает около 10 минут. Могу ли я сделать это более эффективно?
РЕДАКТИРОВАТЬ: Если я просто пропущу второй l oop и просто прерву второй запуск, он не остановит все подпроекты.