From e520382d2fdc5872ca8e939c6c0f2e1e74749182 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Wed, 16 Nov 2022 22:42:57 +0100 Subject: [PATCH] feat: GITHUB_STATE and GITHUB_OUTPUT file commands (#1391) * feat: set-state and set-output file commands * increase test timeout from 10m to 15m * Prepare for HostExecutor PR Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> --- .github/workflows/checks.yml | 2 +- pkg/runner/step.go | 37 +++++++++++++++++++++++++++ pkg/runner/step_action_local_test.go | 29 +++++++++++++++++++-- pkg/runner/step_action_remote_test.go | 24 +++++++++++++++++ pkg/runner/step_docker_test.go | 12 +++++++++ pkg/runner/step_run_test.go | 12 +++++++++ 6 files changed, 113 insertions(+), 3 deletions(-) diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml index 4a321285..baf5196a 100644 --- a/.github/workflows/checks.yml +++ b/.github/workflows/checks.yml @@ -50,7 +50,7 @@ jobs: key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} restore-keys: | ${{ runner.os }}-go- - - run: go test -v -cover -coverprofile=coverage.txt -covermode=atomic ./... + - run: go test -v -cover -coverprofile=coverage.txt -covermode=atomic -timeout 15m ./... - name: Upload Codecov report uses: codecov/codecov-action@v3.1.1 with: diff --git a/pkg/runner/step.go b/pkg/runner/step.go index 4f7803e1..8a9d2b6d 100644 --- a/pkg/runner/step.go +++ b/pkg/runner/step.go @@ -3,9 +3,11 @@ package runner import ( "context" "fmt" + "path" "strings" "github.com/nektos/act/pkg/common" + "github.com/nektos/act/pkg/container" "github.com/nektos/act/pkg/exprparser" "github.com/nektos/act/pkg/model" ) @@ -94,6 +96,20 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo } logger.Infof("\u2B50 Run %s %s", stage, stepString) + // Prepare and clean Runner File Commands + actPath := rc.JobContainer.GetActPath() + outputFileCommand := path.Join("workflow", "outputcmd.txt") + stateFileCommand := path.Join("workflow", "statecmd.txt") + (*step.getEnv())["GITHUB_OUTPUT"] = path.Join(actPath, outputFileCommand) + (*step.getEnv())["GITHUB_STATE"] = path.Join(actPath, stateFileCommand) + _ = rc.JobContainer.Copy(actPath, &container.FileEntry{ + Name: outputFileCommand, + Mode: 0666, + }, &container.FileEntry{ + Name: stateFileCommand, + Mode: 0666, + })(ctx) + err = executor(ctx) if err == nil { @@ -117,6 +133,27 @@ func runStepExecutor(step step, stage stepStage, executor common.Executor) commo logger.WithField("stepResult", rc.StepResults[rc.CurrentStep].Outcome).Errorf(" \u274C Failure - %s %s", stage, stepString) } + // Process Runner File Commands + orgerr := err + state := map[string]string{} + err = rc.JobContainer.UpdateFromEnv(path.Join(actPath, stateFileCommand), &state)(ctx) + if err != nil { + return err + } + for k, v := range state { + rc.saveState(ctx, map[string]string{"name": k}, v) + } + output := map[string]string{} + err = rc.JobContainer.UpdateFromEnv(path.Join(actPath, outputFileCommand), &output)(ctx) + if err != nil { + return err + } + for k, v := range output { + rc.setOutput(ctx, map[string]string{"name": k}, v) + } + if orgerr != nil { + return orgerr + } return err } } diff --git a/pkg/runner/step_action_local_test.go b/pkg/runner/step_action_local_test.go index 8180d6de..6b14f3d2 100644 --- a/pkg/runner/step_action_local_test.go +++ b/pkg/runner/step_action_local_test.go @@ -2,6 +2,7 @@ package runner import ( "context" + "path/filepath" "strings" "testing" @@ -63,7 +64,7 @@ func TestStepActionLocalTest(t *testing.T) { }, } - salm.On("readAction", sal.Step, "/tmp/path/to/action", "", mock.Anything, mock.Anything). + salm.On("readAction", sal.Step, filepath.Clean("/tmp/path/to/action"), "", mock.Anything, mock.Anything). Return(&model.Action{}, nil) cm.On("UpdateFromImageEnv", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { @@ -78,7 +79,19 @@ func TestStepActionLocalTest(t *testing.T) { return nil }) - salm.On("runAction", sal, "/tmp/path/to/action", (*remoteAction)(nil)).Return(func(ctx context.Context) error { + cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/statecmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + salm.On("runAction", sal, filepath.Clean("/tmp/path/to/action"), (*remoteAction)(nil)).Return(func(ctx context.Context) error { return nil }) @@ -275,6 +288,18 @@ func TestStepActionLocalPost(t *testing.T) { }) } cm.On("Exec", suffixMatcher("pkg/runner/local/action/post.js"), sal.env, "", "").Return(func(ctx context.Context) error { return tt.err }) + + cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/statecmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) } err := sal.post()(ctx) diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 1e117ea5..84fe0829 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -172,6 +172,18 @@ func TestStepActionRemote(t *testing.T) { } if tt.mocks.run { sarm.On("runAction", sar, suffixMatcher("act/remote-action@v1"), newRemoteAction(sar.Step.Uses)).Return(func(ctx context.Context) error { return tt.runError }) + + cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/statecmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) } err := sar.pre()(ctx) @@ -582,6 +594,18 @@ func TestStepActionRemotePost(t *testing.T) { } if tt.mocks.exec { cm.On("Exec", []string{"node", "/var/run/act/actions/remote-action@v1/post.js"}, sar.env, "", "").Return(func(ctx context.Context) error { return tt.err }) + + cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/statecmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) } err := sar.post()(ctx) diff --git a/pkg/runner/step_docker_test.go b/pkg/runner/step_docker_test.go index c6794b47..e0e8575f 100644 --- a/pkg/runner/step_docker_test.go +++ b/pkg/runner/step_docker_test.go @@ -86,6 +86,18 @@ func TestStepDockerMain(t *testing.T) { return nil }) + cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/statecmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + err := sd.main()(ctx) assert.Nil(t, err) diff --git a/pkg/runner/step_run_test.go b/pkg/runner/step_run_test.go index 081d8647..e5cde123 100644 --- a/pkg/runner/step_run_test.go +++ b/pkg/runner/step_run_test.go @@ -65,6 +65,18 @@ func TestStepRun(t *testing.T) { return nil }) + cm.On("Copy", "/var/run/act", mock.AnythingOfType("[]*container.FileEntry")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/statecmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + + cm.On("UpdateFromEnv", "/var/run/act/workflow/outputcmd.txt", mock.AnythingOfType("*map[string]string")).Return(func(ctx context.Context) error { + return nil + }) + ctx := context.Background() err := sr.main()(ctx)