Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does a GitHub action step use `set -e` semantics by default?

A common pattern in GitHub action workflows is to run something like this:

  - name: Install and Build 🔧
    run: |
      npm ci
      npm run build

Clearly the intention is to run the second command only if the first command succeeds.

When running on Linux, the question becomes if the shell runs with set -e semantics. This answer suggests that set -e semantics are the default.

I'm trying to find that information in the documentation, but I'm a bit confused how it is specified. The section on exit codes contains the following for shell/sh shells:

Fail-fast behavior using set -eo pipefail: This option is set when shell: bash is explicitly specified. It is not applied by default.

This seems to contradict the other answer (and question!), and would mean that the above pattern actually is invalid, because the second line would be executed even if the first line fails.

Am I just misreading the documentation, or is it really necessary to either always specify set -e manually or add the shell: bash explicitly to get the desired behavior?

like image 969
bluenote10 Avatar asked Feb 24 '26 14:02

bluenote10


1 Answers

Does a GitHub action step use set -e semantics by default?

Yes, it does.

According to jobs.<job_id>.steps[*].shell, the sh and bash invocations do include -e whether specified or unspecified.

  • unspecified: bash -e {0}
  • with shell: bash: bash --noprofile --norc -eo pipefail {0}
  • with shell: sh: sh -e {0}

However, this section specified under 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.

applies to the -o pipefail part for Bash only. It could have been more explicit though.

An issue has been created on the GitHub docs repo to revise this: https://github.com/github/docs/issues/23853


UPDATE

The respective PR has been merged and the Exit codes and error action preference section now mentions this explicitly:

  • bash/sh:
    • By default, fail-fast behavior is enforced using set -e for both sh and bash. When shell: bash is specified, -o pipefail is also applied to enforce early exit from pipelines that generate a non-zero exit status.
like image 177
Azeem Avatar answered Feb 27 '26 08:02

Azeem