act/pkg/runner/step_action_local.go
Markus Wolf 679cac1677
Fix composite input handling (#1345)
* test: add test case for #1319

* fix: setup of composite inputs

This change fixes the composite action setup handling of inputs.

All inputs are taken from the env now. The env is composed of
the 'level above'.
For example:
- step env -> taken from run context
- action env -> taken from step env
- composite env -> taken from action env

Before this change the env setup for steps, actions and composite
run contexts was harder to understand as all parts looked into
one of these: parent run context, step, action, composite run context.

Now the 'data flow' is from higher levels to lower levels which should
make it more clean.

Fixes #1319

* test: add simple remote composite action test

Since we don't have a remote composite test at all
before this, we need at least the simplest case.
This does not check every feature, but ensures basic
availability of remote composite actions.

* refactor: move ActionRef and ActionRepository

Moving ActionRef and ActionRepository from RunContext into the
step, allows us to remove the - more or less - ugly copy operations
from the RunContext.

This is more clean, as each step does hold the data required anyway
and the RunContext shouldn't know about the action details.

* refactor: remove unused properties
2022-10-06 21:58:16 +00:00

115 lines
3 KiB
Go

package runner
import (
"archive/tar"
"context"
"io"
"os"
"path"
"path/filepath"
"github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/model"
)
type stepActionLocal struct {
Step *model.Step
RunContext *RunContext
compositeRunContext *RunContext
compositeSteps *compositeSteps
runAction runAction
readAction readAction
env map[string]string
action *model.Action
}
func (sal *stepActionLocal) pre() common.Executor {
sal.env = map[string]string{}
return func(ctx context.Context) error {
return nil
}
}
func (sal *stepActionLocal) main() common.Executor {
return runStepExecutor(sal, stepStageMain, func(ctx context.Context) error {
if common.Dryrun(ctx) {
return nil
}
actionDir := filepath.Join(sal.getRunContext().Config.Workdir, sal.Step.Uses)
localReader := func(ctx context.Context) actionYamlReader {
_, cpath := getContainerActionPaths(sal.Step, path.Join(actionDir, ""), sal.RunContext)
return func(filename string) (io.Reader, io.Closer, error) {
tars, err := sal.RunContext.JobContainer.GetContainerArchive(ctx, path.Join(cpath, filename))
if err != nil {
return nil, nil, os.ErrNotExist
}
treader := tar.NewReader(tars)
if _, err := treader.Next(); err != nil {
return nil, nil, os.ErrNotExist
}
return treader, tars, nil
}
}
actionModel, err := sal.readAction(ctx, sal.Step, actionDir, "", localReader(ctx), os.WriteFile)
if err != nil {
return err
}
sal.action = actionModel
return sal.runAction(sal, actionDir, nil)(ctx)
})
}
func (sal *stepActionLocal) post() common.Executor {
return runStepExecutor(sal, stepStagePost, runPostStep(sal)).If(hasPostStep(sal)).If(shouldRunPostStep(sal))
}
func (sal *stepActionLocal) getRunContext() *RunContext {
return sal.RunContext
}
func (sal *stepActionLocal) getGithubContext(ctx context.Context) *model.GithubContext {
return sal.getRunContext().getGithubContext(ctx)
}
func (sal *stepActionLocal) getStepModel() *model.Step {
return sal.Step
}
func (sal *stepActionLocal) getEnv() *map[string]string {
return &sal.env
}
func (sal *stepActionLocal) getIfExpression(context context.Context, stage stepStage) string {
switch stage {
case stepStageMain:
return sal.Step.If.Value
case stepStagePost:
return sal.action.Runs.PostIf
}
return ""
}
func (sal *stepActionLocal) getActionModel() *model.Action {
return sal.action
}
func (sal *stepActionLocal) getCompositeRunContext(ctx context.Context) *RunContext {
if sal.compositeRunContext == nil {
actionDir := filepath.Join(sal.RunContext.Config.Workdir, sal.Step.Uses)
_, containerActionDir := getContainerActionPaths(sal.getStepModel(), actionDir, sal.RunContext)
sal.compositeRunContext = newCompositeRunContext(ctx, sal.RunContext, sal, containerActionDir)
sal.compositeSteps = sal.compositeRunContext.compositeExecutor(sal.action)
}
return sal.compositeRunContext
}
func (sal *stepActionLocal) getCompositeSteps() *compositeSteps {
return sal.compositeSteps
}