Reputation: 16534
As part of my build process, I am running a git commit as an execute shell step. However, if there are no changes in the workspace, Jenkins is failing the build. This is because git is returning an error code when there are no changes to commit. I'd like to either abort the build, or just mark it as unstable if this is the case. Any ideas?
Upvotes: 178
Views: 253390
Reputation: 398
For Windows node can be done the following trick:
command_that_fails || set errorlevel=0
Yes, I see #linux and #unix tags, but Jenkins also runs on Windows and there ignoring errors can also be very useful :)
Upvotes: 1
Reputation: 1720
Jenkins is executing shell build steps using /bin/sh -xe
by default. -x
means to print every command executed. -e
means to exit with failure if any of the commands in the script failed.
So I think what happened in your case is your git command exit with 1, and because of the default -e
param, the shell picks up the non-0 exit code, ignores the rest of the script and marks the step as a failure. We can confirm this if you can post your build step script here.
If that's the case, you can try to put #!/bin/sh
so that the script will be executed without option; or do a set +e
or anything similar on top of the build step to override this behavior.
Edited: Another thing to note is that, if the last command in your shell script returns non-0 code, the whole build step will still be marked as fail even with this setup. In this case, you can simply put a true
command at the end to avoid that.
Upvotes: 110
Reputation: 16056
This answer is correct, but it doesn't specify the || exit 0
or || true
goes inside the shell command. Here's a more complete example:
sh "adb uninstall com.example.app || true"
The above will work, but the following will fail:
sh "adb uninstall com.example.app" || true
Perhaps it's obvious to others, but I wasted a lot of time before I realized this.
Upvotes: 24
Reputation: 529
For multiple shell commands, I ignores the failures by adding:
set +e
commands
true
Upvotes: 6
Reputation: 1793
Another one answer with some tips, can be helpful for somebody:
remember to separate your commands with the following rule:
command1 && command2 - means, that command2 will be executed, only if command1 success
command1 ; command2 - means, that command 2 will be executed despite on result of command1
for example:
String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test ;set -e;echo 0 ", returnStdout: true).trim()
println run_tests
will be executed successfully with set -e
and echo 0
commands if gmake test
failed (your tests failed), while the following code snipped:
String run_tests = sh(script: "set +e && cd ~/development/tests/ && gmake test && set -e && echo 0 ", returnStdout: true).trim()
println run_tests
a bit wrong and commands set -e
and echo 0
in&& gmake test && set -e && echo 0
will be skipped, with the println run_tests
statement, because failed gmake test
will abort the jenkins build. As workaround you can switch to returnStatus:true
, but then you will miss the output from your command.
Upvotes: 1
Reputation: 302
https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
if you include a returnStatus: true property, then the shell return is ignored.
Upvotes: 15
Reputation: 4637
There is another smooth way to tell Jenkins not to fail. You can isolate your commit in a build step and set the shell to not fail:
set +e
git commit -m "Bla."
set -e
Upvotes: 34
Reputation: 5742
If you put this commands into shell block:
false
true
your build will be marked as fail ( at least 1 non-zero exit code ), so you can add (set +e) to ignore it:
set +e
false
true
will not fail. However, this will fail even with the (set +e) in place:
set +e
false
because the last shell command must exit with 0.
Upvotes: 4
Reputation: 6978
To stop further execution when command fails:
command || exit 0
To continue execution when command fails:
command || true
Upvotes: 285
Reputation: 10012
On the (more general) question in title - to prevent Jenkins from failing you can prevent it from seeing exit code 1. Example for ping:
bash -c "ping 1.2.3.9999 -c 1; exit 0"
And now you can e.g. get output of ping:
output=`bash -c "ping 1.2.3.9999 -c 1; exit 0"`
Of course instead of ping ...
You can use any command(s) - including git commit
.
Upvotes: 8
Reputation: 561
If there is nothing to push git returns exit status 1. Execute shell build step is marked as failed respectively. You can use OR statement || (double pipe).
git commit -m 'some messasge' || echo 'Commit failed. There is probably nothing to commit.'
That means, execute second argument if first failed (returned exit status > 0). Second command always returns 0. When there is nothing to push (exit status 1 -> execute second command) echo will return 0 and build step continues.
To mark build as unstable you can use post-build step Jenkins Text Finder. It can go through console output, match pattern (your echo) and mark build as unstable.
Upvotes: 46
Reputation: 2541
The following works for mercurial by only committing if there are changes. So the build only fails if the commit fails.
hg id | grep "+" || exit 0
hg commit -m "scheduled commit"
Upvotes: 2
Reputation: 16534
I was able to get this working using the answer found here:
How to git commit nothing without an error?
git diff --quiet --exit-code --cached || git commit -m 'bla'
Upvotes: 10
Reputation: 7048
Jenkins determines the success/failure of a step by the return value of the step. For the case of a shell, it should be the return of the last value. For both Windows CMD and (POSIX) Bash shells, you should be able to set the return value manually by using exit 0
as the last command.
Upvotes: 8
Reputation: 628
You can use the Text-finder Plugin. It will allow you to check the output console for an expression of your choice then mark the build as Unstable
.
Upvotes: 6