act/pkg/runner/job_executor.go
Björn Brauer 9abc87b416
fix: always execute closeContainer() executor (#988)
* fix: always execute closeContainer() executor

During our earlier refactoring in #984 we accidentally changed the
behaviour in such a way that the `closeContainer()` executor was never
called.

This commit restores the earlier behaviour.

Ref:
* https://github.com/nektos/act/pull/984/files#diff-c057d66dc9657d8428e290c69871596e2b567bb8fecad62a99cab54398131a84L294
* https://github.com/nektos/act/pull/984/files#diff-ea9d5c93d769ef9b268932dd9990363e97fc3bec8a00114979d049bead5dd718R68

* test: add testcases to ensure job containers are started/stopped

This commit adds tests to ensure that the executors of `startContainer`,
`stopContainer`, `interpolateOutputs` and `closeContainer` are always
called in the correct order.
2022-02-10 16:54:58 +00:00

69 lines
1.5 KiB
Go

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(info.closeContainer())
}