github.com/nektos/act@v0.2.63/pkg/runner/step_action_local.go (about)

     1  package runner
     2  
     3  import (
     4  	"archive/tar"
     5  	"context"
     6  	"errors"
     7  	"fmt"
     8  	"io"
     9  	"io/fs"
    10  	"os"
    11  	"path"
    12  	"path/filepath"
    13  
    14  	"github.com/nektos/act/pkg/common"
    15  	"github.com/nektos/act/pkg/model"
    16  )
    17  
    18  type stepActionLocal struct {
    19  	Step                *model.Step
    20  	RunContext          *RunContext
    21  	compositeRunContext *RunContext
    22  	compositeSteps      *compositeSteps
    23  	runAction           runAction
    24  	readAction          readAction
    25  	env                 map[string]string
    26  	action              *model.Action
    27  }
    28  
    29  func (sal *stepActionLocal) pre() common.Executor {
    30  	sal.env = map[string]string{}
    31  
    32  	return func(ctx context.Context) error {
    33  		return nil
    34  	}
    35  }
    36  
    37  func (sal *stepActionLocal) main() common.Executor {
    38  	return runStepExecutor(sal, stepStageMain, func(ctx context.Context) error {
    39  		if common.Dryrun(ctx) {
    40  			return nil
    41  		}
    42  
    43  		actionDir := filepath.Join(sal.getRunContext().Config.Workdir, sal.Step.Uses)
    44  
    45  		localReader := func(ctx context.Context) actionYamlReader {
    46  			_, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, ""), sal.RunContext)
    47  			return func(filename string) (io.Reader, io.Closer, error) {
    48  				spath := path.Join(cpath, filename)
    49  				for i := 0; i < maxSymlinkDepth; i++ {
    50  					tars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, spath)
    51  					if errors.Is(err, fs.ErrNotExist) {
    52  						return nil, nil, err
    53  					} else if err != nil {
    54  						return nil, nil, fs.ErrNotExist
    55  					}
    56  					treader := tar.NewReader(tars)
    57  					header, err := treader.Next()
    58  					if errors.Is(err, io.EOF) {
    59  						return nil, nil, os.ErrNotExist
    60  					} else if err != nil {
    61  						return nil, nil, err
    62  					}
    63  					if header.FileInfo().Mode()&os.ModeSymlink == os.ModeSymlink {
    64  						spath, err = symlinkJoin(spath, header.Linkname, cpath)
    65  						if err != nil {
    66  							return nil, nil, err
    67  						}
    68  					} else {
    69  						return treader, tars, nil
    70  					}
    71  				}
    72  				return nil, nil, fmt.Errorf("max depth %d of symlinks exceeded while reading %s", maxSymlinkDepth, spath)
    73  			}
    74  		}
    75  
    76  		actionModel, err := sal.readAction(ctx, sal.Step, actionDir, "", localReader(ctx), os.WriteFile)
    77  		if err != nil {
    78  			return err
    79  		}
    80  
    81  		sal.action = actionModel
    82  
    83  		return sal.runAction(sal, actionDir, nil)(ctx)
    84  	})
    85  }
    86  
    87  func (sal *stepActionLocal) post() common.Executor {
    88  	return runStepExecutor(sal, stepStagePost, runPostStep(sal)).If(hasPostStep(sal)).If(shouldRunPostStep(sal))
    89  }
    90  
    91  func (sal *stepActionLocal) getRunContext() *RunContext {
    92  	return sal.RunContext
    93  }
    94  
    95  func (sal *stepActionLocal) getGithubContext(ctx context.Context) *model.GithubContext {
    96  	return sal.getRunContext().getGithubContext(ctx)
    97  }
    98  
    99  func (sal *stepActionLocal) getStepModel() *model.Step {
   100  	return sal.Step
   101  }
   102  
   103  func (sal *stepActionLocal) getEnv() *map[string]string {
   104  	return &sal.env
   105  }
   106  
   107  func (sal *stepActionLocal) getIfExpression(_ context.Context, stage stepStage) string {
   108  	switch stage {
   109  	case stepStageMain:
   110  		return sal.Step.If.Value
   111  	case stepStagePost:
   112  		return sal.action.Runs.PostIf
   113  	}
   114  	return ""
   115  }
   116  
   117  func (sal *stepActionLocal) getActionModel() *model.Action {
   118  	return sal.action
   119  }
   120  
   121  func (sal *stepActionLocal) getCompositeRunContext(ctx context.Context) *RunContext {
   122  	if sal.compositeRunContext == nil {
   123  		actionDir := filepath.Join(sal.RunContext.Config.Workdir, sal.Step.Uses)
   124  		_, containerActionDir := getContainerActionPaths(sal.getStepModel(), actionDir, sal.RunContext)
   125  
   126  		sal.compositeRunContext = newCompositeRunContext(ctx, sal.RunContext, sal, containerActionDir)
   127  		sal.compositeSteps = sal.compositeRunContext.compositeExecutor(sal.action)
   128  	}
   129  	return sal.compositeRunContext
   130  }
   131  
   132  func (sal *stepActionLocal) getCompositeSteps() *compositeSteps {
   133  	return sal.compositeSteps
   134  }