Skip to content

Default non-Windows bash is not invoked as documented #353

@johnstevenson

Description

@johnstevenson

Describe the bug
The documentation at https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun implies that when a shell is not specified on a non-Windows platform, bash (if found) will be invoked as bash --noprofile --norc -eo pipefail {0}.

Fail-fast behavior using set -e o pipefail: Default for bash and built-in shell. It is also the default when you don't provide an option on non-Windows platforms.

However, this is not exactly the case.

To Reproduce
Steps to reproduce the behavior:

  1. Create an action without specifying a shell value:
    - name: No shell specified (default bash)
      run: echo Hello, world!
  1. Observe that it is executed as shell: /bin/bash -e {0} as per this example at https://github.com/johnstevenson/runner-actions-test/actions/runs/48283923 which also shows the documented behaviour when the shell is specified.

action-error-bash

Expected behavior
For the command to be executed as shell: /bin/bash --noprofile --norc -e -o pipefail {0}

Runner Version and Platform

Current runner version: 2.165.2
Tested on ubuntu-latest and macos-latest

What's not working?

Regardless of whether this is a documentation problem (or my incorrect interpretation), there is no consistency when invoking bash with and without a shell value.

The ScriptHandler:RunAsync code (also duplicated in ScriptHandler:PrintActionDetails) sets shellCommand as sh even if bash is found, resulting in the wrong format string being used:

if (string.IsNullOrEmpty(shell))
{
#if OS_WINDOWS
shellCommand = "pwsh";
commandPath = WhichUtil.Which(shellCommand, require: false, Trace, prependPath);
if (string.IsNullOrEmpty(commandPath))
{
shellCommand = "powershell";
Trace.Info($"Defaulting to {shellCommand}");
commandPath = WhichUtil.Which(shellCommand, require: true, Trace, prependPath);
}
ArgUtil.NotNullOrEmpty(commandPath, "Default Shell");
#else
shellCommand = "sh";
commandPath = WhichUtil.Which("bash", false, Trace, prependPath) ?? WhichUtil.Which("sh", true, Trace, prependPath);
#endif
argFormat = ScriptHandlerHelpers.GetScriptArgumentsFormat(shellCommand);

So any fix would be:

#if OS_WINDOWS
                shellCommand = "pwsh";
                commandPath = WhichUtil.Which(shellCommand, require: false, Trace, prependPath);
                if (string.IsNullOrEmpty(commandPath))
                {
                    shellCommand = "powershell";
                    Trace.Info($"Defaulting to {shellCommand}");
                    commandPath = WhichUtil.Which(shellCommand, require: true, Trace, prependPath);
                }
                ArgUtil.NotNullOrEmpty(commandPath, "Default Shell");
#else
                shellCommand = "bash";
                commandPath = WhichUtil.Which(shellCommand, require: false, Trace, prependPath)
                if (string.IsNullOrEmpty(commandPath))
                {
                    shellCommand = "sh";
                    Trace.Info($"Defaulting to {shellCommand}");
                    commandPath = WhichUtil.Which(shellCommand, require: true, Trace, prependPath);
                }
                ArgUtil.NotNullOrEmpty(commandPath, "Default Shell");
#endif
                argFormat = ScriptHandlerHelpers.GetScriptArgumentsFormat(shellCommand);

I'd happily PR this if needed and if I could find out how you debug an action in Visual Studio (are there any docs about this?)

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions