-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
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:
- Create an action without specifying a shell value:
- name: No shell specified (default bash)
run: echo Hello, world!- 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.
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:
runner/src/Runner.Worker/Handlers/ScriptHandler.cs
Lines 152 to 168 in d80ab09
| 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?)
