Как реализовать этап Post-Build с помощью плагина Jenkins Pipeline?

После прочтения учебника Дженкинса с объяснением Pipeline, кажется, что плагин должен позволять выполнять шаги после сборки. Однако документация довольно ограничена в отношении конкретных инструкций.

Например, мне интересно, как реализовать:

  • Запускать, только если сборка прошла успешно
  • Запускать, только если сборка прошла успешно или нестабильна
  • Запускать независимо от результата сборки
  • Запускать, только если сборка прошла успешно

    stage 'build'
    ... build
    ... tests
    stage 'post-build'
    ...
    

    (Или добавьте -Dmaven.test.failure.ignore=false к MAVEN_OPTS)

  • Запускать, только если сборка выполнена успешно или нестабильна

    stage 'build'
    ... build
    try {
        ... tests
    } catch {
        ...
    }
    stage 'post-build'
    ...
    

    (Или добавьте -Dmaven.test.failure.ignore=true к MAVEN_OPTS)

  • Запускать независимо от результата сборки - можно ли это сделать с помощью try / catch / finally?

    try {
        stage 'build'
        ...
    } catch {
        ...
    } finally {
        stage 'post-build'
        ...
    }
    

(Я заметил, что статус окончательной сборки установлен как УСПЕШНО, хотя некоторые этапы, например, «сборка», завершились неудачно, как это было установлено на последнем этапе. Означает ли это, что статус окончательной сборки должен быть явно установить, т.е.currentBuild.result = 'UNSTABLE'?)


person luka5z    schedule 15.04.2016    source источник


Ответы (4)


Лучше всего использовать действие после сборки в скрипте конвейера.

Обработка сбоев
Декларативный конвейер поддерживает надежную обработку сбоев по умолчанию через свой раздел сообщений, который позволяет объявлять ряд различных «условий публикации», таких как: всегда, нестабильно, успешно, сбой и изменено. В разделе «Синтаксис конвейера» содержится более подробная информация о том, как использовать различные условия публикации.

Jenkinsfile (декларативный конвейер)

pipeline {
    agent any
    stages {
        stage('Test') {
            steps {
                sh 'make check'
            }
        }
    }
    post {
        always {
            junit '**/target/*.xml'
        }
        failure {
            mail to: [email protected], subject: 'The Pipeline failed :('
        }
    }
}

Документация находится ниже https://jenkins.io/doc/book/pipeline/syntax/#post

person Mohamed Thoufeeque    schedule 22.03.2017
comment
это не работает для меня, когда я запускаю его в проекте конвейера - person Subrat Sahoo; 12.06.2017
comment
@Mohamed, как сказал Субрат, это не работает вне файла jenkins. Есть другой способ сделать это? - person Jason; 18.07.2017
comment
Это могло быть связано с версией jenkins или версией плагина, но я не уверен. Другой способ сделать это - поместить изменения в блокировку try и finally. - person Mohamed Thoufeeque; 19.07.2017
comment
@MohamedThoufeeque, знаете ли вы, можете ли вы сделать шаги posy условными? Я хотел бы отправлять электронное письмо только в случае сбоя сборки для определенных веток. - person thecoshman; 14.11.2017
comment
как добраться до стадии, на которой произошел сбой в директиве post? это переменная среды? - person red888; 18.01.2018
comment
это работает идеально для меня, мы также можем использовать success в посте. - person valdeci; 25.01.2019
comment
Действия POST выполняются на основе currentBuild.result. Есть ли способ выполнить эти действия с публикацией на основе currentState.result ?? - person Frank Escobar; 21.02.2020

Если вы используете try / catch и хотите, чтобы сборка была помечена как нестабильная или неудачная, вы должны использовать currentBuild.result = 'UNSTABLE' и т. Д. Я считаю, что некоторые плагины, такие как плагин JUnit Report, установят это для вас, если обнаружит, что не удалось результаты тестов в junit. Но в большинстве случаев вам придется настраивать его самостоятельно, если вы обнаруживаете ошибки.

Второй вариант, если вы не хотите продолжать, - это повторно выбросить ошибку.

stage 'build'
... build
try {
    ... tests
} catch(err) {
    //do something then re-throw error if needed.
    throw(err)
}
stage 'post-build'
...
person DanielD    schedule 21.06.2016

FWIW, если вы используете скриптовые конвейеры, а не декларативно, вы должны использовать блок try/catch/finally, как предлагается в других ответах. В блоке finally, если вы хотите имитировать то, что делает декларативный конвейер, вы можете либо поместить следующее непосредственно в блок, либо сделать его функцией и вызвать эту функцию из вашего блока finally:

def currResult = currentBuild.result ?: 'SUCCESS'
def prevResult = currentBuild.previousBuild?.result ?: 'NOT_BUILT'

// Identify current result
boolean isAborted = (currResult == 'ABORTED')
boolean isFailure = (currResult == 'FAILURE')
boolean isSuccess = (currResult == 'SUCCESS')
boolean isUnstable = (currResult == 'UNSTABLE')

boolean isChanged = (currResult != prevResult)
boolean isFixed = isChanged && isSuccess && (prevResult != 'ABORTED') && (prevResult != 'NOT_BUILT')
boolean isRegression = isChanged && currentBuild.resultIsWorseOrEqualTo(prevResult)

onAlways()
if (isChanged) {
    onChanged()
    if (isFixed) {
        onFixed()
    } else if (isRegression) {
        onRegression()
    }
}
if (isSuccess) {
    onSuccess()
} else {
    if (isAborted) {
        onAborted()
    }
    onUnsuccessful()
    if (isFailure) {
        onFailure()
    }
    if (isUnstable) {
        onUnstable()
    }
}
onCleanup()

Различные вызовы onXYZ() - это функции, которые вы должны определить для обработки этого конкретного условия вместо использования более удобного синтаксиса декларативных блоков post.

person Will    schedule 17.01.2019
comment
Я просто попробовал это и обнаружил случаи, когда некоторые ошибки этапа (ошибка, добавленная специально для проверки этапа пост-сборки) не могут быть обнаружены ... currResult == УСПЕХ, когда задание явно не выполняется (Дженкинс буквально пишет в консоли Finished: FAILURE) . в моем блоке finally как currentBuild.result, так и currentBuild.currentResult - УСПЕХ. Есть идеи, почему? - person MoOx; 08.04.2020

try-catch блоки могут быть настроены для обработки ошибок, как в реальном коде приложения.

Например:

try {
    node {
        sh 'sleep 20' // <<- can abort here
    }
} catch (Exception e) {
    println 'catch'
} finally {
    println 'finally'
}

node {
    println 'second'
}

try {
    node {
        sh 'sleep 20' // <<- can abort here again
    }
} catch (Exception e) {
    println 'catch'
} finally {
    println 'finally'
}

А вот пример вывода с двумя прерываниями.

Started by user me
Replayed #3
[Pipeline] node
Running on my-node in /var/lib/jenkins-slave/workspace/my-job
[Pipeline] {
[Pipeline] sh
[my-job] Running shell script
+ sleep 20

Aborted by me

Sending interrupt signal to process

/var/lib/jenkins-slave/workspace/my-job@tmp/durable-9e1a15e6/script.sh: line 2: 10411 Terminated              sleep 20
[Pipeline] }
[Pipeline] // node
[Pipeline] echo
catch
[Pipeline] echo
finally
[Pipeline] node
Running on my-node in /var/lib/jenkins-slave/workspace/my-job
[Pipeline] {
[Pipeline] echo
second
[Pipeline] }
[Pipeline] // node
[Pipeline] node
Running on my-node in /var/lib/jenkins-slave/workspace/my-job
[Pipeline] {
[Pipeline] sh
[my-job] Running shell script
+ sleep 20

Aborted by me

Sending interrupt signal to process
/var/lib/jenkins-slave/workspace/my-job@tmp/durable-d711100c/script.sh: line 2: 10416 Terminated              sleep 20
[Pipeline] }
[Pipeline] // node
[Pipeline] echo
catch
[Pipeline] echo
finally
[Pipeline] End of Pipeline
Finished: ABORTED

Конечно, это работает для любых исключений, происходящих во время выполнения.

person allprog    schedule 07.11.2016