¿La forma más limpia de salir prematuramente de un trabajo de Jenkins Pipeline como un éxito?

56

Tengo un trabajo que creará archivos, a menos que uno de los valores que se le proporcione coincida con un valor anterior. ¿Cuál es la forma más limpia en Jenkins de abortar o salir del trabajo, sin que sea así FAILED? Salir es el comportamiento correcto, así que quiero marcar la compilación SUCCESS.

Terminará en una declaración if así;

stage ('Check value') {

     if( $VALUE1 == $VALUE2 ) {
       //if they do match exit as a success, else continue with the rest of the job 
    }

}

No quiero lanzar un código de error a menos que eso de alguna manera pueda traducirse en que se marque como una compilación exitosa.

Alex
fuente
1
Solo exit 0...
Tensibai
¿Pensé que eso marcó el trabajo como un fracaso? Si me equivoco y puede mostrar documentación, me complacería aceptar eso como respuesta
Alex
Bueno, solo bash scripts, la salida 0 significa éxito, la salida no cero significa falla ...
Tensibai
Esto no está dentro de un script bash, este es el trabajo de canalización en sí mismo, así que Groovy. ¿Eso cambia las cosas?
Alex
En groovy, solo probaría un return 0, en general, cualquier extremo del código groovy que no arroje una excepción debería hacerlo, creo.
Dejaré

Respuestas:

47

Lo averigué. Fuera de cualquier etapa (de lo contrario, esto solo terminará la etapa particular como un éxito) haga lo siguiente;

if( $VALUE1 == $VALUE2 ) {
   currentBuild.result = 'SUCCESS'
   return
}

return detendrá la etapa o el nodo en el que se está ejecutando, por lo que es importante ejecutarlo fuera de una etapa, mientras que la configuración currentBuild.resultevita que falle.

Alex
fuente
solo regresar debería dejar la compilación con un estado atenuado y sin resultado ... así que no es lo mismo que una compilación fallida.
2017
1
¿Cómo regresas y te saltas todas las etapas restantes?
Jess Bowers
1
@JessBowers se trata de dónde pones el fragmento. Si lo hace a nivel de nodo en lugar de a nivel de etapa, finalizará todo el trabajo.
Alex
44
Tenga en cuenta que solo funciona para la tubería programada, no para declarativa
kagarlickij
@kagarlickij - ¡No existían tuberías declarativas correctas cuando se escribió esta respuesta!
Alex
11

También puede usar el error para salir de la etapa actual, luego no tiene que considerar la jerarquía de la etapa actual y cosas similares:

def autoCancelled = false

try {
  stage('checkout') {
    ...
    if (your condition) {
      autoCancelled = true
      error('Aborting the build.')
    }
  }
} catch (e) {
  if (autoCancelled) {
    currentBuild.result = 'SUCCESS'
    // return here instead of throwing error to keep the build "green"
    return
  }
  // normal error handling
  throw e
}

Pero esto llevaría a una etapa roja, si el error ocurre dentro de una etapa.

ingrese la descripción de la imagen aquí

Depende de sus requisitos, de qué manera desea usar.

CSchulz
fuente
Si vas a hacerlo de esta manera, crea una nueva subclase de RuntimeExceptionlanzar en lugar de tener que atrapar todas las excepciones y marcar una bandera
Michael Mrozek
1

Honestamente, no debería necesitar usar el comando de salida específicamente, pero hay un complemento condicional de BuildStep que puede lograr el mismo resultado final (código que no se ejecuta).

Todavía no me he encontrado con esto, así que no he usado el complemento.

También hay condicionales como se encuentran en esta publicación anterior de desbordamiento de pila en Jenkins: Jenkins Pipeline Conditional Step / Stage

MrMesees
fuente
1
Si bien su respuesta parece ser válida (no la he revisado en vivo desde que encontré otra solución), no creo que "Sinceramente no deba salir" sea una buena forma de comenzarla; claramente la existencia de estos métodos significa que a veces es necesario salir.
Alex
¿Qué sugieres? ¿Pasar a una declaración final? Agregar el calificador "en general"? Usted ha proporcionado "comentarios", pero no es fácil para mí decir la intención o la acción, por favor sea menos conciso.
MrMesees
Espera un poco. ¿Es tu pregunta? Si es así, TBH no querrá escuchar que no debe salir, pero ninguno de los métodos que he sugerido proporciona salidas, eluden el código en ejecución ... Directamente apoyando mi posición.
MrMesees
1
Ahh, ya veo, creo que malinterpreté tu afirmación como "hacer algo para terminar el trabajo es malo" en lugar de "no deberías usar el exitcomando literal ". Si es así, me disculpo, ese es mi malentendido.
Alex
3
He tratado de aclararlo, no hay necesidad de disculparse, el idioma es una bestia voluble, especialmente en Internet :)
MrMesees
0

El Executor.interrupt(Result)método es la forma más limpia y directa que pude encontrar para detener una compilación prematuramente y marcarla como un éxito.

script {
    currentBuild.getRawBuild().getExecutor().interrupt(Result.SUCCESS)
}

Pros :

  • Funciona en una tubería declarativa tan bien como una secuencia de comandos.
  • Sin intento / captura o excepciones para manejar.
  • Marca la etapa de llamada y cualquier etapa sucesiva como verde / pasando en la interfaz de usuario.

Contras :

  • Requiere varias aprobaciones de script en proceso, incluida una que se considera insegura . Aprobar y usar con precaución.
Ben Amos
fuente
Para mí no funciona, se están ejecutando etapas consecutivas.
Łukasz K