From 9b8af8f90ed0be721d550488f5b17f0c6a2f4242 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Tue, 29 Oct 2024 20:52:14 +0000 Subject: [PATCH 01/12] feat: make use of the new action cache * removal of old backend * migrated tests --- cmd/input.go | 1 - cmd/root.go | 38 ++++----- pkg/container/docker_run.go | 3 + pkg/container/host_environment.go | 4 +- pkg/runner/action.go | 22 ++--- pkg/runner/reusable_workflow.go | 15 +--- pkg/runner/run_context.go | 9 ++ pkg/runner/step_action_remote.go | 105 +++++++---------------- pkg/runner/step_action_remote_test.go | 115 ++++++++------------------ 9 files changed, 108 insertions(+), 204 deletions(-) diff --git a/cmd/input.go b/cmd/input.go index 59c14002b2c..0c80ec64772 100644 --- a/cmd/input.go +++ b/cmd/input.go @@ -58,7 +58,6 @@ type Input struct { actionOfflineMode bool logPrefixJobID bool networkName string - useNewActionCache bool localRepository []string } diff --git a/cmd/root.go b/cmd/root.go index bbe6917b836..21b82d19306 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -102,7 +102,6 @@ func Execute(ctx context.Context, version string) { rootCmd.PersistentFlags().StringVarP(&input.actionCachePath, "action-cache-path", "", filepath.Join(CacheHomeDir, "act"), "Defines the path where the actions get cached and host workspaces created.") rootCmd.PersistentFlags().BoolVarP(&input.actionOfflineMode, "action-offline-mode", "", false, "If action contents exists, it will not be fetch and pull again. If turn on this,will turn off force pull") rootCmd.PersistentFlags().StringVarP(&input.networkName, "network", "", "host", "Sets a docker network name. Defaults to host.") - rootCmd.PersistentFlags().BoolVarP(&input.useNewActionCache, "use-new-action-cache", "", false, "Enable using the new Action Cache for storing Actions locally") rootCmd.PersistentFlags().StringArrayVarP(&input.localRepository, "local-repository", "", []string{}, "Replaces the specified repository and ref with a local folder (e.g. https://github.com/test/test@v0=/home/act/test or test/test@v0=/home/act/test, the latter matches any hosts or protocols)") rootCmd.SetArgs(args()) @@ -588,31 +587,26 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str Matrix: matrixes, ContainerNetworkMode: docker_container.NetworkMode(input.networkName), } - if input.useNewActionCache || len(input.localRepository) > 0 { - if input.actionOfflineMode { - config.ActionCache = &runner.GoGitActionCacheOfflineMode{ - Parent: runner.GoGitActionCache{ - Path: config.ActionCacheDir, - }, - } - } else { - config.ActionCache = &runner.GoGitActionCache{ + if input.actionOfflineMode { + config.ActionCache = &runner.GoGitActionCacheOfflineMode{ + Parent: runner.GoGitActionCache{ Path: config.ActionCacheDir, - } + }, } - if len(input.localRepository) > 0 { - localRepositories := map[string]string{} - for _, l := range input.localRepository { - k, v, _ := strings.Cut(l, "=") - localRepositories[k] = v - } - config.ActionCache = &runner.LocalRepositoryCache{ - Parent: config.ActionCache, - LocalRepositories: localRepositories, - CacheDirCache: map[string]string{}, - } + } + if len(input.localRepository) > 0 { + localRepositories := map[string]string{} + for _, l := range input.localRepository { + k, v, _ := strings.Cut(l, "=") + localRepositories[k] = v + } + config.ActionCache = &runner.LocalRepositoryCache{ + Parent: config.ActionCache, + LocalRepositories: localRepositories, + CacheDirCache: map[string]string{}, } } + r, err := runner.New(config) if err != nil { return err diff --git a/pkg/container/docker_run.go b/pkg/container/docker_run.go index 61b2bfac34a..2b8a59b500d 100644 --- a/pkg/container/docker_run.go +++ b/pkg/container/docker_run.go @@ -699,6 +699,9 @@ func (cr *containerReference) waitForCommand(ctx context.Context, isTerminal boo } func (cr *containerReference) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error { + if common.Dryrun(ctx) { + return nil + } // Mkdir buf := &bytes.Buffer{} tw := tar.NewWriter(buf) diff --git a/pkg/container/host_environment.go b/pkg/container/host_environment.go index 0103ebdb2f0..d4a9869d070 100644 --- a/pkg/container/host_environment.go +++ b/pkg/container/host_environment.go @@ -435,9 +435,9 @@ func goArchToActionArch(arch string) string { func goOsToActionOs(os string) string { osMapper := map[string]string{ - "linux": "Linux", + "linux": "Linux", "windows": "Windows", - "darwin": "macOS", + "darwin": "macOS", } if os, ok := osMapper[os]; ok { return os diff --git a/pkg/runner/action.go b/pkg/runner/action.go index a19e58f1eb2..0db3c4e134c 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -133,21 +133,13 @@ func maybeCopyToActionDir(ctx context.Context, step actionStep, actionDir string containerActionDirCopy += `/` } - if rc.Config != nil && rc.Config.ActionCache != nil { - raction := step.(*stepActionRemote) - ta, err := rc.Config.ActionCache.GetTarArchive(ctx, raction.cacheDir, raction.resolvedSha, "") - if err != nil { - return err - } - defer ta.Close() - return rc.JobContainer.CopyTarStream(ctx, containerActionDirCopy, ta) - } - - if err := removeGitIgnore(ctx, actionDir); err != nil { + raction := step.(*stepActionRemote) + ta, err := rc.getActionCache().GetTarArchive(ctx, raction.cacheDir, raction.resolvedSha, "") + if err != nil { return err } - - return rc.JobContainer.CopyDir(containerActionDirCopy, actionDir+"/", rc.Config.UseGitIgnore)(ctx) + defer ta.Close() + return rc.JobContainer.CopyTarStream(ctx, containerActionDirCopy, ta) } func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction) common.Executor { @@ -291,9 +283,9 @@ func execAsDocker(ctx context.Context, step actionStep, actionName string, based return err } defer buildContext.Close() - } else if rc.Config.ActionCache != nil { + } else { rstep := step.(*stepActionRemote) - buildContext, err = rc.Config.ActionCache.GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, contextDir) + buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, contextDir) if err != nil { return err } diff --git a/pkg/runner/reusable_workflow.go b/pkg/runner/reusable_workflow.go index 7ce68e9289e..8aa73f4f0f7 100644 --- a/pkg/runner/reusable_workflow.go +++ b/pkg/runner/reusable_workflow.go @@ -32,27 +32,20 @@ func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor { // instead we will just use {owner}-{repo}@{ref} as our target directory. This should also improve performance when we are using // multiple reusable workflows from the same repository and ref since for each workflow we won't have to clone it again filename := fmt.Sprintf("%s/%s@%s", remoteReusableWorkflow.Org, remoteReusableWorkflow.Repo, remoteReusableWorkflow.Ref) - workflowDir := fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(filename)) - if rc.Config.ActionCache != nil { - return newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow) - } - - return common.NewPipelineExecutor( - newMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir)), - newReusableWorkflowExecutor(rc, workflowDir, fmt.Sprintf("./.github/workflows/%s", remoteReusableWorkflow.Filename)), - ) + return newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow) } func newActionCacheReusableWorkflowExecutor(rc *RunContext, filename string, remoteReusableWorkflow *remoteReusableWorkflow) common.Executor { return func(ctx context.Context) error { ghctx := rc.getGithubContext(ctx) remoteReusableWorkflow.URL = ghctx.ServerURL - sha, err := rc.Config.ActionCache.Fetch(ctx, filename, remoteReusableWorkflow.CloneURL(), remoteReusableWorkflow.Ref, ghctx.Token) + cache := rc.getActionCache() + sha, err := cache.Fetch(ctx, filename, remoteReusableWorkflow.CloneURL(), remoteReusableWorkflow.Ref, ghctx.Token) if err != nil { return err } - archive, err := rc.Config.ActionCache.GetTarArchive(ctx, filename, sha, fmt.Sprintf(".github/workflows/%s", remoteReusableWorkflow.Filename)) + archive, err := cache.GetTarArchive(ctx, filename, sha, fmt.Sprintf(".github/workflows/%s", remoteReusableWorkflow.Filename)) if err != nil { return err } diff --git a/pkg/runner/run_context.go b/pkg/runner/run_context.go index b8f338eef96..9cd899d2005 100644 --- a/pkg/runner/run_context.go +++ b/pkg/runner/run_context.go @@ -628,6 +628,15 @@ func (rc *RunContext) ActionCacheDir() string { return filepath.Join(xdgCache, "act") } +func (rc *RunContext) getActionCache() ActionCache { + if rc.Config.ActionCache == nil { + rc.Config.ActionCache = &GoGitActionCache{ + Path: rc.ActionCacheDir(), + } + } + return rc.Config.ActionCache +} + // Interpolate outputs after a job is done func (rc *RunContext) interpolateOutputs() common.Executor { return func(ctx context.Context) error { diff --git a/pkg/runner/step_action_remote.go b/pkg/runner/step_action_remote.go index b34c6d9c140..ff673b49a90 100644 --- a/pkg/runner/step_action_remote.go +++ b/pkg/runner/step_action_remote.go @@ -3,7 +3,6 @@ package runner import ( "archive/tar" "context" - "errors" "fmt" "io" "os" @@ -12,8 +11,6 @@ import ( "regexp" "strings" - gogit "github.com/go-git/go-git/v5" - "github.com/nektos/act/pkg/common" "github.com/nektos/act/pkg/common/git" "github.com/nektos/act/pkg/model" @@ -63,84 +60,46 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor { github.Token = sar.RunContext.Config.ReplaceGheActionTokenWithGithubCom } } - if sar.RunContext.Config.ActionCache != nil { - cache := sar.RunContext.Config.ActionCache - - var err error - sar.cacheDir = fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo) - repoURL := sar.remoteAction.URL + "/" + sar.cacheDir - repoRef := sar.remoteAction.Ref - sar.resolvedSha, err = cache.Fetch(ctx, sar.cacheDir, repoURL, repoRef, github.Token) - if err != nil { - return fmt.Errorf("failed to fetch \"%s\" version \"%s\": %w", repoURL, repoRef, err) - } + cache := sar.RunContext.getActionCache() + + var err error + sar.cacheDir = fmt.Sprintf("%s/%s", sar.remoteAction.Org, sar.remoteAction.Repo) + repoURL := sar.remoteAction.URL + "/" + sar.cacheDir + repoRef := sar.remoteAction.Ref + sar.resolvedSha, err = cache.Fetch(ctx, sar.cacheDir, repoURL, repoRef, github.Token) + if err != nil { + return fmt.Errorf("failed to fetch \"%s\" version \"%s\": %w", repoURL, repoRef, err) + } - remoteReader := func(ctx context.Context) actionYamlReader { - return func(filename string) (io.Reader, io.Closer, error) { - spath := path.Join(sar.remoteAction.Path, filename) - for i := 0; i < maxSymlinkDepth; i++ { - tars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath) - if err != nil { - return nil, nil, os.ErrNotExist - } - treader := tar.NewReader(tars) - header, err := treader.Next() + remoteReader := func(ctx context.Context) actionYamlReader { + return func(filename string) (io.Reader, io.Closer, error) { + spath := path.Join(sar.remoteAction.Path, filename) + for i := 0; i < maxSymlinkDepth; i++ { + tars, err := cache.GetTarArchive(ctx, sar.cacheDir, sar.resolvedSha, spath) + if err != nil { + return nil, nil, os.ErrNotExist + } + treader := tar.NewReader(tars) + header, err := treader.Next() + if err != nil { + return nil, nil, os.ErrNotExist + } + if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink { + spath, err = symlinkJoin(spath, header.Linkname, ".") if err != nil { - return nil, nil, os.ErrNotExist - } - if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink { - spath, err = symlinkJoin(spath, header.Linkname, ".") - if err != nil { - return nil, nil, err - } - } else { - return treader, tars, nil + return nil, nil, err } + } else { + return treader, tars, nil } - return nil, nil, fmt.Errorf("max depth %d of symlinks exceeded while reading %s", maxSymlinkDepth, spath) } - } - - actionModel, err := sar.readAction(ctx, sar.Step, sar.resolvedSha, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile) - sar.action = actionModel - return err - } - - actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses)) - gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{ - URL: sar.remoteAction.CloneURL(), - Ref: sar.remoteAction.Ref, - Dir: actionDir, - Token: github.Token, - OfflineMode: sar.RunContext.Config.ActionOfflineMode, - }) - var ntErr common.Executor - if err := gitClone(ctx); err != nil { - if errors.Is(err, git.ErrShortRef) { - return fmt.Errorf("Unable to resolve action `%s`, the provided ref `%s` is the shortened version of a commit SHA, which is not supported. Please use the full commit SHA `%s` instead", - sar.Step.Uses, sar.remoteAction.Ref, err.(*git.Error).Commit()) - } else if errors.Is(err, gogit.ErrForceNeeded) { // TODO: figure out if it will be easy to shadow/alias go-git err's - ntErr = common.NewInfoExecutor("Non-terminating error while running 'git clone': %v", err) - } else { - return err - } - } - - remoteReader := func(ctx context.Context) actionYamlReader { - return func(filename string) (io.Reader, io.Closer, error) { - f, err := os.Open(filepath.Join(actionDir, sar.remoteAction.Path, filename)) - return f, f, err + return nil, nil, fmt.Errorf("max depth %d of symlinks exceeded while reading %s", maxSymlinkDepth, spath) } } - return common.NewPipelineExecutor( - ntErr, - func(ctx context.Context) error { - actionModel, err := sar.readAction(ctx, sar.Step, actionDir, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile) - sar.action = actionModel - return err - }, - )(ctx) + actionModel, err := sar.readAction(ctx, sar.Step, sar.resolvedSha, sar.remoteAction.Path, remoteReader(ctx), os.WriteFile) + sar.action = actionModel + return err } } diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 253ad40ec53..0e3619bc40c 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -13,7 +13,6 @@ import ( "gopkg.in/yaml.v3" "github.com/nektos/act/pkg/common" - "github.com/nektos/act/pkg/common/git" "github.com/nektos/act/pkg/model" ) @@ -31,6 +30,20 @@ func (sarm *stepActionRemoteMocks) runAction(step actionStep, actionDir string, return args.Get(0).(func(context.Context) error) } +type TestRepositoryCache struct { + mock.Mock +} + +func (l *TestRepositoryCache) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) { + args := l.Called(ctx, cacheDir, url, ref, token) + return args.Get(0).(string), nil +} + +func (l *TestRepositoryCache) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) { + args := l.Called(ctx, cacheDir, sha, includePrefix) + return args.Get(0).(io.ReadCloser), nil +} + func TestStepActionRemote(t *testing.T) { table := []struct { name string @@ -124,23 +137,13 @@ func TestStepActionRemote(t *testing.T) { cm := &containerMock{} sarm := &stepActionRemoteMocks{} - clonedAction := false - - origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor - stepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor { - return func(ctx context.Context) error { - clonedAction = true - return nil - } - } - defer (func() { - stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor - })() + cacheMock := &TestRepositoryCache{} sar := &stepActionRemote{ RunContext: &RunContext{ Config: &Config{ GitHubInstance: "github.com", + ActionCache: cacheMock, }, Run: &model.Run{ JobID: "1", @@ -159,6 +162,7 @@ func TestStepActionRemote(t *testing.T) { } sar.RunContext.ExprEval = sar.RunContext.NewExpressionEvaluator(ctx) + cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/remote/action", "v1", "").Return("someval") suffixMatcher := func(suffix string) interface{} { return mock.MatchedBy(func(actionDir string) bool { return strings.HasSuffix(actionDir, suffix) @@ -166,7 +170,7 @@ func TestStepActionRemote(t *testing.T) { } if tt.mocks.read { - sarm.On("readAction", sar.Step, suffixMatcher("act/remote-action@v1"), "", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.On("readAction", sar.Step, "someval", "", mock.Anything, mock.Anything).Return(&model.Action{}, nil) } 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 }) @@ -196,11 +200,11 @@ func TestStepActionRemote(t *testing.T) { } assert.Equal(t, tt.runError, err) - assert.Equal(t, tt.mocks.cloned, clonedAction) assert.Equal(t, tt.result, sar.RunContext.StepResults["step"]) sarm.AssertExpectations(t) cm.AssertExpectations(t) + cacheMock.AssertExpectations(t) }) } } @@ -222,25 +226,15 @@ func TestStepActionRemotePre(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - clonedAction := false + cacheMock := &TestRepositoryCache{} sarm := &stepActionRemoteMocks{} - origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor - stepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor { - return func(ctx context.Context) error { - clonedAction = true - return nil - } - } - defer (func() { - stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor - })() - sar := &stepActionRemote{ Step: tt.stepModel, RunContext: &RunContext{ Config: &Config{ - GitHubInstance: "https://github.com", + GitHubInstance: "github.com", + ActionCache: cacheMock, }, Run: &model.Run{ JobID: "1", @@ -254,20 +248,15 @@ func TestStepActionRemotePre(t *testing.T) { readAction: sarm.readAction, } - suffixMatcher := func(suffix string) interface{} { - return mock.MatchedBy(func(actionDir string) bool { - return strings.HasSuffix(actionDir, suffix) - }) - } - - sarm.On("readAction", sar.Step, suffixMatcher("org-repo-path@ref"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.On("readAction", sar.Step, "someval", "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") err := sar.pre()(ctx) assert.Nil(t, err) - assert.Equal(t, true, clonedAction) sarm.AssertExpectations(t) + cacheMock.AssertExpectations(t) }) } } @@ -289,28 +278,16 @@ func TestStepActionRemotePreThroughAction(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - clonedAction := false + cacheMock := &TestRepositoryCache{} sarm := &stepActionRemoteMocks{} - origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor - stepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor { - return func(ctx context.Context) error { - if input.URL == "https://github.com/org/repo" { - clonedAction = true - } - return nil - } - } - defer (func() { - stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor - })() - sar := &stepActionRemote{ Step: tt.stepModel, RunContext: &RunContext{ Config: &Config{ GitHubInstance: "https://enterprise.github.com", ReplaceGheActionWithGithubCom: []string{"org/repo"}, + ActionCache: cacheMock, }, Run: &model.Run{ JobID: "1", @@ -324,20 +301,15 @@ func TestStepActionRemotePreThroughAction(t *testing.T) { readAction: sarm.readAction, } - suffixMatcher := func(suffix string) interface{} { - return mock.MatchedBy(func(actionDir string) bool { - return strings.HasSuffix(actionDir, suffix) - }) - } - - sarm.On("readAction", sar.Step, suffixMatcher("org-repo-path@ref"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") err := sar.pre()(ctx) assert.Nil(t, err) - assert.Equal(t, true, clonedAction) sarm.AssertExpectations(t) + cacheMock.AssertExpectations(t) }) } } @@ -359,22 +331,9 @@ func TestStepActionRemotePreThroughActionToken(t *testing.T) { t.Run(tt.name, func(t *testing.T) { ctx := context.Background() - clonedAction := false sarm := &stepActionRemoteMocks{} - origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor - stepActionRemoteNewCloneExecutor = func(input git.NewGitCloneExecutorInput) common.Executor { - return func(ctx context.Context) error { - if input.URL == "https://github.com/org/repo" && input.Token == "PRIVATE_ACTIONS_TOKEN_ON_GITHUB" { - clonedAction = true - } - return nil - } - } - defer (func() { - stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor - })() - + cacheMock := &TestRepositoryCache{} sar := &stepActionRemote{ Step: tt.stepModel, RunContext: &RunContext{ @@ -382,6 +341,7 @@ func TestStepActionRemotePreThroughActionToken(t *testing.T) { GitHubInstance: "https://enterprise.github.com", ReplaceGheActionWithGithubCom: []string{"org/repo"}, ReplaceGheActionTokenWithGithubCom: "PRIVATE_ACTIONS_TOKEN_ON_GITHUB", + ActionCache: cacheMock, }, Run: &model.Run{ JobID: "1", @@ -395,20 +355,15 @@ func TestStepActionRemotePreThroughActionToken(t *testing.T) { readAction: sarm.readAction, } - suffixMatcher := func(suffix string) interface{} { - return mock.MatchedBy(func(actionDir string) bool { - return strings.HasSuffix(actionDir, suffix) - }) - } - - sarm.On("readAction", sar.Step, suffixMatcher("org-repo-path@ref"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "PRIVATE_ACTIONS_TOKEN_ON_GITHUB").Return("someval") err := sar.pre()(ctx) assert.Nil(t, err) - assert.Equal(t, true, clonedAction) sarm.AssertExpectations(t) + cacheMock.AssertExpectations(t) }) } } From b989239d3256685676c389d3506b943e4d35c23f Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Tue, 29 Oct 2024 21:04:04 +0000 Subject: [PATCH 02/12] linter again --- pkg/runner/step_action_remote_test.go | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 0e3619bc40c..262c1e88126 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -35,12 +35,12 @@ type TestRepositoryCache struct { } func (l *TestRepositoryCache) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) { - args := l.Called(ctx, cacheDir, url, ref, token) + args := l.Mock.Called(ctx, cacheDir, url, ref, token) return args.Get(0).(string), nil } func (l *TestRepositoryCache) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) { - args := l.Called(ctx, cacheDir, sha, includePrefix) + args := l.Mock.Called(ctx, cacheDir, sha, includePrefix) return args.Get(0).(io.ReadCloser), nil } @@ -162,7 +162,7 @@ func TestStepActionRemote(t *testing.T) { } sar.RunContext.ExprEval = sar.RunContext.NewExpressionEvaluator(ctx) - cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/remote/action", "v1", "").Return("someval") + cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/remote/action", "v1", "").Return("someval") suffixMatcher := func(suffix string) interface{} { return mock.MatchedBy(func(actionDir string) bool { return strings.HasSuffix(actionDir, suffix) @@ -204,7 +204,7 @@ func TestStepActionRemote(t *testing.T) { sarm.AssertExpectations(t) cm.AssertExpectations(t) - cacheMock.AssertExpectations(t) + cacheMock.Mock.AssertExpectations(t) }) } } @@ -249,14 +249,14 @@ func TestStepActionRemotePre(t *testing.T) { } sarm.On("readAction", sar.Step, "someval", "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) - cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") + cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") err := sar.pre()(ctx) assert.Nil(t, err) sarm.AssertExpectations(t) - cacheMock.AssertExpectations(t) + cacheMock.Mock.AssertExpectations(t) }) } } @@ -302,14 +302,14 @@ func TestStepActionRemotePreThroughAction(t *testing.T) { } sarm.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) - cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") + cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") err := sar.pre()(ctx) assert.Nil(t, err) sarm.AssertExpectations(t) - cacheMock.AssertExpectations(t) + cacheMock.Mock.AssertExpectations(t) }) } } @@ -356,14 +356,14 @@ func TestStepActionRemotePreThroughActionToken(t *testing.T) { } sarm.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) - cacheMock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "PRIVATE_ACTIONS_TOKEN_ON_GITHUB").Return("someval") + cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "PRIVATE_ACTIONS_TOKEN_ON_GITHUB").Return("someval") err := sar.pre()(ctx) assert.Nil(t, err) sarm.AssertExpectations(t) - cacheMock.AssertExpectations(t) + cacheMock.Mock.AssertExpectations(t) }) } } From 35918ddaaa8300e8ab90d93e4dc075af29489b9e Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Tue, 29 Oct 2024 21:50:52 +0000 Subject: [PATCH 03/12] fix bug --- pkg/runner/action.go | 24 ++--- pkg/runner/action_test.go | 4 + pkg/runner/runner_test.go | 190 +++++++++++++++++++------------------- 3 files changed, 111 insertions(+), 107 deletions(-) diff --git a/pkg/runner/action.go b/pkg/runner/action.go index 0db3c4e134c..8aa8a52d4bb 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -178,11 +178,11 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx) case model.ActionRunsUsingDocker: - location := actionLocation if remoteAction == nil { - location = containerActionDir + actionDir = "" + actionPath = containerActionDir } - return execAsDocker(ctx, step, actionName, location, remoteAction == nil, "entrypoint") + return execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, "entrypoint") case model.ActionRunsUsingComposite: if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil { return err @@ -235,7 +235,7 @@ func removeGitIgnore(ctx context.Context, directory string) error { // TODO: break out parts of function to reduce complexicity // //nolint:gocyclo -func execAsDocker(ctx context.Context, step actionStep, actionName string, basedir string, localAction bool, entrypointType string) error { +func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, subpath string, localAction bool, entrypointType string) error { logger := common.Logger(ctx) rc := step.getRunContext() action := step.getActionModel() @@ -252,7 +252,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName string, based image = fmt.Sprintf("%s-dockeraction:%s", regexp.MustCompile("[^a-zA-Z0-9]").ReplaceAllString(actionName, "-"), "latest") image = fmt.Sprintf("act-%s", strings.TrimLeft(image, "-")) image = strings.ToLower(image) - contextDir, fileName := filepath.Split(filepath.Join(basedir, action.Runs.Image)) + contextDir, fileName := filepath.Split(filepath.Join(basedir, subpath, action.Runs.Image)) anyArchExists, err := container.ImageExistsLocally(ctx, image, "any") if err != nil { @@ -285,7 +285,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName string, based defer buildContext.Close() } else { rstep := step.(*stepActionRemote) - buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, contextDir) + buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, path.Join(subpath, action.Runs.Image)) if err != nil { return err } @@ -549,11 +549,11 @@ func runPreStep(step actionStep) common.Executor { return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx) case model.ActionRunsUsingDocker: - location := actionLocation if remoteAction == nil { - location = containerActionDir + actionDir = "" + actionPath = containerActionDir } - return execAsDocker(ctx, step, actionName, location, remoteAction == nil, "pre-entrypoint") + return execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, "pre-entrypoint") case model.ActionRunsUsingComposite: if step.getCompositeSteps() == nil { @@ -654,11 +654,11 @@ func runPostStep(step actionStep) common.Executor { return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx) case model.ActionRunsUsingDocker: - location := actionLocation if remoteAction == nil { - location = containerActionDir + actionDir = "" + actionPath = containerActionDir } - return execAsDocker(ctx, step, actionName, location, remoteAction == nil, "post-entrypoint") + return execAsDocker(ctx, step, actionName, actionDir, actionPath, remoteAction == nil, "post-entrypoint") case model.ActionRunsUsingComposite: if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil { diff --git a/pkg/runner/action_test.go b/pkg/runner/action_test.go index 52658432e98..2e2003f37a0 100644 --- a/pkg/runner/action_test.go +++ b/pkg/runner/action_test.go @@ -229,6 +229,9 @@ func TestActionRunner(t *testing.T) { cm := &containerMock{} cm.On("CopyDir", "/var/run/act/actions/dir/", "dir/", false).Return(func(ctx context.Context) error { return nil }) + cacheMock := &TestRepositoryCache{} + cacheMock.On("GetTarArchive", ctx, "", "", "").Return(io.MultiReader()) + envMatcher := mock.MatchedBy(func(env map[string]string) bool { for k, v := range tt.expectedEnv { if env[k] != v { @@ -241,6 +244,7 @@ func TestActionRunner(t *testing.T) { cm.On("Exec", []string{"node", "/var/run/act/actions/dir/path"}, envMatcher, "", "").Return(func(ctx context.Context) error { return nil }) tt.step.getRunContext().JobContainer = cm + tt.step.getRunContext().Config.ActionCache = cacheMock err := runActionImpl(tt.step, "dir", newRemoteAction("org/repo/path@ref"))(ctx) diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index 82defd77661..df997c0c064 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -227,102 +227,102 @@ func TestRunEvent(t *testing.T) { tables := []TestJobFileInfo{ // Shells - {workdir, "shells/defaults", "push", "", platforms, secrets}, - // TODO: figure out why it fails - // {workdir, "shells/custom", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, }, // custom image with pwsh - {workdir, "shells/pwsh", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, secrets}, // custom image with pwsh - {workdir, "shells/bash", "push", "", platforms, secrets}, - {workdir, "shells/python", "push", "", map[string]string{"ubuntu-latest": "node:16-buster"}, secrets}, // slim doesn't have python - {workdir, "shells/sh", "push", "", platforms, secrets}, - - // Local action - {workdir, "local-action-docker-url", "push", "", platforms, secrets}, - {workdir, "local-action-dockerfile", "push", "", platforms, secrets}, - {workdir, "local-action-via-composite-dockerfile", "push", "", platforms, secrets}, - {workdir, "local-action-js", "push", "", platforms, secrets}, - - // Uses - {workdir, "uses-composite", "push", "", platforms, secrets}, - {workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets}, - {workdir, "uses-composite-check-for-input-collision", "push", "", platforms, secrets}, - {workdir, "uses-composite-check-for-input-shadowing", "push", "", platforms, secrets}, - {workdir, "uses-nested-composite", "push", "", platforms, secrets}, - {workdir, "remote-action-composite-js-pre-with-defaults", "push", "", platforms, secrets}, - {workdir, "remote-action-composite-action-ref", "push", "", platforms, secrets}, - {workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}}, - {workdir, "uses-workflow", "pull_request", "", platforms, map[string]string{"secret": "keep_it_private"}}, - {workdir, "uses-docker-url", "push", "", platforms, secrets}, - {workdir, "act-composite-env-test", "push", "", platforms, secrets}, - - // Eval - {workdir, "evalmatrix", "push", "", platforms, secrets}, - {workdir, "evalmatrixneeds", "push", "", platforms, secrets}, - {workdir, "evalmatrixneeds2", "push", "", platforms, secrets}, - {workdir, "evalmatrix-merge-map", "push", "", platforms, secrets}, - {workdir, "evalmatrix-merge-array", "push", "", platforms, secrets}, - {workdir, "issue-1195", "push", "", platforms, secrets}, - - {workdir, "basic", "push", "", platforms, secrets}, - {workdir, "fail", "push", "exit with `FAILURE`: 1", platforms, secrets}, - {workdir, "runs-on", "push", "", platforms, secrets}, - {workdir, "checkout", "push", "", platforms, secrets}, - {workdir, "job-container", "push", "", platforms, secrets}, - {workdir, "job-container-non-root", "push", "", platforms, secrets}, - {workdir, "job-container-invalid-credentials", "push", "failed to handle credentials: failed to interpolate container.credentials.password", platforms, secrets}, - {workdir, "container-hostname", "push", "", platforms, secrets}, - {workdir, "remote-action-docker", "push", "", platforms, secrets}, - {workdir, "remote-action-js", "push", "", platforms, secrets}, - {workdir, "remote-action-js-node-user", "push", "", platforms, secrets}, // Test if this works with non root container - {workdir, "matrix", "push", "", platforms, secrets}, - {workdir, "matrix-include-exclude", "push", "", platforms, secrets}, - {workdir, "matrix-exitcode", "push", "Job 'test' failed", platforms, secrets}, - {workdir, "commands", "push", "", platforms, secrets}, - {workdir, "workdir", "push", "", platforms, secrets}, - {workdir, "defaults-run", "push", "", platforms, secrets}, - {workdir, "composite-fail-with-output", "push", "", platforms, secrets}, - {workdir, "issue-597", "push", "", platforms, secrets}, - {workdir, "issue-598", "push", "", platforms, secrets}, - {workdir, "if-env-act", "push", "", platforms, secrets}, - {workdir, "env-and-path", "push", "", platforms, secrets}, - {workdir, "environment-files", "push", "", platforms, secrets}, - {workdir, "GITHUB_STATE", "push", "", platforms, secrets}, - {workdir, "environment-files-parser-bug", "push", "", platforms, secrets}, - {workdir, "non-existent-action", "push", "Job 'nopanic' failed", platforms, secrets}, - {workdir, "outputs", "push", "", platforms, secrets}, - {workdir, "networking", "push", "", platforms, secrets}, - {workdir, "steps-context/conclusion", "push", "", platforms, secrets}, - {workdir, "steps-context/outcome", "push", "", platforms, secrets}, - {workdir, "job-status-check", "push", "job 'fail' failed", platforms, secrets}, - {workdir, "if-expressions", "push", "Job 'mytest' failed", platforms, secrets}, + // {workdir, "shells/defaults", "push", "", platforms, secrets}, + // // TODO: figure out why it fails + // // {workdir, "shells/custom", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, }, // custom image with pwsh + // {workdir, "shells/pwsh", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, secrets}, // custom image with pwsh + // {workdir, "shells/bash", "push", "", platforms, secrets}, + // {workdir, "shells/python", "push", "", map[string]string{"ubuntu-latest": "node:16-buster"}, secrets}, // slim doesn't have python + // {workdir, "shells/sh", "push", "", platforms, secrets}, + + // // Local action + // {workdir, "local-action-docker-url", "push", "", platforms, secrets}, + // {workdir, "local-action-dockerfile", "push", "", platforms, secrets}, + // {workdir, "local-action-via-composite-dockerfile", "push", "", platforms, secrets}, + // {workdir, "local-action-js", "push", "", platforms, secrets}, + + // // Uses + // {workdir, "uses-composite", "push", "", platforms, secrets}, + // {workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets}, + // {workdir, "uses-composite-check-for-input-collision", "push", "", platforms, secrets}, + // {workdir, "uses-composite-check-for-input-shadowing", "push", "", platforms, secrets}, + // {workdir, "uses-nested-composite", "push", "", platforms, secrets}, + // {workdir, "remote-action-composite-js-pre-with-defaults", "push", "", platforms, secrets}, + // {workdir, "remote-action-composite-action-ref", "push", "", platforms, secrets}, + // {workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}}, + // {workdir, "uses-workflow", "pull_request", "", platforms, map[string]string{"secret": "keep_it_private"}}, + // {workdir, "uses-docker-url", "push", "", platforms, secrets}, + // {workdir, "act-composite-env-test", "push", "", platforms, secrets}, + + // // Eval + // {workdir, "evalmatrix", "push", "", platforms, secrets}, + // {workdir, "evalmatrixneeds", "push", "", platforms, secrets}, + // {workdir, "evalmatrixneeds2", "push", "", platforms, secrets}, + // {workdir, "evalmatrix-merge-map", "push", "", platforms, secrets}, + // {workdir, "evalmatrix-merge-array", "push", "", platforms, secrets}, + // {workdir, "issue-1195", "push", "", platforms, secrets}, + + // {workdir, "basic", "push", "", platforms, secrets}, + // {workdir, "fail", "push", "exit with `FAILURE`: 1", platforms, secrets}, + // {workdir, "runs-on", "push", "", platforms, secrets}, + // {workdir, "checkout", "push", "", platforms, secrets}, + // {workdir, "job-container", "push", "", platforms, secrets}, + // {workdir, "job-container-non-root", "push", "", platforms, secrets}, + // {workdir, "job-container-invalid-credentials", "push", "failed to handle credentials: failed to interpolate container.credentials.password", platforms, secrets}, + // {workdir, "container-hostname", "push", "", platforms, secrets}, + // {workdir, "remote-action-docker", "push", "", platforms, secrets}, + // {workdir, "remote-action-js", "push", "", platforms, secrets}, + // {workdir, "remote-action-js-node-user", "push", "", platforms, secrets}, // Test if this works with non root container + // {workdir, "matrix", "push", "", platforms, secrets}, + // {workdir, "matrix-include-exclude", "push", "", platforms, secrets}, + // {workdir, "matrix-exitcode", "push", "Job 'test' failed", platforms, secrets}, + // {workdir, "commands", "push", "", platforms, secrets}, + // {workdir, "workdir", "push", "", platforms, secrets}, + // {workdir, "defaults-run", "push", "", platforms, secrets}, + // {workdir, "composite-fail-with-output", "push", "", platforms, secrets}, + // {workdir, "issue-597", "push", "", platforms, secrets}, + // {workdir, "issue-598", "push", "", platforms, secrets}, + // {workdir, "if-env-act", "push", "", platforms, secrets}, + // {workdir, "env-and-path", "push", "", platforms, secrets}, + // {workdir, "environment-files", "push", "", platforms, secrets}, + // {workdir, "GITHUB_STATE", "push", "", platforms, secrets}, + // {workdir, "environment-files-parser-bug", "push", "", platforms, secrets}, + // {workdir, "non-existent-action", "push", "Job 'nopanic' failed", platforms, secrets}, + // {workdir, "outputs", "push", "", platforms, secrets}, + // {workdir, "networking", "push", "", platforms, secrets}, + // {workdir, "steps-context/conclusion", "push", "", platforms, secrets}, + // {workdir, "steps-context/outcome", "push", "", platforms, secrets}, + // {workdir, "job-status-check", "push", "job 'fail' failed", platforms, secrets}, + // {workdir, "if-expressions", "push", "Job 'mytest' failed", platforms, secrets}, {workdir, "actions-environment-and-context-tests", "push", "", platforms, secrets}, - {workdir, "uses-action-with-pre-and-post-step", "push", "", platforms, secrets}, - {workdir, "evalenv", "push", "", platforms, secrets}, - {workdir, "docker-action-custom-path", "push", "", platforms, secrets}, - {workdir, "GITHUB_ENV-use-in-env-ctx", "push", "", platforms, secrets}, - {workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms, secrets}, - {workdir, "workflow_call_inputs", "workflow_call", "", platforms, secrets}, - {workdir, "workflow_dispatch", "workflow_dispatch", "", platforms, secrets}, - {workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets}, - {workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets}, - {workdir, "workflow_dispatch-scalar-composite-action", "workflow_dispatch", "", platforms, secrets}, - {workdir, "job-needs-context-contains-result", "push", "", platforms, secrets}, - {"../model/testdata", "strategy", "push", "", platforms, secrets}, // TODO: move all testdata into pkg so we can validate it with planner and runner - {"../model/testdata", "container-volumes", "push", "", platforms, secrets}, - {workdir, "path-handling", "push", "", platforms, secrets}, - {workdir, "do-not-leak-step-env-in-composite", "push", "", platforms, secrets}, - {workdir, "set-env-step-env-override", "push", "", platforms, secrets}, - {workdir, "set-env-new-env-file-per-step", "push", "", platforms, secrets}, - {workdir, "no-panic-on-invalid-composite-action", "push", "jobs failed due to invalid action", platforms, secrets}, - - // services - {workdir, "services", "push", "", platforms, secrets}, - {workdir, "services-empty-image", "push", "", platforms, secrets}, - {workdir, "services-host-network", "push", "", platforms, secrets}, - {workdir, "services-with-container", "push", "", platforms, secrets}, - {workdir, "mysql-service-container-with-health-check", "push", "", platforms, secrets}, - - // local remote action overrides - {workdir, "local-remote-action-overrides", "push", "", platforms, secrets}, + // {workdir, "uses-action-with-pre-and-post-step", "push", "", platforms, secrets}, + // {workdir, "evalenv", "push", "", platforms, secrets}, + // {workdir, "docker-action-custom-path", "push", "", platforms, secrets}, + // {workdir, "GITHUB_ENV-use-in-env-ctx", "push", "", platforms, secrets}, + // {workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms, secrets}, + // {workdir, "workflow_call_inputs", "workflow_call", "", platforms, secrets}, + // {workdir, "workflow_dispatch", "workflow_dispatch", "", platforms, secrets}, + // {workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets}, + // {workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets}, + // {workdir, "workflow_dispatch-scalar-composite-action", "workflow_dispatch", "", platforms, secrets}, + // {workdir, "job-needs-context-contains-result", "push", "", platforms, secrets}, + // {"../model/testdata", "strategy", "push", "", platforms, secrets}, // TODO: move all testdata into pkg so we can validate it with planner and runner + // {"../model/testdata", "container-volumes", "push", "", platforms, secrets}, + // {workdir, "path-handling", "push", "", platforms, secrets}, + // {workdir, "do-not-leak-step-env-in-composite", "push", "", platforms, secrets}, + // {workdir, "set-env-step-env-override", "push", "", platforms, secrets}, + // {workdir, "set-env-new-env-file-per-step", "push", "", platforms, secrets}, + // {workdir, "no-panic-on-invalid-composite-action", "push", "jobs failed due to invalid action", platforms, secrets}, + + // // services + // {workdir, "services", "push", "", platforms, secrets}, + // {workdir, "services-empty-image", "push", "", platforms, secrets}, + // {workdir, "services-host-network", "push", "", platforms, secrets}, + // {workdir, "services-with-container", "push", "", platforms, secrets}, + // {workdir, "mysql-service-container-with-health-check", "push", "", platforms, secrets}, + + // // local remote action overrides + // {workdir, "local-remote-action-overrides", "push", "", platforms, secrets}, } for _, table := range tables { From cd1ea374df87fb77ed13d90c841d7bf679054359 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Tue, 29 Oct 2024 22:05:30 +0000 Subject: [PATCH 04/12] .... --- pkg/runner/action_test.go | 4 ++-- pkg/runner/container_mock_test.go | 9 +++++++++ pkg/runner/step_action_remote_test.go | 6 +++--- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/pkg/runner/action_test.go b/pkg/runner/action_test.go index 2e2003f37a0..286bf30c85d 100644 --- a/pkg/runner/action_test.go +++ b/pkg/runner/action_test.go @@ -227,10 +227,10 @@ func TestActionRunner(t *testing.T) { ctx := context.Background() cm := &containerMock{} - cm.On("CopyDir", "/var/run/act/actions/dir/", "dir/", false).Return(func(ctx context.Context) error { return nil }) + cm.Mock.On("CopyTarStream", ctx, "/var/run/act/actions/dir/", mock.Anything).Return(nil) cacheMock := &TestRepositoryCache{} - cacheMock.On("GetTarArchive", ctx, "", "", "").Return(io.MultiReader()) + cacheMock.Mock.On("GetTarArchive", ctx, "", "", "").Return(io.NopCloser(io.MultiReader())) envMatcher := mock.MatchedBy(func(env map[string]string) bool { for k, v := range tt.expectedEnv { diff --git a/pkg/runner/container_mock_test.go b/pkg/runner/container_mock_test.go index 04d6261b167..7a8af59f273 100644 --- a/pkg/runner/container_mock_test.go +++ b/pkg/runner/container_mock_test.go @@ -73,3 +73,12 @@ func (cm *containerMock) GetContainerArchive(ctx context.Context, srcPath string } return args.Get(0).(io.ReadCloser), err } + +func (cm *containerMock) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error { + args := cm.Called(ctx, destPath, tarStream) + err, hasErr := args.Get(0).(error) + if !hasErr { + err = nil + } + return err +} diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 262c1e88126..7b695669c48 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -170,7 +170,7 @@ func TestStepActionRemote(t *testing.T) { } if tt.mocks.read { - sarm.On("readAction", sar.Step, "someval", "", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.Mock.On("readAction", sar.Step, "someval", "", mock.Anything, mock.Anything).Return(&model.Action{}, nil) } 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 }) @@ -248,7 +248,7 @@ func TestStepActionRemotePre(t *testing.T) { readAction: sarm.readAction, } - sarm.On("readAction", sar.Step, "someval", "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.Mock.On("readAction", sar.Step, "someval", "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") err := sar.pre()(ctx) @@ -301,7 +301,7 @@ func TestStepActionRemotePreThroughAction(t *testing.T) { readAction: sarm.readAction, } - sarm.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.Mock.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "").Return("someval") err := sar.pre()(ctx) From c29378de656e2fd77ec2b4cf8d4ba9a72e483224 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Tue, 29 Oct 2024 22:08:16 +0000 Subject: [PATCH 05/12] lint --- pkg/runner/container_mock_test.go | 2 +- pkg/runner/step_action_remote_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/runner/container_mock_test.go b/pkg/runner/container_mock_test.go index 7a8af59f273..86343d5a238 100644 --- a/pkg/runner/container_mock_test.go +++ b/pkg/runner/container_mock_test.go @@ -75,7 +75,7 @@ func (cm *containerMock) GetContainerArchive(ctx context.Context, srcPath string } func (cm *containerMock) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error { - args := cm.Called(ctx, destPath, tarStream) + args := cm.Mock.Called(ctx, destPath, tarStream) err, hasErr := args.Get(0).(error) if !hasErr { err = nil diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 7b695669c48..d93d625846d 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -355,7 +355,7 @@ func TestStepActionRemotePreThroughActionToken(t *testing.T) { readAction: sarm.readAction, } - sarm.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) + sarm.Mock.On("readAction", sar.Step, mock.AnythingOfType("string"), "path", mock.Anything, mock.Anything).Return(&model.Action{}, nil) cacheMock.Mock.On("Fetch", ctx, mock.AnythingOfType("string"), "https://github.com/org/repo", "ref", "PRIVATE_ACTIONS_TOKEN_ON_GITHUB").Return("someval") err := sar.pre()(ctx) From b6886c6562b6bf5ca1fec4ef611193f6349db7e9 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sat, 2 Nov 2024 20:44:11 +0000 Subject: [PATCH 06/12] wip --- pkg/runner/action.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/runner/action.go b/pkg/runner/action.go index 8aa8a52d4bb..03f6a98a8c6 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -285,7 +285,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, sub defer buildContext.Close() } else { rstep := step.(*stepActionRemote) - buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, path.Join(subpath, action.Runs.Image)) + buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, subpath) if err != nil { return err } From 6560e026f96b3b8404063038033b16ee8a5bfc83 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sat, 2 Nov 2024 22:06:51 +0000 Subject: [PATCH 07/12] fixup --- pkg/runner/action.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/runner/action.go b/pkg/runner/action.go index 03f6a98a8c6..759f112c886 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -252,7 +252,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, sub image = fmt.Sprintf("%s-dockeraction:%s", regexp.MustCompile("[^a-zA-Z0-9]").ReplaceAllString(actionName, "-"), "latest") image = fmt.Sprintf("act-%s", strings.TrimLeft(image, "-")) image = strings.ToLower(image) - contextDir, fileName := filepath.Split(filepath.Join(basedir, subpath, action.Runs.Image)) + contextDir, fileName := path.Split(path.Join(subpath, action.Runs.Image)) anyArchExists, err := container.ImageExistsLocally(ctx, image, "any") if err != nil { @@ -285,7 +285,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, sub defer buildContext.Close() } else { rstep := step.(*stepActionRemote) - buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, subpath) + buildContext, err = rc.getActionCache().GetTarArchive(ctx, rstep.cacheDir, rstep.resolvedSha, contextDir) if err != nil { return err } From 51b5861c7410b863dfe34d0c5adb1546b87d95bf Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sat, 2 Nov 2024 22:07:54 +0000 Subject: [PATCH 08/12] fix --- pkg/runner/runner_test.go | 190 +++++++++++++++++++------------------- 1 file changed, 95 insertions(+), 95 deletions(-) diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index df997c0c064..82defd77661 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -227,102 +227,102 @@ func TestRunEvent(t *testing.T) { tables := []TestJobFileInfo{ // Shells - // {workdir, "shells/defaults", "push", "", platforms, secrets}, - // // TODO: figure out why it fails - // // {workdir, "shells/custom", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, }, // custom image with pwsh - // {workdir, "shells/pwsh", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, secrets}, // custom image with pwsh - // {workdir, "shells/bash", "push", "", platforms, secrets}, - // {workdir, "shells/python", "push", "", map[string]string{"ubuntu-latest": "node:16-buster"}, secrets}, // slim doesn't have python - // {workdir, "shells/sh", "push", "", platforms, secrets}, - - // // Local action - // {workdir, "local-action-docker-url", "push", "", platforms, secrets}, - // {workdir, "local-action-dockerfile", "push", "", platforms, secrets}, - // {workdir, "local-action-via-composite-dockerfile", "push", "", platforms, secrets}, - // {workdir, "local-action-js", "push", "", platforms, secrets}, - - // // Uses - // {workdir, "uses-composite", "push", "", platforms, secrets}, - // {workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets}, - // {workdir, "uses-composite-check-for-input-collision", "push", "", platforms, secrets}, - // {workdir, "uses-composite-check-for-input-shadowing", "push", "", platforms, secrets}, - // {workdir, "uses-nested-composite", "push", "", platforms, secrets}, - // {workdir, "remote-action-composite-js-pre-with-defaults", "push", "", platforms, secrets}, - // {workdir, "remote-action-composite-action-ref", "push", "", platforms, secrets}, - // {workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}}, - // {workdir, "uses-workflow", "pull_request", "", platforms, map[string]string{"secret": "keep_it_private"}}, - // {workdir, "uses-docker-url", "push", "", platforms, secrets}, - // {workdir, "act-composite-env-test", "push", "", platforms, secrets}, - - // // Eval - // {workdir, "evalmatrix", "push", "", platforms, secrets}, - // {workdir, "evalmatrixneeds", "push", "", platforms, secrets}, - // {workdir, "evalmatrixneeds2", "push", "", platforms, secrets}, - // {workdir, "evalmatrix-merge-map", "push", "", platforms, secrets}, - // {workdir, "evalmatrix-merge-array", "push", "", platforms, secrets}, - // {workdir, "issue-1195", "push", "", platforms, secrets}, - - // {workdir, "basic", "push", "", platforms, secrets}, - // {workdir, "fail", "push", "exit with `FAILURE`: 1", platforms, secrets}, - // {workdir, "runs-on", "push", "", platforms, secrets}, - // {workdir, "checkout", "push", "", platforms, secrets}, - // {workdir, "job-container", "push", "", platforms, secrets}, - // {workdir, "job-container-non-root", "push", "", platforms, secrets}, - // {workdir, "job-container-invalid-credentials", "push", "failed to handle credentials: failed to interpolate container.credentials.password", platforms, secrets}, - // {workdir, "container-hostname", "push", "", platforms, secrets}, - // {workdir, "remote-action-docker", "push", "", platforms, secrets}, - // {workdir, "remote-action-js", "push", "", platforms, secrets}, - // {workdir, "remote-action-js-node-user", "push", "", platforms, secrets}, // Test if this works with non root container - // {workdir, "matrix", "push", "", platforms, secrets}, - // {workdir, "matrix-include-exclude", "push", "", platforms, secrets}, - // {workdir, "matrix-exitcode", "push", "Job 'test' failed", platforms, secrets}, - // {workdir, "commands", "push", "", platforms, secrets}, - // {workdir, "workdir", "push", "", platforms, secrets}, - // {workdir, "defaults-run", "push", "", platforms, secrets}, - // {workdir, "composite-fail-with-output", "push", "", platforms, secrets}, - // {workdir, "issue-597", "push", "", platforms, secrets}, - // {workdir, "issue-598", "push", "", platforms, secrets}, - // {workdir, "if-env-act", "push", "", platforms, secrets}, - // {workdir, "env-and-path", "push", "", platforms, secrets}, - // {workdir, "environment-files", "push", "", platforms, secrets}, - // {workdir, "GITHUB_STATE", "push", "", platforms, secrets}, - // {workdir, "environment-files-parser-bug", "push", "", platforms, secrets}, - // {workdir, "non-existent-action", "push", "Job 'nopanic' failed", platforms, secrets}, - // {workdir, "outputs", "push", "", platforms, secrets}, - // {workdir, "networking", "push", "", platforms, secrets}, - // {workdir, "steps-context/conclusion", "push", "", platforms, secrets}, - // {workdir, "steps-context/outcome", "push", "", platforms, secrets}, - // {workdir, "job-status-check", "push", "job 'fail' failed", platforms, secrets}, - // {workdir, "if-expressions", "push", "Job 'mytest' failed", platforms, secrets}, + {workdir, "shells/defaults", "push", "", platforms, secrets}, + // TODO: figure out why it fails + // {workdir, "shells/custom", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, }, // custom image with pwsh + {workdir, "shells/pwsh", "push", "", map[string]string{"ubuntu-latest": "catthehacker/ubuntu:pwsh-latest"}, secrets}, // custom image with pwsh + {workdir, "shells/bash", "push", "", platforms, secrets}, + {workdir, "shells/python", "push", "", map[string]string{"ubuntu-latest": "node:16-buster"}, secrets}, // slim doesn't have python + {workdir, "shells/sh", "push", "", platforms, secrets}, + + // Local action + {workdir, "local-action-docker-url", "push", "", platforms, secrets}, + {workdir, "local-action-dockerfile", "push", "", platforms, secrets}, + {workdir, "local-action-via-composite-dockerfile", "push", "", platforms, secrets}, + {workdir, "local-action-js", "push", "", platforms, secrets}, + + // Uses + {workdir, "uses-composite", "push", "", platforms, secrets}, + {workdir, "uses-composite-with-error", "push", "Job 'failing-composite-action' failed", platforms, secrets}, + {workdir, "uses-composite-check-for-input-collision", "push", "", platforms, secrets}, + {workdir, "uses-composite-check-for-input-shadowing", "push", "", platforms, secrets}, + {workdir, "uses-nested-composite", "push", "", platforms, secrets}, + {workdir, "remote-action-composite-js-pre-with-defaults", "push", "", platforms, secrets}, + {workdir, "remote-action-composite-action-ref", "push", "", platforms, secrets}, + {workdir, "uses-workflow", "push", "", platforms, map[string]string{"secret": "keep_it_private"}}, + {workdir, "uses-workflow", "pull_request", "", platforms, map[string]string{"secret": "keep_it_private"}}, + {workdir, "uses-docker-url", "push", "", platforms, secrets}, + {workdir, "act-composite-env-test", "push", "", platforms, secrets}, + + // Eval + {workdir, "evalmatrix", "push", "", platforms, secrets}, + {workdir, "evalmatrixneeds", "push", "", platforms, secrets}, + {workdir, "evalmatrixneeds2", "push", "", platforms, secrets}, + {workdir, "evalmatrix-merge-map", "push", "", platforms, secrets}, + {workdir, "evalmatrix-merge-array", "push", "", platforms, secrets}, + {workdir, "issue-1195", "push", "", platforms, secrets}, + + {workdir, "basic", "push", "", platforms, secrets}, + {workdir, "fail", "push", "exit with `FAILURE`: 1", platforms, secrets}, + {workdir, "runs-on", "push", "", platforms, secrets}, + {workdir, "checkout", "push", "", platforms, secrets}, + {workdir, "job-container", "push", "", platforms, secrets}, + {workdir, "job-container-non-root", "push", "", platforms, secrets}, + {workdir, "job-container-invalid-credentials", "push", "failed to handle credentials: failed to interpolate container.credentials.password", platforms, secrets}, + {workdir, "container-hostname", "push", "", platforms, secrets}, + {workdir, "remote-action-docker", "push", "", platforms, secrets}, + {workdir, "remote-action-js", "push", "", platforms, secrets}, + {workdir, "remote-action-js-node-user", "push", "", platforms, secrets}, // Test if this works with non root container + {workdir, "matrix", "push", "", platforms, secrets}, + {workdir, "matrix-include-exclude", "push", "", platforms, secrets}, + {workdir, "matrix-exitcode", "push", "Job 'test' failed", platforms, secrets}, + {workdir, "commands", "push", "", platforms, secrets}, + {workdir, "workdir", "push", "", platforms, secrets}, + {workdir, "defaults-run", "push", "", platforms, secrets}, + {workdir, "composite-fail-with-output", "push", "", platforms, secrets}, + {workdir, "issue-597", "push", "", platforms, secrets}, + {workdir, "issue-598", "push", "", platforms, secrets}, + {workdir, "if-env-act", "push", "", platforms, secrets}, + {workdir, "env-and-path", "push", "", platforms, secrets}, + {workdir, "environment-files", "push", "", platforms, secrets}, + {workdir, "GITHUB_STATE", "push", "", platforms, secrets}, + {workdir, "environment-files-parser-bug", "push", "", platforms, secrets}, + {workdir, "non-existent-action", "push", "Job 'nopanic' failed", platforms, secrets}, + {workdir, "outputs", "push", "", platforms, secrets}, + {workdir, "networking", "push", "", platforms, secrets}, + {workdir, "steps-context/conclusion", "push", "", platforms, secrets}, + {workdir, "steps-context/outcome", "push", "", platforms, secrets}, + {workdir, "job-status-check", "push", "job 'fail' failed", platforms, secrets}, + {workdir, "if-expressions", "push", "Job 'mytest' failed", platforms, secrets}, {workdir, "actions-environment-and-context-tests", "push", "", platforms, secrets}, - // {workdir, "uses-action-with-pre-and-post-step", "push", "", platforms, secrets}, - // {workdir, "evalenv", "push", "", platforms, secrets}, - // {workdir, "docker-action-custom-path", "push", "", platforms, secrets}, - // {workdir, "GITHUB_ENV-use-in-env-ctx", "push", "", platforms, secrets}, - // {workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms, secrets}, - // {workdir, "workflow_call_inputs", "workflow_call", "", platforms, secrets}, - // {workdir, "workflow_dispatch", "workflow_dispatch", "", platforms, secrets}, - // {workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets}, - // {workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets}, - // {workdir, "workflow_dispatch-scalar-composite-action", "workflow_dispatch", "", platforms, secrets}, - // {workdir, "job-needs-context-contains-result", "push", "", platforms, secrets}, - // {"../model/testdata", "strategy", "push", "", platforms, secrets}, // TODO: move all testdata into pkg so we can validate it with planner and runner - // {"../model/testdata", "container-volumes", "push", "", platforms, secrets}, - // {workdir, "path-handling", "push", "", platforms, secrets}, - // {workdir, "do-not-leak-step-env-in-composite", "push", "", platforms, secrets}, - // {workdir, "set-env-step-env-override", "push", "", platforms, secrets}, - // {workdir, "set-env-new-env-file-per-step", "push", "", platforms, secrets}, - // {workdir, "no-panic-on-invalid-composite-action", "push", "jobs failed due to invalid action", platforms, secrets}, - - // // services - // {workdir, "services", "push", "", platforms, secrets}, - // {workdir, "services-empty-image", "push", "", platforms, secrets}, - // {workdir, "services-host-network", "push", "", platforms, secrets}, - // {workdir, "services-with-container", "push", "", platforms, secrets}, - // {workdir, "mysql-service-container-with-health-check", "push", "", platforms, secrets}, - - // // local remote action overrides - // {workdir, "local-remote-action-overrides", "push", "", platforms, secrets}, + {workdir, "uses-action-with-pre-and-post-step", "push", "", platforms, secrets}, + {workdir, "evalenv", "push", "", platforms, secrets}, + {workdir, "docker-action-custom-path", "push", "", platforms, secrets}, + {workdir, "GITHUB_ENV-use-in-env-ctx", "push", "", platforms, secrets}, + {workdir, "ensure-post-steps", "push", "Job 'second-post-step-should-fail' failed", platforms, secrets}, + {workdir, "workflow_call_inputs", "workflow_call", "", platforms, secrets}, + {workdir, "workflow_dispatch", "workflow_dispatch", "", platforms, secrets}, + {workdir, "workflow_dispatch_no_inputs_mapping", "workflow_dispatch", "", platforms, secrets}, + {workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets}, + {workdir, "workflow_dispatch-scalar-composite-action", "workflow_dispatch", "", platforms, secrets}, + {workdir, "job-needs-context-contains-result", "push", "", platforms, secrets}, + {"../model/testdata", "strategy", "push", "", platforms, secrets}, // TODO: move all testdata into pkg so we can validate it with planner and runner + {"../model/testdata", "container-volumes", "push", "", platforms, secrets}, + {workdir, "path-handling", "push", "", platforms, secrets}, + {workdir, "do-not-leak-step-env-in-composite", "push", "", platforms, secrets}, + {workdir, "set-env-step-env-override", "push", "", platforms, secrets}, + {workdir, "set-env-new-env-file-per-step", "push", "", platforms, secrets}, + {workdir, "no-panic-on-invalid-composite-action", "push", "jobs failed due to invalid action", platforms, secrets}, + + // services + {workdir, "services", "push", "", platforms, secrets}, + {workdir, "services-empty-image", "push", "", platforms, secrets}, + {workdir, "services-host-network", "push", "", platforms, secrets}, + {workdir, "services-with-container", "push", "", platforms, secrets}, + {workdir, "mysql-service-container-with-health-check", "push", "", platforms, secrets}, + + // local remote action overrides + {workdir, "local-remote-action-overrides", "push", "", platforms, secrets}, } for _, table := range tables { From 12ce7edcf7f1f634c85f76fce02118df32425373 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sat, 2 Nov 2024 23:02:15 +0000 Subject: [PATCH 09/12] remove old cache entries --- cmd/root.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/root.go b/cmd/root.go index 21b82d19306..107e477b159 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -392,6 +392,16 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str vars := newSecrets(input.vars) _ = readEnvs(input.Varfile(), vars) + log.Debugf("Cleaning up %s old action cache format", input.actionCachePath) + entries, _ := os.ReadDir(input.actionCachePath) + for _, entry := range entries { + if strings.Contains(entry.Name(), "@") { + fullPath := filepath.Join(input.actionCachePath, entry.Name()) + log.Debugf("Removing %s", fullPath) + _ = os.RemoveAll(fullPath) + } + } + matrixes := parseMatrix(input.matrix) log.Debugf("Evaluated matrix inclusions: %v", matrixes) @@ -652,7 +662,7 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str func defaultImageSurvey(actrc string) error { var answer string confirmation := &survey.Select{ - Message: "Please choose the default image you want to use with act:\n - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in " + configLocations()[0] + " (please refer to https://github.com/nektos/act#configuration for additional information about file structure)", + Message: "Please choose the default image you want to use with act:\n - Large size image: ca. 17GB download + 53.1GB storage, you will need 75GB of free disk space, snapshots of GitHub Hosted Runners without snap and pulled docker images\n - Medium size image: ~500MB, includes only necessary tools to bootstrap actions and aims to be compatible with most actions\n - Micro size image: <200MB, contains only NodeJS required to bootstrap actions, doesn't work with all actions\n\nDefault image and other options can be changed manually in " + configLocations()[0] + " (please refer to https://github.com/nektos/act#configuration for additional information about file structure)", Help: "If you want to know why act asks you that, please go to https://github.com/nektos/act/issues/107", Default: "Medium", Options: []string{"Large", "Medium", "Micro"}, From 3e99f35aa81234bcf3584709404a1b26895a38c8 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sun, 3 Nov 2024 01:10:45 +0100 Subject: [PATCH 10/12] don't cause bugs in otherwise deleted code --- pkg/runner/action.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pkg/runner/action.go b/pkg/runner/action.go index 759f112c886..a4789b06c48 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -292,7 +292,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, sub defer buildContext.Close() } prepImage = container.NewDockerBuildExecutor(container.NewDockerBuildExecutorInput{ - ContextDir: contextDir, + ContextDir: filepath.Join(basedir, contextDir), Dockerfile: fileName, ImageTag: image, BuildContext: buildContext, @@ -316,6 +316,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, sub if len(entrypoint) == 0 { if entrypointType == "pre-entrypoint" && action.Runs.PreEntrypoint != "" { entrypoint, err = shellquote.Split(action.Runs.PreEntrypoint) + if err != nil { return err } From d04693d5e6201c8ac3123eb059fefe249a7d9c45 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sun, 3 Nov 2024 01:18:53 +0100 Subject: [PATCH 11/12] Update action.go --- pkg/runner/action.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/runner/action.go b/pkg/runner/action.go index a4789b06c48..46f7880c5f2 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -316,7 +316,7 @@ func execAsDocker(ctx context.Context, step actionStep, actionName, basedir, sub if len(entrypoint) == 0 { if entrypointType == "pre-entrypoint" && action.Runs.PreEntrypoint != "" { entrypoint, err = shellquote.Split(action.Runs.PreEntrypoint) - + if err != nil { return err } From f8757324a187207832cd290e963d6816f7635165 Mon Sep 17 00:00:00 2001 From: ChristopherHX Date: Sun, 3 Nov 2024 15:16:22 +0100 Subject: [PATCH 12/12] add dryrun early exit to CopyTarStream --- pkg/container/host_environment.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/container/host_environment.go b/pkg/container/host_environment.go index d4a9869d070..2c541c2d2e7 100644 --- a/pkg/container/host_environment.go +++ b/pkg/container/host_environment.go @@ -62,6 +62,9 @@ func (e *HostEnvironment) Copy(destPath string, files ...*FileEntry) common.Exec } func (e *HostEnvironment) CopyTarStream(ctx context.Context, destPath string, tarStream io.Reader) error { + if common.Dryrun(ctx) { + return nil + } if err := os.RemoveAll(destPath); err != nil { return err }