如何使用Jenkins管道插件实现构建后阶段?

如何使用Jenkins管道插件实现构建后阶段?,jenkins,jenkins-workflow,jenkins-pipeline,Jenkins,Jenkins Workflow,Jenkins Pipeline,在阅读了Jenkins对插件的解释之后,似乎插件应该能够实现后期构建步骤。然而,文件在具体说明方面相当有限 例如,我想知道如何实施: 仅在生成成功时运行 仅在生成成功或不稳定时运行 不管生成结果如何运行 仅在生成成功时运行 (或将-Dmaven.test.failure.ignore=false添加到MAVEN\u OPTS) 仅在生成成功或不稳定时运行 (或将-Dmaven.test.failure.ignore=true添加到MAVEN\u OPTS) 不管生成结果如何运行—是否可以使

在阅读了Jenkins对插件的解释之后,似乎插件应该能够实现后期构建步骤。然而,文件在具体说明方面相当有限

例如,我想知道如何实施:

  • 仅在生成成功时运行
  • 仅在生成成功或不稳定时运行
  • 不管生成结果如何运行
  • 仅在生成成功时运行

    (或将
    -Dmaven.test.failure.ignore=false添加到
    MAVEN\u OPTS

  • 仅在生成成功或不稳定时运行

    (或将
    -Dmaven.test.failure.ignore=true
    添加到
    MAVEN\u OPTS

  • 不管生成结果如何运行—是否可以使用
    try/catch/finally
    来完成

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

(我注意到最终构建状态设置为SUCCESS,即使某些阶段(即“构建”)已失败,因为它是基于最后一个阶段设置的。这是否意味着最终构建状态需要显式设置,即
currentBuild.result=“不稳定”
?)

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

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

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

最好的方法是在管道脚本中使用生成后操作

处理故障
声明性管道支持健壮失败 默认情况下,通过允许声明 不同“后条件”的数量,例如:始终、不稳定、, 成功、失败和改变。管道语法部分提供了 关于如何使用各种post条件的更多详细信息

Jenkinsfile(声明性管道)

文件如下

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

当我在管道中运行它时,这种可能的重复对我来说不起作用project@Mohamed正如苏布拉特所说,这在jenkins档案之外是行不通的。有没有其他方法可以做到这一点?这可能是由于詹金斯版本或插件版本,但我不确定。另一种方法是将更改放在一个try-catch并最终阻塞中。@MohamedThoufeeque您知道是否可以使posy步骤有条件吗?我只想在某些分支的构建失败时发送电子邮件。如何在post指令中获得失败发生的阶段?这是一个环境变量吗?我只是尝试了一下,发现有些阶段错误(为了测试后期构建步骤而添加的错误)无法检测到。。。currResult==作业明显失败时的成功(Jenkins在控制台中直接写入
Finished:FAILURE
)。在我的最后一块中,currentBuild.result和currentBuild.currentResult都是成功的。知道为什么吗?
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
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 :('
        }
    }
}
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()