docs icon indicating copy to clipboard operation
docs copied to clipboard

[GitHub Actions] Fail fast from the default shells (bash/sh) in Linux/macOS

Open iamazeem opened this issue 2 years ago • 5 comments

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 using set -eo pipefail: This option is set when shell: bash is 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.

  • -e is applied by default to sh and bash.
  • -o pipefail is only applied to bash (e.g. bash -e -o pipefail) and not sh.
  • sh command should also have pipefail but 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/

iamazeem avatar Feb 11 '23 13:02 iamazeem

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.

welcome[bot] avatar Feb 11 '23 13:02 welcome[bot]

@iamazeem Thanks so much for opening an issue! I'll triage this for the team to take a look :eyes:

cmwilson21 avatar Feb 13 '23 15:02 cmwilson21

No wait! Don't mark this as stale!

norwd avatar Apr 23 '23 21:04 norwd

So is this going to be updated? I just spent too long digging through the internet to find this

ms-ati avatar Jun 06 '23 20:06 ms-ati

@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.

iamazeem avatar Jun 07 '23 05:06 iamazeem

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 avatar Jul 19 '23 23:07 jmarshall

@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 avatar Jul 20 '23 07:07 iamazeem

@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 avatar Aug 08 '23 09:08 hubwriter

@hubwriter: PR #27583 created. Please review. Thanks!

iamazeem avatar Aug 19 '23 07:08 iamazeem