diff --git a/pkg/runner/action.go b/pkg/runner/action.go index dedb497eb6f..355668069c0 100644 --- a/pkg/runner/action.go +++ b/pkg/runner/action.go @@ -100,6 +100,27 @@ func readActionImpl(step *model.Step, actionDir string, actionPath string, readF return action, err } +func maybeCopyToActionDir(ctx context.Context, step actionStep, actionDir string, actionPath string, containerActionDir string) error { + rc := step.getRunContext() + stepModel := step.getStepModel() + + if stepModel.Type() != model.StepTypeUsesActionRemote { + return nil + } + if err := removeGitIgnore(actionDir); err != nil { + return err + } + + var containerActionDirCopy string + containerActionDirCopy = strings.TrimSuffix(containerActionDir, actionPath) + log.Debug(containerActionDirCopy) + + if !strings.HasSuffix(containerActionDirCopy, `/`) { + containerActionDirCopy += `/` + } + return rc.JobContainer.CopyDir(containerActionDirCopy, actionDir+"/", rc.Config.UseGitIgnore)(ctx) +} + func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction) common.Executor { rc := step.getRunContext() stepModel := step.getStepModel() @@ -139,27 +160,9 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction log.Debugf("type=%v actionDir=%s actionPath=%s workdir=%s actionCacheDir=%s actionName=%s containerActionDir=%s", stepModel.Type(), actionDir, actionPath, rc.Config.Workdir, rc.ActionCacheDir(), actionName, containerActionDir) - maybeCopyToActionDir := func() error { - if stepModel.Type() != model.StepTypeUsesActionRemote { - return nil - } - if err := removeGitIgnore(actionDir); err != nil { - return err - } - - var containerActionDirCopy string - containerActionDirCopy = strings.TrimSuffix(containerActionDir, actionPath) - log.Debug(containerActionDirCopy) - - if !strings.HasSuffix(containerActionDirCopy, `/`) { - containerActionDirCopy += `/` - } - return rc.JobContainer.CopyDir(containerActionDirCopy, actionDir+"/", rc.Config.UseGitIgnore)(ctx) - } - switch action.Runs.Using { case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16: - if err := maybeCopyToActionDir(); err != nil { + if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil { return err } containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Main)} @@ -172,7 +175,7 @@ func runActionImpl(step actionStep, actionDir string, remoteAction *remoteAction } return execAsDocker(ctx, step, actionName, location, remoteAction == nil) case model.ActionRunsUsingComposite: - if err := maybeCopyToActionDir(); err != nil { + if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil { return err } @@ -372,6 +375,29 @@ func newStepContainer(ctx context.Context, step step, image string, cmd []string return stepContainer } +func (rc *RunContext) setupActionInputs(step actionStep) { + if step.getActionModel() == nil { + // e.g. local checkout skip has no action model + return + } + + stepModel := step.getStepModel() + action := step.getActionModel() + + eval := rc.NewExpressionEvaluator() + inputs := make(map[string]interface{}) + for k, input := range action.Inputs { + inputs[k] = eval.Interpolate(input.Default) + } + if stepModel.With != nil { + for k, v := range stepModel.With { + inputs[k] = eval.Interpolate(v) + } + } + + rc.Inputs = inputs +} + func populateEnvsFromSavedState(env *map[string]string, step actionStep, rc *RunContext) { stepResult := rc.StepResults[step.getStepModel().ID] if stepResult != nil { @@ -424,6 +450,78 @@ func getOsSafeRelativePath(s, prefix string) string { return actionName } +func shouldRunPreStep(step actionStep) common.Conditional { + return func(ctx context.Context) bool { + log := common.Logger(ctx) + + if step.getActionModel() == nil { + log.Debugf("skip pre step for '%s': no action model available", step.getStepModel()) + return false + } + + return true + } +} + +func hasPreStep(step actionStep) common.Conditional { + return func(ctx context.Context) bool { + action := step.getActionModel() + return action.Runs.Using == model.ActionRunsUsingComposite || + ((action.Runs.Using == model.ActionRunsUsingNode12 || + action.Runs.Using == model.ActionRunsUsingNode16) && + action.Runs.Pre != "") + } +} + +func runPreStep(step actionStep) common.Executor { + return func(ctx context.Context) error { + common.Logger(ctx).Debugf("run pre step for '%s'", step.getStepModel()) + + rc := step.getRunContext() + stepModel := step.getStepModel() + action := step.getActionModel() + + switch action.Runs.Using { + case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16: + // todo: refactor into step + var actionDir string + var actionPath string + if _, ok := step.(*stepActionRemote); ok { + actionPath = newRemoteAction(stepModel.Uses).Path + actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), strings.ReplaceAll(stepModel.Uses, "/", "-")) + } else { + actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses) + actionPath = "" + } + + actionLocation := "" + if actionPath != "" { + actionLocation = path.Join(actionDir, actionPath) + } else { + actionLocation = actionDir + } + + _, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc) + + if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil { + return err + } + + containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Pre)} + log.Debugf("executing remote job container: %s", containerArgs) + + return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx) + + case model.ActionRunsUsingComposite: + step.getCompositeRunContext().updateCompositeRunContext(step.getRunContext(), step) + return step.getCompositeSteps().pre(ctx) + + default: + return nil + } + } +} + func shouldRunPostStep(step actionStep) common.Conditional { return func(ctx context.Context) bool { log := common.Logger(ctx) @@ -467,30 +565,30 @@ func runPostStep(step actionStep) common.Executor { stepModel := step.getStepModel() action := step.getActionModel() - switch action.Runs.Using { - case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16: + // todo: refactor into step + var actionDir string + var actionPath string + if _, ok := step.(*stepActionRemote); ok { + actionPath = newRemoteAction(stepModel.Uses).Path + actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), strings.ReplaceAll(stepModel.Uses, "/", "-")) + } else { + actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses) + actionPath = "" + } - populateEnvsFromSavedState(step.getEnv(), step, rc) + actionLocation := "" + if actionPath != "" { + actionLocation = path.Join(actionDir, actionPath) + } else { + actionLocation = actionDir + } - // todo: refactor into step - var actionDir string - var actionPath string - if _, ok := step.(*stepActionRemote); ok { - actionPath = newRemoteAction(stepModel.Uses).Path - actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), strings.ReplaceAll(stepModel.Uses, "/", "-")) - } else { - actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses) - actionPath = "" - } + _, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc) - actionLocation := "" - if actionPath != "" { - actionLocation = path.Join(actionDir, actionPath) - } else { - actionLocation = actionDir - } + switch action.Runs.Using { + case model.ActionRunsUsingNode12, model.ActionRunsUsingNode16: - _, containerActionDir := getContainerActionPaths(stepModel, actionLocation, rc) + populateEnvsFromSavedState(step.getEnv(), step, rc) containerArgs := []string{"node", path.Join(containerActionDir, action.Runs.Post)} log.Debugf("executing remote job container: %s", containerArgs) @@ -498,6 +596,10 @@ func runPostStep(step actionStep) common.Executor { return rc.execJobContainer(containerArgs, *step.getEnv(), "", "")(ctx) case model.ActionRunsUsingComposite: + if err := maybeCopyToActionDir(ctx, step, actionDir, actionPath, containerActionDir); err != nil { + return err + } + step.getCompositeRunContext().updateCompositeRunContext(step.getRunContext(), step) return step.getCompositeSteps().post(ctx) diff --git a/pkg/runner/action_composite.go b/pkg/runner/action_composite.go index bb6c5dc6d1b..924bc7b5bbc 100644 --- a/pkg/runner/action_composite.go +++ b/pkg/runner/action_composite.go @@ -85,18 +85,12 @@ func execAsComposite(step actionStep) common.Executor { return func(ctx context.Context) error { compositerc := step.getCompositeRunContext() - var err error steps := step.getCompositeSteps() - compositerc.updateCompositeRunContext(rc, step) ctx = WithCompositeLogger(ctx, &compositerc.Masks) - // todo: pre should be run in the pre step - err = steps.pre(ctx) - if err == nil { - compositerc.updateCompositeRunContext(rc, step) - err = steps.main(ctx) - } + compositerc.updateCompositeRunContext(rc, step) + err := steps.main(ctx) // Map outputs from composite RunContext to job RunContext eval := compositerc.NewExpressionEvaluator() diff --git a/pkg/runner/runner_test.go b/pkg/runner/runner_test.go index fa27995ee5f..224d1012b59 100644 --- a/pkg/runner/runner_test.go +++ b/pkg/runner/runner_test.go @@ -173,6 +173,7 @@ func TestRunEvent(t *testing.T) { {workdir, "job-status-check", "push", "job 'fail' failed", platforms}, {workdir, "if-expressions", "push", "Job 'mytest' failed", platforms}, {workdir, "actions-environment-and-context-tests", "push", "", platforms}, + {workdir, "uses-action-with-pre-and-post-step", "push", "", platforms}, {"../model/testdata", "strategy", "push", "", platforms}, // TODO: move all testdata into pkg so we can validate it with planner and runner // {"testdata", "issue-228", "push", "", platforms, }, // TODO [igni]: Remove this once everything passes {"../model/testdata", "container-volumes", "push", "", platforms}, diff --git a/pkg/runner/step.go b/pkg/runner/step.go index c57ad64e957..60a37542022 100644 --- a/pkg/runner/step.go +++ b/pkg/runner/step.go @@ -169,7 +169,7 @@ func isStepEnabled(ctx context.Context, expr string, step step) (bool, error) { runStep, err := EvalBool(rc.NewStepExpressionEvaluator(step), expr) if err != nil { - return false, fmt.Errorf(" \u274C Error in if-expression: \"if: %s\" (%s)", step.getStepModel().If.Value, err) + return false, fmt.Errorf(" \u274C Error in if-expression: \"if: %s\" (%s)", expr, err) } return runStep, nil diff --git a/pkg/runner/step_action_local.go b/pkg/runner/step_action_local.go index 5697c3ed791..be4303aac75 100644 --- a/pkg/runner/step_action_local.go +++ b/pkg/runner/step_action_local.go @@ -25,15 +25,9 @@ type stepActionLocal struct { } func (sal *stepActionLocal) pre() common.Executor { - return func(ctx context.Context) error { - return nil - } -} - -func (sal *stepActionLocal) main() common.Executor { sal.env = map[string]string{} - return runStepExecutor(sal, stepStageMain, func(ctx context.Context) error { + return func(ctx context.Context) error { actionDir := filepath.Join(sal.getRunContext().Config.Workdir, sal.Step.Uses) localReader := func(ctx context.Context) actionYamlReader { @@ -58,6 +52,20 @@ func (sal *stepActionLocal) main() common.Executor { sal.action = actionModel + // run local pre step only for composite actions, to allow to run + // inside pre steps + if sal.action.Runs.Using == model.ActionRunsUsingComposite { + sal.RunContext.setupActionInputs(sal) + return runStepExecutor(sal, stepStagePre, runPreStep(sal)).If(hasPreStep(sal)).If(shouldRunPreStep(sal))(ctx) + } + + return nil + } +} + +func (sal *stepActionLocal) main() common.Executor { + return runStepExecutor(sal, stepStageMain, func(ctx context.Context) error { + actionDir := filepath.Join(sal.getRunContext().Config.Workdir, sal.Step.Uses) return sal.runAction(sal, actionDir, nil)(ctx) }) } diff --git a/pkg/runner/step_action_local_test.go b/pkg/runner/step_action_local_test.go index 055169b8608..d0b0dfb0ee0 100644 --- a/pkg/runner/step_action_local_test.go +++ b/pkg/runner/step_action_local_test.go @@ -82,8 +82,10 @@ func TestStepActionLocalTest(t *testing.T) { return nil }) - err := sal.main()(ctx) + err := sal.pre()(ctx) + assert.Nil(t, err) + err = sal.main()(ctx) assert.Nil(t, err) cm.AssertExpectations(t) @@ -91,12 +93,49 @@ func TestStepActionLocalTest(t *testing.T) { } func TestStepActionLocalPre(t *testing.T) { + cm := &containerMock{} + salm := &stepActionLocalMocks{} + ctx := context.Background() - sal := &stepActionLocal{} + sal := &stepActionLocal{ + readAction: salm.readAction, + RunContext: &RunContext{ + StepResults: map[string]*model.StepResult{}, + ExprEval: &expressionEvaluator{}, + Config: &Config{ + Workdir: "/tmp", + }, + Run: &model.Run{ + JobID: "1", + Workflow: &model.Workflow{ + Jobs: map[string]*model.Job{ + "1": { + Defaults: model.Defaults{ + Run: model.RunDefaults{ + Shell: "bash", + }, + }, + }, + }, + }, + }, + JobContainer: cm, + }, + Step: &model.Step{ + ID: "1", + Uses: "./path/to/action", + }, + } + + salm.On("readAction", sal.Step, "/tmp/path/to/action", "", mock.Anything, mock.Anything). + Return(&model.Action{}, nil) err := sal.pre()(ctx) assert.Nil(t, err) + + cm.AssertExpectations(t) + salm.AssertExpectations(t) } func TestStepActionLocalPost(t *testing.T) { diff --git a/pkg/runner/step_action_remote.go b/pkg/runner/step_action_remote.go index 784ba2b14c9..edf4218bd3c 100644 --- a/pkg/runner/step_action_remote.go +++ b/pkg/runner/step_action_remote.go @@ -25,69 +25,85 @@ type stepActionRemote struct { runAction runAction action *model.Action env map[string]string -} - -func (sar *stepActionRemote) pre() common.Executor { - return func(ctx context.Context) error { - return nil - } + remoteAction *remoteAction } var ( stepActionRemoteNewCloneExecutor = common.NewGitCloneExecutor ) -func (sar *stepActionRemote) main() common.Executor { +func (sar *stepActionRemote) pre() common.Executor { sar.env = map[string]string{} - return runStepExecutor(sar, stepStageMain, func(ctx context.Context) error { - remoteAction := newRemoteAction(sar.Step.Uses) - if remoteAction == nil { - return fmt.Errorf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format", sar.Step.Uses) - } + return common.NewPipelineExecutor( + func(ctx context.Context) error { + sar.remoteAction = newRemoteAction(sar.Step.Uses) + if sar.remoteAction == nil { + return fmt.Errorf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format", sar.Step.Uses) + } + + sar.remoteAction.URL = sar.RunContext.Config.GitHubInstance + + github := sar.RunContext.getGithubContext() + if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout { + common.Logger(ctx).Debugf("Skipping local actions/checkout because workdir was already copied") + return nil + } + + actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), strings.ReplaceAll(sar.Step.Uses, "/", "-")) + gitClone := stepActionRemoteNewCloneExecutor(common.NewGitCloneExecutorInput{ + URL: sar.remoteAction.CloneURL(), + Ref: sar.remoteAction.Ref, + Dir: actionDir, + Token: github.Token, + }) + var ntErr common.Executor + if err := gitClone(ctx); err != nil { + if err.Error() == "short SHA references are not supported" { + err = errors.Cause(err) + 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.Error()) + } else if err.Error() != "some refs were not updated" { + return err + } else { + ntErr = common.NewInfoExecutor("Non-terminating error while running 'git clone': %v", err) + } + } - remoteAction.URL = sar.RunContext.Config.GitHubInstance + 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 common.NewPipelineExecutor( + ntErr, + func(ctx context.Context) error { + actionModel, err := sar.readAction(sar.Step, actionDir, sar.remoteAction.Path, remoteReader(ctx), ioutil.WriteFile) + sar.action = actionModel + return err + }, + )(ctx) + }, + func(ctx context.Context) error { + sar.RunContext.setupActionInputs(sar) + return nil + }, + runStepExecutor(sar, stepStagePre, runPreStep(sar)).If(hasPreStep(sar)).If(shouldRunPreStep(sar))) +} + +func (sar *stepActionRemote) main() common.Executor { + return runStepExecutor(sar, stepStageMain, func(ctx context.Context) error { github := sar.RunContext.getGithubContext() - if remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout { + if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout { common.Logger(ctx).Debugf("Skipping local actions/checkout because workdir was already copied") return nil } actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), strings.ReplaceAll(sar.Step.Uses, "/", "-")) - gitClone := stepActionRemoteNewCloneExecutor(common.NewGitCloneExecutorInput{ - URL: remoteAction.CloneURL(), - Ref: remoteAction.Ref, - Dir: actionDir, - Token: github.Token, - }) - var ntErr common.Executor - if err := gitClone(ctx); err != nil { - if err.Error() == "short SHA references are not supported" { - err = errors.Cause(err) - 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, remoteAction.Ref, err.Error()) - } else if err.Error() != "some refs were not updated" { - return err - } else { - ntErr = common.NewInfoExecutor("Non-terminating error while running 'git clone': %v", err) - } - } - - remoteReader := func(ctx context.Context) actionYamlReader { - return func(filename string) (io.Reader, io.Closer, error) { - f, err := os.Open(filepath.Join(actionDir, remoteAction.Path, filename)) - return f, f, err - } - } return common.NewPipelineExecutor( - ntErr, - func(ctx context.Context) error { - actionModel, err := sar.readAction(sar.Step, actionDir, remoteAction.Path, remoteReader(ctx), ioutil.WriteFile) - sar.action = actionModel - return err - }, - sar.runAction(sar, actionDir, remoteAction), + sar.runAction(sar, actionDir, sar.remoteAction), )(ctx) }) } @@ -111,6 +127,11 @@ func (sar *stepActionRemote) getEnv() *map[string]string { func (sar *stepActionRemote) getIfExpression(stage stepStage) string { switch stage { case stepStagePre: + github := sar.RunContext.getGithubContext() + if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout { + // skip local checkout pre step + return "false" + } return sar.action.Runs.PreIf case stepStageMain: return sar.Step.If.Value @@ -127,7 +148,7 @@ func (sar *stepActionRemote) getActionModel() *model.Action { func (sar *stepActionRemote) getCompositeRunContext() *RunContext { if sar.compositeRunContext == nil { actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), strings.ReplaceAll(sar.Step.Uses, "/", "-")) - actionLocation := path.Join(actionDir, newRemoteAction(sar.Step.Uses).Path) + actionLocation := path.Join(actionDir, sar.remoteAction.Path) _, containerActionDir := getContainerActionPaths(sar.getStepModel(), actionLocation, sar.RunContext) sar.compositeRunContext = newCompositeRunContext(sar.RunContext, sar, containerActionDir) diff --git a/pkg/runner/step_action_remote_test.go b/pkg/runner/step_action_remote_test.go index 4425268069e..209bee5c38a 100644 --- a/pkg/runner/step_action_remote_test.go +++ b/pkg/runner/step_action_remote_test.go @@ -82,8 +82,8 @@ func TestStepActionRemote(t *testing.T) { run bool }{ env: true, - cloned: false, - read: false, + cloned: true, + read: true, run: false, }, }, @@ -172,7 +172,10 @@ func TestStepActionRemote(t *testing.T) { sarm.On("runAction", sar, suffixMatcher("act/remote-action@v1"), newRemoteAction(sar.Step.Uses)).Return(func(ctx context.Context) error { return tt.runError }) } - err := sar.main()(ctx) + err := sar.pre()(ctx) + if err == nil { + err = sar.main()(ctx) + } assert.Equal(t, tt.runError, err) assert.Equal(t, tt.mocks.cloned, clonedAction) @@ -185,12 +188,70 @@ func TestStepActionRemote(t *testing.T) { } func TestStepActionRemotePre(t *testing.T) { - ctx := context.Background() + table := []struct { + name string + stepModel *model.Step + }{ + { + name: "run-pre", + stepModel: &model.Step{ + Uses: "org/repo/path@ref", + }, + }, + } + + for _, tt := range table { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + + clonedAction := false + sarm := &stepActionRemoteMocks{} + + origStepAtionRemoteNewCloneExecutor := stepActionRemoteNewCloneExecutor + stepActionRemoteNewCloneExecutor = func(input common.NewGitCloneExecutorInput) common.Executor { + return func(ctx context.Context) error { + clonedAction = true + return nil + } + } + defer (func() { + stepActionRemoteNewCloneExecutor = origStepAtionRemoteNewCloneExecutor + })() - sar := &stepActionRemote{} + sar := &stepActionRemote{ + Step: tt.stepModel, + RunContext: &RunContext{ + Config: &Config{ + GitHubInstance: "https://github.com", + }, + Run: &model.Run{ + JobID: "1", + Workflow: &model.Workflow{ + Jobs: map[string]*model.Job{ + "1": {}, + }, + }, + }, + }, + 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) + + err := sar.pre()(ctx) + + assert.Nil(t, err) + assert.Equal(t, true, clonedAction) - err := sar.pre()(ctx) - assert.Nil(t, err) + sarm.AssertExpectations(t) + }) + } } func TestStepActionRemotePost(t *testing.T) { diff --git a/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/action.yml b/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/action.yml new file mode 100644 index 00000000000..1ba0fc61eb7 --- /dev/null +++ b/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/action.yml @@ -0,0 +1,7 @@ +name: "last action check" +description: "last action check" + +runs: + using: "node16" + main: main.js + post: post.js diff --git a/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/main.js b/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/main.js new file mode 100644 index 00000000000..e69de29bb2d diff --git a/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/post.js b/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/post.js new file mode 100644 index 00000000000..e147e37d297 --- /dev/null +++ b/pkg/runner/testdata/uses-action-with-pre-and-post-step/last-action/post.js @@ -0,0 +1,17 @@ +const pre = process.env['ACTION_OUTPUT_PRE']; +const main = process.env['ACTION_OUTPUT_MAIN']; +const post = process.env['ACTION_OUTPUT_POST']; + +console.log({pre, main, post}); + +if (pre !== 'pre') { + throw new Error(`Expected 'pre' but got '${pre}'`); +} + +if (main !== 'main') { + throw new Error(`Expected 'main' but got '${main}'`); +} + +if (post !== 'post') { + throw new Error(`Expected 'post' but got '${post}'`); +} diff --git a/pkg/runner/testdata/uses-action-with-pre-and-post-step/push.yml b/pkg/runner/testdata/uses-action-with-pre-and-post-step/push.yml new file mode 100644 index 00000000000..0c3b793340e --- /dev/null +++ b/pkg/runner/testdata/uses-action-with-pre-and-post-step/push.yml @@ -0,0 +1,15 @@ +name: uses-action-with-pre-and-post-step +on: push + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - uses: ./uses-action-with-pre-and-post-step/last-action + - uses: nektos/act-test-actions/js-with-pre-and-post-step@main + with: + pre: true + post: true + - run: | + cat $GITHUB_ENV