From 4e046e1ec078e9f80ac91afaa4d659e4f118be5e Mon Sep 17 00:00:00 2001 From: Casey Lee Date: Fri, 7 Feb 2020 16:59:07 -0800 Subject: [PATCH] support custom shell Signed-off-by: Casey Lee --- .github/workflows/basic.yml | 5 ++++ pkg/runner/run_context.go | 58 ++++++++++++++++++++++++++++++------- pkg/runner/runner_test.go | 3 +- 3 files changed, 54 insertions(+), 12 deletions(-) diff --git a/.github/workflows/basic.yml b/.github/workflows/basic.yml index ae962d0..b570a86 100644 --- a/.github/workflows/basic.yml +++ b/.github/workflows/basic.yml @@ -2,6 +2,10 @@ name: basic on: push jobs: + action: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 build: runs-on: ubuntu-latest container: @@ -12,6 +16,7 @@ jobs: - run: env test: runs-on: ubuntu-latest + needs: [build] steps: - run: cp $GITHUB_EVENT_PATH $HOME/foo.json - run: ls $HOME diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index e00c9c4..fcbfeb9 100644 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -10,6 +10,7 @@ import ( "os" "path/filepath" "regexp" + "runtime" "strings" "github.com/nektos/act/pkg/container" @@ -105,8 +106,7 @@ func (rc *RunContext) Executor() common.Executor { // read action.yaml // if runs.using == node12, start node12 container and run `main` // if runs.using == docker, pull `image` and run - // set inputs as env - // caputre output + // caputre output/commands } else { stepExecutor = common.NewErrorExecutor(fmt.Errorf("Unable to determine how to run job:%s step:%+v", rc.Run, step)) } @@ -125,13 +125,13 @@ func (rc *RunContext) setupContainerSpec(step *model.Step, containerSpec *model. containerSpec.Image = step.Uses } else if job.Container != nil { containerSpec.Image = job.Container.Image - containerSpec.Args = step.Run + containerSpec.Args = rc.shellCommand(step.Shell, step.Run) containerSpec.Ports = job.Container.Ports containerSpec.Volumes = job.Container.Volumes containerSpec.Options = job.Container.Options } else if step.Run != "" { containerSpec.Image = platformImage(job.RunsOn) - containerSpec.Args = step.Run + containerSpec.Args = rc.shellCommand(step.Shell, step.Run) } else { return fmt.Errorf("Unable to setup container for %s", step) } @@ -139,6 +139,44 @@ func (rc *RunContext) setupContainerSpec(step *model.Step, containerSpec *model. } } +func (rc *RunContext) shellCommand(shell string, run string) string { + shellCommand := "" + + switch shell { + case "", "bash": + shellCommand = "bash --noprofile --norc -eo pipefail {0}" + case "pwsh": + shellCommand = "pwsh -command \"& '{0}'\"" + case "python": + shellCommand = "python {0}" + case "sh": + shellCommand = "sh -e -c {0}" + case "cmd": + shellCommand = "%ComSpec% /D /E:ON /V:OFF /S /C \"CALL \"{0}\"\"" + case "powershell": + shellCommand = "powershell -command \"& '{0}'\"" + default: + shellCommand = shell + } + + tempScript, err := ioutil.TempFile(rc.Tempdir, ".temp-script-") + if err != nil { + log.Fatalf("Unable to create temp script %v", err) + } + + if _, err := tempScript.Write([]byte(run)); err != nil { + log.Fatal(err) + } + log.Debugf("Wrote command '%s' to '%s'", run, tempScript.Name()) + if err := tempScript.Close(); err != nil { + log.Fatal(err) + } + containerPath := fmt.Sprintf("/github/home/%s", filepath.Base(tempScript.Name())) + cmd := strings.Replace(shellCommand, "{0}", containerPath, 1) + log.Debugf("about to run %s", cmd) + return cmd +} + func platformImage(platform string) string { switch platform { case "ubuntu-latest", "ubuntu-18.04": @@ -165,7 +203,11 @@ func mergeMaps(maps ...map[string]string) map[string]string { func (rc *RunContext) setupTempDir() common.Executor { return func(ctx context.Context) error { var err error - rc.Tempdir, err = ioutil.TempDir("", "act-") + tempBase := "" + if runtime.GOOS == "darwin" { + tempBase = "/tmp" + } + rc.Tempdir, err = ioutil.TempDir(tempBase, "act-") return err } } @@ -192,11 +234,7 @@ func (rc *RunContext) runContainer(containerSpec *model.ContainerSpec) common.Ex } var cmd, entrypoint []string if containerSpec.Args != "" { - cmd = []string{ - "/bin/sh", - "-c", - containerSpec.Args, - } + cmd = strings.Fields(containerSpec.Args) } if containerSpec.Entrypoint != "" { entrypoint = strings.Fields(containerSpec.Entrypoint) diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 5ca1d0f..e932980 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -9,8 +9,7 @@ import ( ) func TestGraphEvent(t *testing.T) { - runnerConfig := &RunnerConfig{ - Ctx: context.Background(), + runnerConfig := &Config{ WorkflowPath: "multi.workflow", WorkingDir: "testdata", EventName: "push",