如何使用Jenkins Pipeline插件实现Post-Build阶段?

时间:2016-04-15 15:39:38

标签: jenkins jenkins-workflow jenkins-pipeline

在阅读Jenkins tutorial解释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'
        ...
    }
    

(我注意到最终的构建状态设置为 SUCCESS ,即使某些阶段,即“' build'”因基于最后阶段设置而失败这是否意味着最终构建状态需要明确设置,即currentBuild.result = 'UNSTABLE'?)

4 个答案:

答案 0 :(得分:35)

最好的方法是在管道脚本中使用post build action。

  

处理故障
  声明性管道支持强大的故障   默认情况下通过其帖子部分处理,允许声明a   不同“后置条件”的数量,例如:总是,不稳定,   成功,失败和改变。 “管道语法”部分提供   关于如何使用各种后置条件的更多细节。

Jenkinsfile(声明性管道)

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

文档如下 https://jenkins.io/doc/book/pipeline/syntax/#post

答案 1 :(得分:4)

如果您正在使用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'
...

答案 2 :(得分:1)

可以设置

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

当然,这适用于执行期间发生的任何异常。

答案 3 :(得分:1)

FWIW,如果您使用脚本化管道而不是声明性管道,则应使用其他答案中建议的try/catch/finally块。在finally块中,如果要模仿声明性管道的功能,则可以将以下内容直接放在该块中,或者使其成为函数并从finally块中调用该函数:< / p>

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块的更好语法。