Jenkins - при запуске сборки отменить все предыдущие сборки той же ветки - PullRequest
3 голосов
/ 10 июля 2020

Я использую 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 и просто прерву второй запуск, он не остановит все подпроекты.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...