refactor: extract RunContext Executor in JobExecutor (#984)

This splits the executor from the RunContext into its own function
called newJobExecutor.
We defined an interface called jobInfo which is implemented by the RunContext.
This enables better unit testing because only a small interface needs to
be mocked.

This is a preparation for implementing pre and post actions.

Co-authored-by: Björn Brauer <bjoern.brauer@new-work.se>
Co-authored-by: Marcus Noll <marcus.noll@new-work.se>
Co-authored-by: Jonas Holland <jonas.holland@new-work.se>
Co-authored-by: Robert Kowalski <robert.kowalski@new-work.se>
Co-authored-by: Markus Wolf <markus.wolf@new-work.se>

Co-authored-by: Björn Brauer <bjoern.brauer@new-work.se>
Co-authored-by: Marcus Noll <marcus.noll@new-work.se>
Co-authored-by: Jonas Holland <jonas.holland@new-work.se>
Co-authored-by: Robert Kowalski <robert.kowalski@new-work.se>
Co-authored-by: Markus Wolf <markus.wolf@new-work.se>
This commit is contained in:
Philipp Hinrichsen
2022-02-08 18:22:41 +01:00
committed by GitHub
parent b1f5963c86
commit e23223ad02
4 changed files with 233 additions and 45 deletions

View File

@@ -0,0 +1,71 @@
package runner
import (
"context"
"fmt"
"github.com/nektos/act/pkg/common"
"github.com/nektos/act/pkg/model"
)
type jobInfo interface {
matrix() map[string]interface{}
steps() []*model.Step
startContainer() common.Executor
stopContainer() common.Executor
closeContainer() common.Executor
newStepExecutor(step *model.Step) common.Executor
interpolateOutputs() common.Executor
result(result string)
}
func newJobExecutor(info jobInfo) common.Executor {
steps := make([]common.Executor, 0)
steps = append(steps, func(ctx context.Context) error {
if len(info.matrix()) > 0 {
common.Logger(ctx).Infof("\U0001F9EA Matrix: %v", info.matrix())
}
return nil
})
steps = append(steps, info.startContainer())
for i, step := range info.steps() {
if step.ID == "" {
step.ID = fmt.Sprintf("%d", i)
}
stepExec := info.newStepExecutor(step)
steps = append(steps, func(ctx context.Context) error {
err := stepExec(ctx)
if err != nil {
common.Logger(ctx).Errorf("%v", err)
common.SetJobError(ctx, err)
} else if ctx.Err() != nil {
common.Logger(ctx).Errorf("%v", ctx.Err())
common.SetJobError(ctx, ctx.Err())
}
return nil
})
}
steps = append(steps, func(ctx context.Context) error {
err := info.stopContainer()(ctx)
if err != nil {
return err
}
jobError := common.JobError(ctx)
if jobError != nil {
info.result("failure")
} else {
info.result("success")
}
return nil
})
return common.NewPipelineExecutor(steps...).Finally(info.interpolateOutputs()).Finally(func(ctx context.Context) error {
info.closeContainer()
return nil
})
}