steps scm plugin from example create git jenkins groovy multibranch-pipeline

git - scm - jenkins pipeline stage steps



Jenkins-cancela la ejecuciĆ³n en ejecuciĆ³n si se inicia una nueva (6)

Yo uso Jenkins y Multibranch Pipeline. Tengo un trabajo para cada rama git activa. Nueva construcción es activada por push en el repositorio git. Lo que quiero es abortar las compilaciones en ejecución en la rama actual si aparece una nueva en la misma rama.

Por ejemplo: me comprometo y presiono para ramificar feature1 . Entonces BUILD_1 comenzó en Jenkins. Hago otra confirmación y BUILD_1 feature1 BUILD_1 mientras BUILD_1 aún se está ejecutando. Quiero que se BUILD_1 y que se inicie BUILD_2 .

Intenté usar la opción de stage concurrency=x , y la función stage-lock-milestone , pero no pude resolver mi problema.

También he leído este hilo Deteniendo el trabajo de Jenkins en caso de que se inicie uno más nuevo , pero no hay solución para mi problema.

¿Conoces alguna solución a esto?


Basado en la idea de @ C4stor, he hecho esta versión mejorada ... Me parece más legible desde la versión de @daggett

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() } }


Con la seguridad del script de Jenkins, muchas de las soluciones aquí se vuelven difíciles ya que utilizan métodos no incluidos en la lista blanca.

Con estos pasos importantes al inicio del archivo Jenkins, esto está funcionando para mí:

def buildNumber = env.BUILD_NUMBER as int if (buildNumber > 1) milestone(buildNumber - 1) milestone(buildNumber)

El resultado aquí sería:

  • La compilación 1 se ejecuta y crea el hito 1
  • Mientras se ejecuta la compilación 1, compila 2 disparos. Tiene el hito 1 y el hito 2. Pasa el hito 1, lo que hace que la compilación # 1 se cancele.

Se puso a trabajar con la siguiente secuencia de comandos en la Biblioteca compartida global:

import hudson.model.Result import jenkins.model.CauseOfInterruption.UserInterruption def killOldBuilds() { while(currentBuild.rawBuild.getPreviousBuildInProgress() != null) { currentBuild.rawBuild.getPreviousBuildInProgress().doKill() } }

Y llamándolo en mi pipeline:

@Library(''librayName'') def pipeline = new killOldBuilds() [...] stage ''purge'' pipeline.killOldBuilds()

Edición: ¡Dependiendo de la fuerza con la que quiera matar al oldBuild, puede usar doStop (), doTerm () o doKill ()!


Si alguien lo necesita en Jenkins Pipeline Multibranch, puede hacerlo en Jenkinsfile así:

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}") } } }


También compilé una versión de las que se dieron anteriormente con algunos ajustes menores:

  • El bucle while() generó múltiples salidas para cada compilación
  • UserInterruption actualmente espera un ID de usuario en lugar de una cadena de razonamiento, y no mostrará una cadena de razonamiento en ningún lugar. Por lo tanto, esto solo proporciona el ID de usuario

def killOldBuilds(userAborting) { def killedBuilds = [] while(currentBuild.rawBuild.getPreviousBuildInProgress() != null) { def build = currentBuild.rawBuild.getPreviousBuildInProgress() def exec = build.getExecutor() if (build.number != currentBuild.number && exec != null && !killedBuilds.contains(build.number)) { exec.interrupt( Result.ABORTED, // The line below actually requires a userId, and doesn''t output this text anywhere new CauseOfInterruption.UserInterruption( "${userAborting}" ) ) println("Aborted previous running build #${build.number}") killedBuilds.add(build.number) } } }


habilite la ejecución paralela del trabajo para su proyecto con Execute concurrent builds if necessary

Utilice el execute system groovy script como primer paso de compilación:

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) } }

y en el (los) trabajo (s) interrumpido (s) habrá un registro:

Build was aborted interrupted by build #12 Finished: ABORTED