pkg/runner/sequence_of_steps.go (71 lines of code) (raw):

package runner import ( ctx "context" "fmt" "google.golang.org/protobuf/types/known/structpb" "gitlab.com/gitlab-org/step-runner/pkg/internal/expression" "gitlab.com/gitlab-org/step-runner/proto" ) // SequenceOfSteps is a step that executes many steps. type SequenceOfSteps struct { loadedFrom StepReference params *Params specDef *SpecDefinition steps []Step } func NewSequenceOfSteps(loadedFrom StepReference, params *Params, specDef *SpecDefinition, steps ...Step) *SequenceOfSteps { return &SequenceOfSteps{ loadedFrom: loadedFrom, params: params, steps: steps, specDef: specDef, } } func (s *SequenceOfSteps) Describe() string { if len(s.steps) < 2 { return "sequence of steps" } return fmt.Sprintf("sequence of %d steps", len(s.steps)) } func (s *SequenceOfSteps) Run(ctx ctx.Context, stepsCtx *StepsContext) (*proto.StepResult, error) { result := NewStepResultBuilder(s.loadedFrom, s.params, s.specDef) if err := result.ObserveEnv(stepsCtx.ExpandAndApplyEnv(s.specDef.Env())); err != nil { return result.BuildFailure(), fmt.Errorf("expand step env: %w", err) } for _, step := range s.steps { stepResult, err := result.ObserveStepResult(step.Run(ctx, stepsCtx)) stepsCtx.RecordResult(stepResult) if err != nil { return result.BuildFailure(), err // expose underlying step error (no need to wrap) } } if err := result.ObserveOutputs(s.readOutputs(stepsCtx, stepsCtx.StepResults())); err != nil { return result.BuildFailure(), fmt.Errorf("outputs: %w", err) } return result.Build(), nil } func (s *SequenceOfSteps) readOutputs(stepsCtx *StepsContext, stepResults []*proto.StepResult) (map[string]*structpb.Value, error) { if s.specDef.IsDelegateOutputs() { return findOutputsWithName(s.specDef.DelegateTo(), stepResults) } return s.interpolateStepOutputs(stepsCtx) } func (s *SequenceOfSteps) interpolateStepOutputs(stepsCtx *StepsContext) (map[string]*structpb.Value, error) { outputs := make(map[string]*structpb.Value) for k, v := range s.specDef.DefinitionOutputs() { res, err := expression.Expand(stepsCtx.View(), v) if err == nil { outputs[k] = res.Value } else { return nil, fmt.Errorf("expand %q: %w", k, err) } } return outputs, nil } func findOutputsWithName(name string, results []*proto.StepResult) (map[string]*structpb.Value, error) { for _, s := range results { if s.Step != nil && s.Step.Name == name { return s.Outputs, nil } } return nil, fmt.Errorf("delegate: could not find step with name %q", name) }