From 94fbf748a97579f147a87a56b80a2935e494fb8f Mon Sep 17 00:00:00 2001 From: Jon Jensen Date: Wed, 29 Nov 2023 10:57:45 -0700 Subject: [PATCH] Allow local actions outside the workspace Also simplify actionName logic and ensure it returns sensible values for actions outside the workspace (it's only used for logging and docker image name) --- pkg/runner/action.go | 26 +++++++------------ pkg/runner/action_test.go | 7 +++-- pkg/runner/runner_test.go | 1 + .../local-action-outside-workspace/push.yml | 17 ++++++++++++ 4 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 pkg/runner/testdata/local-action-outside-workspace/push.yml diff --git a/pkg/runner/action.go b/pkg/runner/action.go index 3809359405b..e33c436ff27 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -445,31 +445,23 @@ func getContainerActionPaths(step *model.Step, actionDir string, rc *RunContext) actionName := "" containerActionDir := "." if step.Type() != model.StepTypeUsesActionRemote { - actionName = getOsSafeRelativePath(actionDir, rc.Config.Workdir) - containerActionDir = rc.JobContainer.ToContainerPath(rc.Config.Workdir) + "/" + actionName - actionName = "./" + actionName + actionName = "./" + getOsSafeRelativePath(actionDir, rc.Config.Workdir) + containerActionDir = rc.JobContainer.ToContainerPath(actionDir) } else if step.Type() == model.StepTypeUsesActionRemote { actionName = getOsSafeRelativePath(actionDir, rc.ActionCacheDir()) containerActionDir = rc.JobContainer.GetActPath() + "/actions/" + actionName } - - if actionName == "" { - actionName = filepath.Base(actionDir) - if runtime.GOOS == "windows" { - actionName = strings.ReplaceAll(actionName, "\\", "/") - } - } return actionName, containerActionDir } -func getOsSafeRelativePath(s, prefix string) string { - actionName := strings.TrimPrefix(s, prefix) - if runtime.GOOS == "windows" { - actionName = strings.ReplaceAll(actionName, "\\", "/") +func getOsSafeRelativePath(s, basepath string) string { + if relpath, err := filepath.Rel(basepath, s); err == nil { + if runtime.GOOS == "windows" { + relpath = strings.ReplaceAll(relpath, "\\", "/") + } + return relpath } - actionName = strings.TrimPrefix(actionName, "/") - - return actionName + return filepath.Base(s) } func shouldRunPreStep(step actionStep) common.Conditional { diff --git a/pkg/runner/action_test.go b/pkg/runner/action_test.go index 36ee14f73b6..5f6ba52e542 100644 --- a/pkg/runner/action_test.go +++ b/pkg/runner/action_test.go @@ -2,6 +2,7 @@ package runner import ( "context" + "fmt" "io" "io/fs" "strings" @@ -224,8 +225,10 @@ func TestActionRunner(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() + actionDir := fmt.Sprintf("%s/dir", tt.step.getRunContext().ActionCacheDir()) + cm := &containerMock{} - cm.On("CopyDir", "/var/run/act/actions/dir/", "dir/", false).Return(func(ctx context.Context) error { return nil }) + cm.On("CopyDir", "/var/run/act/actions/dir/", actionDir+"/", false).Return(func(ctx context.Context) error { return nil }) envMatcher := mock.MatchedBy(func(env map[string]string) bool { for k, v := range tt.expectedEnv { @@ -240,7 +243,7 @@ func TestActionRunner(t *testing.T) { tt.step.getRunContext().JobContainer = cm - err := runActionImpl(tt.step, "dir", newRemoteAction("org/repo/path@ref"))(ctx) + err := runActionImpl(tt.step, actionDir, newRemoteAction("org/repo/path@ref"))(ctx) assert.Nil(t, err) cm.AssertExpectations(t) diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 13e6844df01..8ca66dfba17 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -238,6 +238,7 @@ func TestRunEvent(t *testing.T) { {workdir, "local-action-dockerfile", "push", "", platforms, secrets}, {workdir, "local-action-via-composite-dockerfile", "push", "", platforms, secrets}, {workdir, "local-action-js", "push", "", platforms, secrets}, + {workdir, "local-action-outside-workspace", "push", "", platforms, secrets}, // Uses {workdir, "uses-composite", "push", "", platforms, secrets}, diff --git a/pkg/runner/testdata/local-action-outside-workspace/push.yml b/pkg/runner/testdata/local-action-outside-workspace/push.yml new file mode 100644 index 00000000000..d9c0b63a899 --- /dev/null +++ b/pkg/runner/testdata/local-action-outside-workspace/push.yml @@ -0,0 +1,17 @@ +name: local-action-outside-workspace +on: push +jobs: + test: + runs-on: ubuntu-latest + steps: + - run: mkdir ../action-outside-workspace + - run: | + cat <<-ACTIONEOF > ../action-outside-workspace/action.yml + name: test + runs: + using: composite + steps: + - run: echo hello + shell: bash + ACTIONEOF + - uses: ./../action-outside-workspace