146 lines
3.6 KiB
Go
146 lines
3.6 KiB
Go
|
package runner
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/nektos/act/pkg/common"
|
||
|
"github.com/nektos/act/pkg/model"
|
||
|
log "github.com/sirupsen/logrus"
|
||
|
)
|
||
|
|
||
|
type step interface {
|
||
|
pre() common.Executor
|
||
|
main() common.Executor
|
||
|
post() common.Executor
|
||
|
|
||
|
getRunContext() *RunContext
|
||
|
getStepModel() *model.Step
|
||
|
getEnv() *map[string]string
|
||
|
}
|
||
|
|
||
|
func runStepExecutor(step step, executor common.Executor) common.Executor {
|
||
|
return func(ctx context.Context) error {
|
||
|
rc := step.getRunContext()
|
||
|
stepModel := step.getStepModel()
|
||
|
|
||
|
rc.CurrentStep = stepModel.ID
|
||
|
rc.StepResults[rc.CurrentStep] = &model.StepResult{
|
||
|
Outcome: model.StepStatusSuccess,
|
||
|
Conclusion: model.StepStatusSuccess,
|
||
|
Outputs: make(map[string]string),
|
||
|
}
|
||
|
|
||
|
err := setupEnv(ctx, step)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
runStep, err := isStepEnabled(ctx, step)
|
||
|
if err != nil {
|
||
|
rc.StepResults[rc.CurrentStep].Conclusion = model.StepStatusFailure
|
||
|
rc.StepResults[rc.CurrentStep].Outcome = model.StepStatusFailure
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if !runStep {
|
||
|
log.Debugf("Skipping step '%s' due to '%s'", stepModel.String(), stepModel.If.Value)
|
||
|
rc.StepResults[rc.CurrentStep].Conclusion = model.StepStatusSkipped
|
||
|
rc.StepResults[rc.CurrentStep].Outcome = model.StepStatusSkipped
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
common.Logger(ctx).Infof("\u2B50 Run %s", stepModel)
|
||
|
|
||
|
err = executor(ctx)
|
||
|
|
||
|
if err == nil {
|
||
|
common.Logger(ctx).Infof(" \u2705 Success - %s", stepModel)
|
||
|
} else {
|
||
|
common.Logger(ctx).Errorf(" \u274C Failure - %s", stepModel)
|
||
|
|
||
|
rc.StepResults[rc.CurrentStep].Outcome = model.StepStatusFailure
|
||
|
if stepModel.ContinueOnError {
|
||
|
common.Logger(ctx).Infof("Failed but continue next step")
|
||
|
err = nil
|
||
|
rc.StepResults[rc.CurrentStep].Conclusion = model.StepStatusSuccess
|
||
|
} else {
|
||
|
rc.StepResults[rc.CurrentStep].Conclusion = model.StepStatusFailure
|
||
|
}
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func setupEnv(ctx context.Context, step step) error {
|
||
|
rc := step.getRunContext()
|
||
|
|
||
|
mergeEnv(step)
|
||
|
err := rc.JobContainer.UpdateFromImageEnv(step.getEnv())(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
err = rc.JobContainer.UpdateFromEnv((*step.getEnv())["GITHUB_ENV"], step.getEnv())(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
err = rc.JobContainer.UpdateFromPath(step.getEnv())(ctx)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
mergeIntoMap(step.getEnv(), step.getStepModel().GetEnv()) // step env should not be overwritten
|
||
|
|
||
|
exprEval := rc.NewStepExpressionEvaluator(step)
|
||
|
for k, v := range *step.getEnv() {
|
||
|
(*step.getEnv())[k] = exprEval.Interpolate(v)
|
||
|
}
|
||
|
|
||
|
common.Logger(ctx).Debugf("setupEnv => %v", *step.getEnv())
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func mergeEnv(step step) {
|
||
|
env := step.getEnv()
|
||
|
rc := step.getRunContext()
|
||
|
job := rc.Run.Job()
|
||
|
|
||
|
c := job.Container()
|
||
|
if c != nil {
|
||
|
mergeIntoMap(env, rc.GetEnv(), c.Env)
|
||
|
} else {
|
||
|
mergeIntoMap(env, rc.GetEnv())
|
||
|
}
|
||
|
|
||
|
if (*env)["PATH"] == "" {
|
||
|
(*env)["PATH"] = `/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin`
|
||
|
}
|
||
|
if rc.ExtraPath != nil && len(rc.ExtraPath) > 0 {
|
||
|
p := (*env)["PATH"]
|
||
|
(*env)["PATH"] = strings.Join(rc.ExtraPath, `:`)
|
||
|
(*env)["PATH"] += `:` + p
|
||
|
}
|
||
|
|
||
|
mergeIntoMap(env, rc.withGithubEnv(*env))
|
||
|
}
|
||
|
|
||
|
func isStepEnabled(ctx context.Context, step step) (bool, error) {
|
||
|
rc := step.getRunContext()
|
||
|
|
||
|
runStep, err := EvalBool(rc.NewStepExpressionEvaluator(step), step.getStepModel().If.Value)
|
||
|
if err != nil {
|
||
|
return false, fmt.Errorf(" \u274C Error in if-expression: \"if: %s\" (%s)", step.getStepModel().If.Value, err)
|
||
|
}
|
||
|
|
||
|
return runStep, nil
|
||
|
}
|
||
|
|
||
|
func mergeIntoMap(target *map[string]string, maps ...map[string]string) {
|
||
|
for _, m := range maps {
|
||
|
for k, v := range m {
|
||
|
(*target)[k] = v
|
||
|
}
|
||
|
}
|
||
|
}
|