From 09773f7c5c5fdf327fbebb1a2f09bf3fd32ff083 Mon Sep 17 00:00:00 2001 From: Casey Lee Date: Thu, 13 Feb 2020 11:47:38 -0800 Subject: [PATCH] fix tests Signed-off-by: Casey Lee --- Makefile | 2 +- pkg/runner/command.go | 6 +- pkg/runner/command_test.go | 6 +- pkg/runner/expression.go | 128 +++++++++++++++++++++++++++++++--- pkg/runner/expression_test.go | 22 ++++++ pkg/runner/run_context.go | 19 ++--- pkg/runner/step.go | 7 +- 7 files changed, 160 insertions(+), 30 deletions(-) diff --git a/Makefile b/Makefile index 8c99202..d0192e1 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ test: go test -cover -short ./... check: - $(ACT) -rj ci + $(ACT) -orj ci build: check $(eval export SNAPSHOT_VERSION=$(VERSION)) diff --git a/pkg/runner/command.go b/pkg/runner/command.go index 6e0ab67..8088a1a 100644 --- a/pkg/runner/command.go +++ b/pkg/runner/command.go @@ -2,7 +2,6 @@ package runner import ( "context" - "fmt" "regexp" "strings" @@ -72,10 +71,7 @@ func (rc *RunContext) setOutput(ctx context.Context, kvPairs map[string]string, } func (rc *RunContext) addPath(ctx context.Context, arg string) { common.Logger(ctx).Infof(" \U00002699 ::add-path:: %s", arg) - if rc.Env == nil { - rc.Env = make(map[string]string) - } - rc.Env["PATH"] = fmt.Sprintf("%s:%s", arg, rc.Env["PATH"]) + rc.ExtraPath = append(rc.ExtraPath, arg) } func parseKeyValuePairs(kvPairs string) map[string]string { diff --git a/pkg/runner/command_test.go b/pkg/runner/command_test.go index 31b265a..ec41afb 100644 --- a/pkg/runner/command_test.go +++ b/pkg/runner/command_test.go @@ -34,10 +34,10 @@ func TestAddpath(t *testing.T) { handler := rc.commandHandler(ctx) handler("::add-path::/zoo\n") - assert.Equal("/zoo:", rc.Env["PATH"]) + assert.Equal("/zoo", rc.ExtraPath[0]) - handler("::add-path::/booo\n") - assert.Equal("/booo:/zoo:", rc.Env["PATH"]) + handler("::add-path::/boo\n") + assert.Equal("/boo", rc.ExtraPath[1]) } func TestStopCommands(t *testing.T) { diff --git a/pkg/runner/expression.go b/pkg/runner/expression.go index 4fc0c1d..7e3c99c 100644 --- a/pkg/runner/expression.go +++ b/pkg/runner/expression.go @@ -75,7 +75,17 @@ func (rc *RunContext) newVM() *otto.Otto { vmFormat, vmJoin, vmToJSON, - vmHashFiles(rc.Config.Workdir), + vmAlways, + vmCancelled, + rc.vmHashFiles(), + rc.vmSuccess(), + rc.vmFailure(), + + rc.vmGithub(), + rc.vmEnv(), + rc.vmJob(), + rc.vmSteps(), + rc.vmRunner(), } vm := otto.New() for _, configer := range configers { @@ -85,12 +95,12 @@ func (rc *RunContext) newVM() *otto.Otto { } func vmContains(vm *otto.Otto) { - vm.Set("contains", func(searchString interface{}, searchValue string) bool { + _ = vm.Set("contains", func(searchString interface{}, searchValue string) bool { if searchStringString, ok := searchString.(string); ok { return strings.Contains(strings.ToLower(searchStringString), strings.ToLower(searchValue)) } else if searchStringArray, ok := searchString.([]string); ok { for _, s := range searchStringArray { - if strings.ToLower(s) == strings.ToLower(searchValue) { + if strings.EqualFold(s, searchValue) { return true } } @@ -100,19 +110,19 @@ func vmContains(vm *otto.Otto) { } func vmStartsWith(vm *otto.Otto) { - vm.Set("startsWith", func(searchString string, searchValue string) bool { + _ = vm.Set("startsWith", func(searchString string, searchValue string) bool { return strings.HasPrefix(strings.ToLower(searchString), strings.ToLower(searchValue)) }) } func vmEndsWith(vm *otto.Otto) { - vm.Set("endsWith", func(searchString string, searchValue string) bool { + _ = vm.Set("endsWith", func(searchString string, searchValue string) bool { return strings.HasSuffix(strings.ToLower(searchString), strings.ToLower(searchValue)) }) } func vmFormat(vm *otto.Otto) { - vm.Set("format", func(s string, vals ...string) string { + _ = vm.Set("format", func(s string, vals ...string) string { for i, v := range vals { s = strings.ReplaceAll(s, fmt.Sprintf("{%d}", i), v) } @@ -121,7 +131,7 @@ func vmFormat(vm *otto.Otto) { } func vmJoin(vm *otto.Otto) { - vm.Set("join", func(element interface{}, optionalElem string) string { + _ = vm.Set("join", func(element interface{}, optionalElem string) string { slist := make([]string, 0) if elementString, ok := element.(string); ok { slist = append(slist, elementString) @@ -136,7 +146,7 @@ func vmJoin(vm *otto.Otto) { } func vmToJSON(vm *otto.Otto) { - vm.Set("toJSON", func(o interface{}) string { + _ = vm.Set("toJSON", func(o interface{}) string { rtn, err := json.MarshalIndent(o, "", " ") if err != nil { logrus.Errorf("Unable to marsal: %v", err) @@ -146,10 +156,10 @@ func vmToJSON(vm *otto.Otto) { }) } -func vmHashFiles(workdir string) func(*otto.Otto) { +func (rc *RunContext) vmHashFiles() func(*otto.Otto) { return func(vm *otto.Otto) { - vm.Set("hashFiles", func(path string) string { - files, _, err := glob.Glob([]string{filepath.Join(workdir, path)}) + _ = vm.Set("hashFiles", func(path string) string { + files, _, err := glob.Glob([]string{filepath.Join(rc.Config.Workdir, path)}) if err != nil { logrus.Error(err) return "" @@ -169,3 +179,99 @@ func vmHashFiles(workdir string) func(*otto.Otto) { }) } } + +func (rc *RunContext) vmSuccess() func(*otto.Otto) { + return func(vm *otto.Otto) { + _ = vm.Set("success", func() bool { + return !rc.PriorStepFailed + }) + } +} +func (rc *RunContext) vmFailure() func(*otto.Otto) { + return func(vm *otto.Otto) { + _ = vm.Set("failure", func() bool { + return rc.PriorStepFailed + }) + } +} + +func vmAlways(vm *otto.Otto) { + _ = vm.Set("always", func() bool { + return true + }) +} +func vmCancelled(vm *otto.Otto) { + _ = vm.Set("cancelled", func() bool { + return false + }) +} + +func (rc *RunContext) vmGithub() func(*otto.Otto) { + github := map[string]interface{}{ + "event": make(map[string]interface{}), + "event_path": "/github/workflow/event.json", + "workflow": rc.Run.Workflow.Name, + "run_id": "1", + "run_number": "1", + "actor": "nektos/act", + + // TODO + "repository": "", + "event_name": "", + "sha": "", + "ref": "", + "head_ref": "", + "base_ref": "", + "token": "", + "workspace": rc.Config.Workdir, + "action": "", + } + + err := json.Unmarshal([]byte(rc.EventJSON), github["event"]) + if err != nil { + logrus.Error(err) + } + + return func(vm *otto.Otto) { + _ = vm.Set("github", github) + } +} + +func (rc *RunContext) vmEnv() func(*otto.Otto) { + env := map[string]interface{}{} + // TODO + + return func(vm *otto.Otto) { + _ = vm.Set("env", env) + } +} + +func (rc *RunContext) vmJob() func(*otto.Otto) { + job := map[string]interface{}{} + // TODO + + return func(vm *otto.Otto) { + _ = vm.Set("job", job) + } +} + +func (rc *RunContext) vmSteps() func(*otto.Otto) { + steps := map[string]interface{}{} + // TODO + + return func(vm *otto.Otto) { + _ = vm.Set("steps", steps) + } +} + +func (rc *RunContext) vmRunner() func(*otto.Otto) { + runner := map[string]interface{}{ + "os": "Linux", + "temp": "/tmp", + "tool_cache": "/tmp", + } + + return func(vm *otto.Otto) { + _ = vm.Set("runner", runner) + } +} diff --git a/pkg/runner/expression_test.go b/pkg/runner/expression_test.go index 9beffe7..bf085d4 100644 --- a/pkg/runner/expression_test.go +++ b/pkg/runner/expression_test.go @@ -3,6 +3,7 @@ package runner import ( "testing" + "github.com/nektos/act/pkg/model" "github.com/stretchr/testify/assert" ) @@ -12,6 +13,12 @@ func TestEvaluate(t *testing.T) { Config: &Config{ Workdir: ".", }, + Run: &model.Run{ + JobID: "job1", + Workflow: &model.Workflow{ + Name: "test-workflow", + }, + }, } ee := rc.NewExpressionEvaluator() @@ -36,6 +43,15 @@ func TestEvaluate(t *testing.T) { {"join('hello','mona')", "hello mona", ""}, {"toJSON({'foo':'bar'})", "{\n \"foo\": \"bar\"\n}", ""}, {"hashFiles('**/package-lock.json')", "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""}, + {"success()", "true", ""}, + {"failure()", "false", ""}, + {"always()", "true", ""}, + {"cancelled()", "false", ""}, + {"github.workflow", "test-workflow", ""}, + {"github.actor", "nektos/act", ""}, + {"github.run_id", "1", ""}, + {"github.run_number", "1", ""}, + {"runner.os", "Linux", ""}, } for _, table := range tables { @@ -59,6 +75,12 @@ func TestInterpolate(t *testing.T) { Config: &Config{ Workdir: ".", }, + Run: &model.Run{ + JobID: "job1", + Workflow: &model.Workflow{ + Name: "test-workflow", + }, + }, } ee := rc.NewExpressionEvaluator() diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index 419c548..aca86de 100644 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -22,21 +22,20 @@ import ( // RunContext contains info about current job type RunContext struct { - Config *Config - Run *model.Run - EventJSON string - Env map[string]string - Outputs map[string]string - Tempdir string + Config *Config + Run *model.Run + EventJSON string + Env map[string]string + Outputs map[string]string + Tempdir string + PriorStepFailed bool + ExtraPath []string } // GetEnv returns the env for the context func (rc *RunContext) GetEnv() map[string]string { if rc.Env == nil { rc.Env = mergeMaps(rc.Run.Workflow.Env, rc.Run.Job().Env) - if rc.Env["PATH"] == "" { - rc.Env["PATH"] = "/usr/local/bin:/usr/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin" - } } return rc.Env } @@ -64,8 +63,10 @@ func (rc *RunContext) Executor() common.Executor { err := rc.newStepExecutor(s)(ctx) if err == nil { common.Logger(ctx).Infof(" \u2705 Success - %s", s) + rc.PriorStepFailed = false } else { common.Logger(ctx).Errorf(" \u274C Failure - %s", s) + rc.PriorStepFailed = true } return err }) diff --git a/pkg/runner/step.go b/pkg/runner/step.go index f5fd8f1..ba7fa7a 100644 --- a/pkg/runner/step.go +++ b/pkg/runner/step.go @@ -163,7 +163,12 @@ func (rc *RunContext) setupShellCommand(containerSpec *model.ContainerSpec, shel return err } - if _, err := tempScript.Write([]byte(run)); err != nil { + _, err = tempScript.WriteString(fmt.Sprintf("PATH=\"%s:${PATH}\"\n", strings.Join(rc.ExtraPath, ":"))) + if err != nil { + return err + } + + if _, err := tempScript.WriteString(run); err != nil { return err } log.Debugf("Wrote command '%s' to '%s'", run, tempScript.Name())