我想在一个阶段中执行一系列步骤,即使第一个步骤失败。我希望阶段结果失败并且构建被中止,但只有 所有步骤都运行后。例如,
pipeline {
agent any
stages {
stage('Run Test') {
steps {
sh "echo running unit-tests"
sh "echo running linting && false" // failure
sh "echo generating report" // This should still run (It currently doesn't)
publishCoverage adapters: [coberturaAdapter("coverage.xml")] // This should still run (It currently doesn't)
junit 'unit-test.xml' // This should still run (It currently doesn't)
}
}
stage('Deploy') {
steps {
echo "deploying" // This should NOT run
}
}
}
}
结果应该是构建失败,其中“运行测试”阶段失败而“部署”阶段未运行。这可能吗?
附言
我不要求与Continue Jenkins pipeline past failed stage中的行为相同。我想运行失败后的步骤,而不是之后的任何阶段。我尝试用 catchError (buildResult: 'FAILURE', stageResult: 'FAILURE')
将每个测试步骤括起来,但“部署”阶段仍在运行。
编辑:
我无法将所有步骤合并为一个大 sh
步骤并捕获其返回码,因为有些步骤不是 shell 命令,而是像 junit
和 publishCoverage
这样的 jenkins 步骤。
答案 0 :(得分:0)
理论上你应该能够使用 sh "<command>||true"
它会忽略命令上的错误并继续。但是,Jenkins 不会失败,因为它会忽略错误。
如果您不希望 Jenkins 忽略错误并希望它在阶段结束时停止,您可以执行以下操作:sh "<command>||$error=true"
然后根据 $error
变量使构建失败. (sh "$error"
可能就足够了,但我不确定,最后可能需要一个 if 语句。)它只会设置为 true
如果 command
失败。
答案 1 :(得分:0)
具有非零退出代码的脚本将始终导致 jenkins 步骤失败。您可以将 returnStatus
用作 true
,以便 jenkins 不会失败该步骤。
此外,考虑到您的用例,您可以使用 post always
执行,以便始终执行这些步骤。
请参阅以下参考示例:
stage('Run Test') {
steps {
def unit_test_result= sh returnStatus: true, script: 'echo "running unit-tests"'
def lint_result= sh returnStatus: true, script: 'echo "running linting"'
if (unit_test_result!=0 || lint_result!=0 ) {
// If the unit_test_result or lint_result status is not 0 then mark this stage as unstable to continue ahead
// and all later stages will be executed
unstable ('Testing failed')
// You can also mark as failed as below and it will not conintue other stages:
// error ('Testing failed')
}
}
post {
always {
// This block would always be executed inspite of failure
sh "echo generating report"
publishCoverage adapters: [coberturaAdapter("coverage.xml")]
junit 'unit-test.xml'
}
}
}
答案 2 :(得分:0)
另一种选择是将构建步骤包装在 try-catch 块中!如果出现异常,即构建的返回代码不是 0,您可以捕获它,将构建标记为不稳定,然后管道的其余部分继续。
这是一个例子` 管道{
agent {
node {
label 'linux'
}
}
options {
timestamps()
disableConcurrentBuilds()
buildDiscarder(logRotator(numToKeepStr: '3'))
}
tools {
maven 'Maven 3.6.3'
jdk 'jdk11'
}
stages {
stage('CleanWS') {
steps {
cleanWs()
}
}
stage('Build') {
steps {
withMaven(options: [artifactsPublisher(disabled: true)]) {
sh "export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn -f pom.xml clean install -DskipTests -Pregression-test -Dmaven.javadoc.skip=true"
}
}
}
stage('Test') {
steps {
script {
try {
withMaven(options: [artifactsPublisher(disabled: true)]) {
sh "export MAVEN_OPTS=\"-Xmx2048m\" && export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn -B verify -Dmaven.source.skip=true -Dmaven.javadoc.skip=true"
}
} catch (exc) {
currentBuild.result = 'UNSTABLE'
}
}
}
post {
always {
script {
junit "**/surefire-reports/*.xml"
}
}
}
}
stage('Sonar Analyse') {
steps {
script {
withMaven(options: [artifactsPublisher(disabled: true)]) {
withSonarQubeEnv("SonarQube") {
sh "export MAVEN_OPTS=\"-Xmx2048m\" && export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn sonar:sonar"
}
}
}
}
}
stage('Deploy to Nexus') {
steps {
sh "export NLS_LANG=GERMAN_GERMANY.WE8ISO8859P1 && mvn -f pom.xml -B clean deploy -DdeployAtEnd=true -DskipTests"
}
}
}
post {
failure {
script {
emailext(
body: "Please go to ${env.BUILD_URL}/console for more details.",
to: emailextrecipients([developers(), requestor()]),
subject: "Nightly-Build-Pipeline Status is ${currentBuild.result}. ${env.BUILD_URL}"
)
}
}
unstable {
script {
emailext(
body: "Please go to ${env.BUILD_URL}/console for more details.",
to: emailextrecipients([developers(), requestor()]),
subject: "Nightly-Build-Pipeline Build Status is ${currentBuild.result}. ${env.BUILD_URL}"
)
}
}
}
}`
答案 3 :(得分:0)
我找到了一种获得我想要的行为的有点笨拙的方法。其他答案对我不起作用,要么是因为它们需要所有步骤都是 Generics
步骤,要么它们不会阻止 sh
阶段运行。我使用 deploy
来设置构建和暂存结果。但是为了防止下一个阶段运行,如果阶段失败,我需要显式调用 catchError
。
error