我有一个Jenkinsfile
,它有两个不同的阶段:Pre-Build
和Build
。 Pre-Build
正在执行pylint
,并使用warnings-ng
插件将其报告给Jenkins。
类似的东西:
stages {
stage('Pre-build') {
steps {
script {
sh """#!/usr/bin/env bash
pip install .
pylint --exit-zero --output-format=parseable --reports=n myProject > reports/pylint.log
"""
}
}
post {
always {
recordIssues(
enabledForFailure: true,
tool: pyLint(pattern: '**/pylint.log'),
unstableTotalAll: 20,
failedTotalAll: 30,
)
}
failure {
cleanWs()
}
}
}
stage('Build') {
steps {
script {
sh """#!/usr/bin/env bash
set -e
echo 'I AM STAGE TWO AND I SHOULD NOT BE EXECUTED'
"""
}
}
post {
always {
cleanWs()
}
}
}
}
我在这里遇到了两个问题。目前,我正在将pylint
设置为--exit-zero
,因为我想根据报告将warnings-ng
插件确定是否可行。
目前,这总共失败了30次。现在,myProject
有45个问题,我想防止进入下一阶段,Build
。但是目前我似乎无法阻止这种行为,因为它一直持续到Build
阶段。
由于recordIssues
中确定的结果,该构建被标记为失败,但它不会中止该作业。
我在https://issues.jenkins-ci.org(Ticket)上找到了一张票,但是我似乎无法理解所有这些。
答案 0 :(得分:1)
我找到了解决您问题的方法,我认为这是管道工作流程中的错误。 warnings-ng
正确地将构建状态设置为失败,但是尽管${currentBuild.currentResult}
变量中的状态仍然可以开始下一阶段。
您可以使用when { expression { return currentBuild.currentResult == "SUCCESS" } }
跳过后面的阶段,或者抛出错误。但是我认为这应该是默认行为。然后,您的文件应为:
stages {
stage('Pre-build') {
steps {
script {
sh """#!/usr/bin/env bash
pip install .
pylint --exit-zero --output-format=parseable --reports=n myProject > reports/pylint.log
"""
}
}
post {
always {
recordIssues(
enabledForFailure: true,
tool: pyLint(pattern: '**/pylint.log'),
unstableTotalAll: 20,
failedTotalAll: 30,
)
}
}
}
stage('Build') {
when { expression { return currentBuild.currentResult == "SUCCESS" } }
steps {
script {
echo "currentResult: ${currentBuild.currentResult}"
sh """#!/usr/bin/env bash
set -e
echo 'I AM STAGE TWO AND I SHOULD NOT BE EXECUTED'
"""
}
}
}
post {
always {
cleanWs()
}
}
}
我在他们的吉拉(Jira)中创建了一个issue。
我的环境:
Jenkins版本:2.222.1
warnings-ng
版本:8.1
worfklow-api
版本:2.40
答案 1 :(得分:0)
post
2次,这是错误的实现,因为post设计为在所有阶段完成后仅执行一次。它应该在流水线结束之前的所有阶段之后编写。 Build stage
的执行,您可以在顶部创建全局变量,捕获pylint的输出,并在阶段开始时使用if或when条件。类似于-pipeline {
def result
stages {
stage('Pre-build') {
steps {
script {
sh """#!/usr/bin/env bash
pip install .
pylint --exit-zero --output-format=parseable --reports=n myProject > reports/pylint.log
"""
}
}
}
}
stage('Pylint result') { // Not sure how recordIssue works. This just an example.
result = recordIssues(
enabledForFailure: true,
tool: pyLint(pattern: '**/pylint.log'),
unstableTotalAll: 20,
failedTotalAll: 30,
)
}
stage('Build') {
if ( result == "pass") {
steps {
script {
sh """#!/usr/bin/env bash
set -e
echo 'I AM STAGE TWO AND I SHOULD NOT BE EXECUTED'
"""
}
}
}
}
}
post { // this should be used after stages
always {
cleanWs()
}
failure {
cleanWs()
}
}
此外,阶段的设计方式是,如果它们失败,则将不执行下一个阶段,因此,最好在阶段内而不是在后置条件下执行pylint。
注意:上面的代码仅是示例。请根据需要进行修改。
答案 2 :(得分:0)
您可能会考虑的一种选择是使用以下代码明确使构建失败:
post {
always {
recordIssues(
enabledForFailure: true,
tool: pyLint(pattern: '**/pylint.log'),
unstableTotalAll: 20,
failedTotalAll: 30
)
script {
if (currentBuild.currentResult == 'FAILURE') {
error('Ensure that the build fails if the quality gates fail')
}
}
}
}
在这里,在记录问题之后,还要检查currentBuild.currentResult
的值是否为FAILURE
,在这种情况下,您将显式调用error()
函数,该函数会导致构建失败。 / p>