作为构建过程的一部分,我将 git commit 作为执行 shell 步骤运行。但是,如果工作区中没有任何更改,则 Jenkins 会导致构建失败。这是因为 git 在没有要提交的更改时返回错误代码。如果是这种情况,我想中止构建,或者将其标记为不稳定。有任何想法吗?
在命令失败时停止进一步执行:
command || exit 0
命令失败时继续执行:
command || true
默认情况下,Jenkins 使用 /bin/sh -xe
执行 shell 构建步骤。 -x
表示打印每个执行的命令。 -e
表示如果脚本中的任何命令失败,则退出失败。
所以我认为在你的情况下发生的事情是你的 git 命令以 1 退出,并且由于默认的 -e
参数,shell 会选择非 0 退出代码,忽略脚本的其余部分并将步骤标记为失败.如果您可以在此处发布构建步骤脚本,我们可以确认这一点。
如果是这种情况,您可以尝试放置 #!/bin/sh
以便脚本将在没有选项的情况下执行;或在构建步骤之上执行 set +e
或类似操作以覆盖此行为。
已编辑:另外需要注意的是,如果您的 shell 脚本中的 last command 返回非 0 代码,即使这样,整个构建步骤仍将被标记为失败设置。在这种情况下,您只需将 true
命令放在末尾即可避免这种情况。
2>/dev/null
抑制错误时 Jenkins 失败的问题。谢谢!
如果没有推送 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 文本查找器。它可以通过控制台输出,匹配模式(你的回声)并将构建标记为不稳定。
还有另一种告诉詹金斯不要失败的顺利方法。您可以在构建步骤中隔离您的提交并将外壳设置为不失败:
set +e
git commit -m "Bla."
set -e
set -e
。否则,您可能最终会执行您不打算执行的命令。我想自己处理错误,所以我做了类似的事情:` set +e commit -m "bla" EXIT_CODE="${?}" set -e # handle exit code logic `
This answer 是正确的,但它没有指定 || exit 0
或 || true
在 shell 命令中。这是一个更完整的示例:
sh "adb uninstall com.example.app || true"
以上将起作用,但以下将失败:
sh "adb uninstall com.example.app" || true
也许这对其他人来说是显而易见的,但在我意识到这一点之前,我浪费了很多时间。
我能够使用此处找到的答案来完成这项工作:
How to git commit nothing without an error?
git diff --quiet --exit-code --cached || git commit -m 'bla'
git diff
命令,如果失败,执行 git commit
命令。基本上,如果 git diff
找到要提交的内容,它只会提交。但是@jwernerny 的回答是正确的,你应该能够将 exit 0
添加为任何脚本的最后一条语句,以使 Jenkins 将其视为成功。我可以想到一种情况,如果您正在执行 Linux shell 步骤,这将失败,但在批处理中,这应该始终有效。
/bin/sh -xe
执行 shell 构建步骤,如提到的 here(在中间)。因此,您可以尝试在构建步骤之上放置 #!/bin/bash
或执行 set +e
以覆盖此行为,这将继续该步骤的其余部分,即使退出中的一个命令使用非 0 代码
Jenkins 通过步骤的返回值来确定步骤的成功/失败。对于 shell 的情况,它应该是最后一个值的返回。对于 Windows CMD 和 (POSIX) Bash shell,您应该能够通过使用 exit 0
作为最后一个命令来手动设置返回值。
exit 0
和“执行 Windows 批处理命令”,它按预期工作。一定有别的事情发生。您能否发布控制台日志的相关部分?
#!/bin/sh -xv
执行 shell,如果遇到任何错误,则会停止脚本。
在标题中的(更一般的)问题上 - 为了防止 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
。
https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
如果包含 returnStatus: true 属性,则忽略 shell 返回。
对于多个 shell 命令,我通过添加以下内容来忽略失败:
set +e commands true
https://i.stack.imgur.com/3KLyE.png
如果将此命令放入 shell 块中:
false
true
您的构建将被标记为失败(至少 1 个非零退出代码),因此您可以添加 (set +e) 以忽略它:
set +e
false
true
不会失败。但是,即使 (set +e) 就位,这也会失败:
set +e
false
因为最后一个 shell 命令必须以 0 退出。
以下内容仅适用于 mercurial,仅在有更改时才提交。因此,只有在提交失败时构建才会失败。
hg id | grep "+" || exit 0
hg commit -m "scheduled commit"
另一个带有一些提示的答案可能对某人有所帮助:
请记住将您的命令分开 with the following rule:
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
如果 gmake test
失败(您的测试失败),将使用 set -e
和 echo 0
命令成功执行,同时截断以下代码:
String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test && set -e && echo 0 ", returnStdout: true).trim()
println run_tests
有点错误,&& gmake test && set -e && echo 0
中的命令 set -e
和 echo 0
将被跳过,使用 println run_tests
语句,因为失败的 gmake test
将中止 jenkins 构建。作为解决方法,您可以切换到 returnStatus:true
,但您会错过命令的输出。
不定期副业成功案例分享
|| exit 0
,如果command
返回 false,则执行将停止。也就是说,第二个选项非常有帮助!exit 0
,因为任何非零退出代码都会使构建失败。