diff --git a/act/model/workflow_test.go b/act/model/workflow_test.go index 96f4e004..6960e25b 100644 --- a/act/model/workflow_test.go +++ b/act/model/workflow_test.go @@ -546,25 +546,6 @@ func TestReadWorkflow_Strategy(t *testing.T) { assert.Equal(t, job.Strategy.FailFast, false) } -func TestStep_ShellCommand(t *testing.T) { - tests := []struct { - shell string - want string - }{ - {"pwsh -v '. {0}'", "pwsh -v '. {0}'"}, - {"pwsh", "pwsh -command . '{0}'"}, - {"powershell", "powershell -command . '{0}'"}, - {"node", "node {0}"}, - {"python", "python {0}"}, - } - for _, tt := range tests { - t.Run(tt.shell, func(t *testing.T) { - got := (&Step{Shell: tt.shell}).ShellCommand() - assert.Equal(t, got, tt.want) - }) - } -} - func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) { yaml := ` name: local-action-docker-url diff --git a/act/runner/step_run.go b/act/runner/step_run.go index f543ad34..c085be4d 100644 --- a/act/runner/step_run.go +++ b/act/runner/step_run.go @@ -93,6 +93,28 @@ func getScriptName(rc *RunContext, step *model.Step) string { return fmt.Sprintf("workflow/%s", scriptName) } +func shellCommand(shell string) string { + // Reference: https://github.com/actions/runner/blob/8109c962f09d9acc473d92c595ff43afceddb347/src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs#L9-L17 + switch shell { + case "", "bash": + return "bash --noprofile --norc -e -o pipefail {0}" + case "pwsh": + return "pwsh -command . '{0}'" + case "python": + return "python {0}" + case "sh": + return "sh -e {0}" + case "cmd": + return "cmd /D /E:ON /V:OFF /S /C \"CALL \"{0}\"\"" + case "powershell": + return "powershell -command . '{0}'" + case "node": + return "node {0}" + default: + return shell + } +} + // TODO: Currently we just ignore top level keys, BUT we should return proper error on them // BUTx2 I leave this for when we rewrite act to use actionlint for workflow validation // so we return proper errors before any execution or spawning containers @@ -107,27 +129,7 @@ func (sr *stepRun) setupShellCommand(ctx context.Context) (name, script string, script = sr.RunContext.NewStepExpressionEvaluator(ctx, sr).Interpolate(ctx, step.Run) - var shellCommand string - // Reference: https://github.com/actions/runner/blob/8109c962f09d9acc473d92c595ff43afceddb347/src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs#L9-L17 - switch shell { - case "", "bash": - shellCommand = "bash --noprofile --norc -e -o pipefail {0}" - case "pwsh": - shellCommand = "pwsh -command . '{0}'" - case "python": - shellCommand = "python {0}" - case "sh": - shellCommand = "sh -e {0}" - case "cmd": - shellCommand = "cmd /D /E:ON /V:OFF /S /C \"CALL \"{0}\"\"" - case "powershell": - shellCommand = "powershell -command . '{0}'" - case "node": - shellCommand = "node {0}" - default: - shellCommand = shell - } - + shellCommand := shellCommand(shell) name = getScriptName(sr.RunContext, step) // Reference: https://github.com/actions/runner/blob/8109c962f09d9acc473d92c595ff43afceddb347/src/Runner.Worker/Handlers/ScriptHandlerHelpers.cs#L47-L64 diff --git a/act/runner/step_run_test.go b/act/runner/step_run_test.go index b49e2405..1fe376f2 100644 --- a/act/runner/step_run_test.go +++ b/act/runner/step_run_test.go @@ -93,3 +93,22 @@ func TestStepRunPrePost(t *testing.T) { err = sr.post()(ctx) assert.Nil(t, err) } + +func TestStepShellCommand(t *testing.T) { + tests := []struct { + shell string + want string + }{ + {"pwsh -v '. {0}'", "pwsh -v '. {0}'"}, + {"pwsh", "pwsh -command . '{0}'"}, + {"powershell", "powershell -command . '{0}'"}, + {"node", "node {0}"}, + {"python", "python {0}"}, + } + for _, tt := range tests { + t.Run(tt.shell, func(t *testing.T) { + got := shellCommand(tt.shell) + assert.Equal(t, got, tt.want) + }) + } +}