[GitHub Actions] Fail fast from the default shells (bash/sh) in Linux/macOS
Code of Conduct
- [X] I have read and agree to the GitHub Docs project's Code of Conduct
What article on docs.github.com is affected?
https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
What part(s) of the article would you like to see updated?
The jobs.<job_id>.steps[*].shell lists the default shell commands for Linux/macOS under Command run internally column:
| shell | command |
|---|---|
| unspecified | bash -e {0} |
bash |
bash --noprofile --norc -eo pipefail {0} |
sh |
sh -e {0} |
All these variants have -e and according to its description under The Set Builtin section form the Bash manual:
-e: Exit immediately if a pipeline (see Pipelines), which may consist of a single simple command (see Simple Commands), a list (see Lists of Commands), or a compound command (see Compound Commands) returns a non-zero status.
Which is equivalent to the fail fast behavior.
But, according to the Exit codes and error action preference:
bash/sh: Fail-fast behavior usingset -eo pipefail: This option is set whenshell: bashis explicitly specified. It is not applied by default.
And, that is not the case. The section only applies to the -o pipefail part (Bash only) and -e is applied by default.
The -o pipeline only affects the returning of the exit status from Pipelines in Bash:
pipefail: If set, the return value of a pipeline is the value of the last (rightmost) command to exit with a non-zero status, or zero if all commands in the pipeline exit successfully.
The docs should be revised to avoid contradiction when both these sections are read in conjunction.
-
-eis applied by default toshandbash. -
-o pipefailis only applied tobash(e.g.bash -e -o pipefail) and notsh. -
shcommand should also havepipefailbut at the moment it doesn't. Also, it has a different syntax i.e.sh -e -pipefail.
Additional information
Here's a sample workflow run: https://github.com/iamazeem/test/actions/runs/4151342608/
Thanks for opening this issue. A GitHub docs team member should be by to give feedback soon. In the meantime, please check out the contributing guidelines.
@iamazeem Thanks so much for opening an issue! I'll triage this for the team to take a look :eyes:
No wait! Don't mark this as stale!
So is this going to be updated? I just spent too long digging through the internet to find this
@ms-ati: This was originated from this StackOverflow question. If you are blocked by this or need to discuss it, you are welcome to ask a question on SO under github-actions tag until this is updated.
sh command should also have pipefail but at the moment it doesn't. Also, it has a different syntax i.e. sh -e -pipefail.
What version of plain sh has a -pipefail option spelt thus?
The reason why the plain sh entry doesn't have this option is that traditionally plain sh has no equivalent of the pipefail behaviour. (Answers to and comments on this SO question note that -o pipefail is more widespread than it used to be and has been added to an upcoming POSIX revision.)
@jmarshall: Thank you for your input! :+1:
sh (sh -> dash) seems to accept -pipefail flag for version 0.5.8-2.10 (Ubuntu 18.04) and 0.5.11+git20210903+057cd650a4ed-3build1 (Ubuntu 22.04).
Tested both with docker:
ubuntu:18.04
$ docker run -it --rm ubuntu:18.04
root@0ee43bcb3993:/# ls -l $(which sh)
lrwxrwxrwx 1 root root 4 Apr 1 2022 /bin/sh -> dash
root@0ee43bcb3993:/# dpkg -s dash | grep 'Version'
Version: 0.5.8-2.10
root@0ee43bcb3993:/# sh -o pipefail
sh: 0: Illegal option -o pipefail
root@0ee43bcb3993:/#
root@0ee43bcb3993:/# sh -e -pipefail
# echo test | false | true
# echo $?
0
# exit
root@0ee43bcb3993:/# bash -e -o pipefail
root@0ee43bcb3993:/# echo test | false | true
root@0ee43bcb3993:/# echo $?
1
root@0ee43bcb3993:/# exit
exit
ubuntu:22.04
$ docker run -it --rm ubuntu:22.04
root@47bdd8723e19:/# ls -l $(which sh)
lrwxrwxrwx 1 root root 4 Mar 23 2022 /usr/bin/sh -> dash
root@47bdd8723e19:/# dpkg -s dash | grep 'Version'
Version: 0.5.11+git20210903+057cd650a4ed-3build1
root@47bdd8723e19:/# sh -o pipefail
sh: 0: Illegal option -o pipefail
root@47bdd8723e19:/#
root@47bdd8723e19:/# sh -e -pipefail
# echo test | false | true
# echo $?
0
# exit
root@47bdd8723e19:/# bash -e -o pipefail
root@47bdd8723e19:/# echo test | false | true
root@47bdd8723e19:/# echo $?
1
root@47bdd8723e19:/# exit
exit
However, -pipefail doesn't seem to be working as Bash's -o pipefail flag does.
The same is also clear from above tests in the docker containers.
I have updated my original description and struck the last line.
The original intent was to have clarification in the docs i.e. the default -e is both for sh and bash whereas -o pipefail is only for bash when specified in addition to -e.
@iamazeem - Thank you for raising this. It would be good to clarify this in https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions as per the initial description to this issue.
I've marked this issue help-wanted. If you (or anyone else reading this) would like to raise a pull request to update the docs accordingly that would be great.
Information about contributing to the docs: https://docs.github.com/en/contributing
@hubwriter: PR #27583 created. Please review. Thanks!