153

作为构建过程的一部分,我将 git commit 作为执行 shell 步骤运行。但是,如果工作区中没有任何更改,则 Jenkins 会导致构建失败。这是因为 git 在没有要提交的更改时返回错误代码。如果是这种情况,我想中止构建,或者将其标记为不稳定。有任何想法吗?

4

14 回答 14

254

命令失败时停止进一步执行:

command || exit 0

命令失败时继续执行:

command || true

于 2014-09-09T13:13:11.170 回答
97

/bin/sh -xeJenkins默认使用执行 shell 构建步骤。-x表示打印执行的每个命令。-e表示如果脚本中的任何命令失败,则退出失败。

因此,我认为在您的情况下发生的情况是您的 git 命令以 1 退出,并且由于默认-e参数,shell 会选择非 0 退出代码,忽略脚本的其余部分并将该步骤标记为失败。如果您可以在此处发布构建步骤脚本,我们可以确认这一点。

如果是这种情况,您可以尝试 put#!/bin/sh以便在没有选项的情况下执行脚本;或set +e在构建步骤之上执行或执行任何类似操作来覆盖此行为。


编辑:要注意的另一件事是,如果您的 shell 脚本中的最后一个命令返回非 0 代码,即使使用此设置,整个构建步骤仍将被标记为失败。在这种情况下,您可以简单地true在末尾添加一个命令来避免这种情况。

另一个相关问题

于 2015-02-11T07:00:50.553 回答
44

如果没有推送 git 返回退出状态 1. Execute shell build step 分别标记为失败。您可以使用 OR 语句 || (双管)。

git commit -m 'some messasge' || echo 'Commit failed. There is probably nothing to commit.'

这意味着,如果第一次失败(返回退出状态> 0),则执行第二个参数。第二个命令总是返回 0。当没有任何东西可以推送时(退出状态 1 -> 执行第二个命令),echo 将返回 0 并继续构建步骤。

要将构建标记为不稳定,您可以使用构建后步骤 Jenkins 文本查找器。它可以通过控制台输出,匹配模式(你的回声)并将构建标记为不稳定。

于 2013-10-17T10:37:11.567 回答
29

还有另一种告诉詹金斯不要失败的顺利方法。您可以在构建步骤中隔离您的提交并将外壳设置为不失败:

set +e
git commit -m "Bla."
set -e
于 2014-06-04T08:58:09.410 回答
15

这个答案是正确的,但它没有指定|| exit 0or|| true进入shell command。这是一个更完整的示例:

sh "adb uninstall com.example.app || true"

以上将起作用,但以下将失败:

sh "adb uninstall com.example.app" || true

也许这对其他人来说是显而易见的,但在我意识到这一点之前,我浪费了很多时间。

于 2020-06-29T21:11:29.053 回答
10

我能够使用此处找到的答案来完成这项工作:

如何在没有错误的情况下不提交任何内容?

git diff --quiet --exit-code --cached || git commit -m 'bla'
于 2013-01-18T18:06:19.327 回答
8

Jenkins 通过步骤的返回值来确定步骤的成功/失败。对于 shell 的情况,它应该是最后一个值的返回。对于 Windows CMD 和 (POSIX) Bash shell,您应该能够使用exit 0最后一个命令手动设置返回值。

于 2013-01-18T14:55:13.840 回答
8

在标题中的(更一般的)问题上 - 为了防止 Jenkins 失败,您可以阻止它看到退出代码 1。 ping 示例:

bash -c "ping 1.2.3.9999 -c 1; exit 0"

现在您可以获取 ping 的输出:

output=`bash -c "ping 1.2.3.9999 -c 1; exit 0"`

当然,ping ...您可以使用任何命令(包括git commit.

于 2013-11-20T11:05:03.727 回答
7

https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script

如果包含 returnStatus: true 属性,则忽略 shell 返回。

于 2018-07-04T16:17:12.677 回答
6

您可以使用Text-finder Plugin。它将允许您检查输出控制台以获取您选择的表达式,然后将构建标记为Unstable.

于 2013-01-18T09:11:20.327 回答
5

对于多个 shell 命令,我通过添加以下内容来忽略失败:

set +e commands true

在此处输入图像描述

于 2019-03-11T10:31:54.443 回答
3

如果将此命令放入 shell 块中:

false
true

您的构建将被标记为失败(至少 1 个非零退出代码),因此您可以添加 (set +e) 以忽略它:

set +e
false
true

不会失败。但是,即使 (set +e) 就位,这也会失败:

set +e
false

因为最后一个 shell 命令必须以 0 退出。

于 2016-11-30T19:35:52.083 回答
2

以下内容仅适用于mercurial,仅在有更改时才提交。因此,只有在提交失败时构建才会失败。

hg id | grep "+" || exit 0
hg commit -m "scheduled commit"
于 2013-02-05T18:18:46.690 回答
0

另一个带有一些提示的答案可能对某人有所帮助:

请记住使用以下规则分隔您的命令:

command1 && command2 - 表示只有在 command1 成功时才会执行 command2

命令1 command2 - 意味着,尽管 command1 的结果,命令 2 仍将被执行

例如:

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test ;set -e;echo 0 ", returnStdout: true).trim()
println run_tests 

如果失败(您的测试失败),将使用set -e和命令成功执行,而以下代码被剪断:echo 0gmake test

String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test && set -e && echo 0 ", returnStdout: true).trim()
println run_tests 

有点错误,命令set -eecho 0in&& gmake test && set -e && echo 0将被跳过,println run_tests因为 failedgmake test将中止 jenkins 构建。作为解决方法,您可以切换到returnStatus:true,但是您将错过命令的输出。

于 2019-03-11T12:24:43.700 回答