Unexpected step failure on failing Bash function statement

I source a Bash script and call its functions to build MariaDB on macOS.

When a command inside a function returns a non-zero exit code the GitHub Actions build fails whereas the AppVeyor build proceeds as expected.

I am not sure how I should change the step declaration to make my workflow have the same behavior I experience on AppVeyor.


The reason is that by default Github Actions runs bash with -e, as you can see in the logs near the top of the step:

  shell: /bin/bash -e {0}

That means that bash will exit with an error if any command fails, and the failure isn’t handled in some other way (e.g. by an if condition). Your question sounds like you want to ignore the error, there are basically two ways to do that:

  1. Use a custom shell for the run step, without the -e option, e.g.:
      - id: build-mariadb-from-sources
        name: Build MariaDB from sources
        shell: '/bin/bash {0}'
        run: |
          source ${{github.workspace}}/create-macOS-binaries.sh
          # ...
  1. Ignore the failure status for the problematic command within the run block, e.g. by appending || true to the failing command. A logical OR with true is always true, so the combined command never fails.

That said, ignoring what looks like a test failure risks trouble down the line. :wink:

Thanks for your help @airtower-luna!

I did some attempts to use an if but they did not work: should the if be part of the statement with a ; or a && or a || or can the if be some lines after the error, using $? to catch the exit code of the statement?

I usually do not ignore failures, but MariaDB tests, especially for very old versions, are known to contain bugs and I rely on a last install step as a go/no-go flag.

It’d be helpful to see what you tried and what results you got. :wink:

What I meant with if is something like this:

if command; then
   # do stuff for success

In that case a failure of command won’t make the whole script fail even with -e.

The logical OR thing would be:

command || true

Thanks for the clarification!

I tried something like this:

command >log 2>&1
local returnValue=$?
# other commands
if [ $returnValue -ne 0 ]; then
   cat log

But as you explained this does not prevent the shell (because of the -e) to make the step fail in the same exact way as if not if was used.

You can still do something like that with if:

if ! command >log 2>&1; then
   cat log
1 Like