You've already forked woodpecker
mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-06-03 16:35:37 +02:00
pipeline: use more explizite error for step dependencies filtered out by its conditions (#6680)
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
package compiler
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"maps"
|
||||
"path"
|
||||
@@ -221,6 +222,11 @@ func (c *Compiler) Compile(conf *yaml_types.Workflow) (*backend_types.Config, er
|
||||
}
|
||||
|
||||
// add pipeline steps
|
||||
stepNames := make(map[string]struct{}, len(conf.Steps.ContainerList))
|
||||
for _, container := range conf.Steps.ContainerList {
|
||||
stepNames[container.Name] = struct{}{}
|
||||
}
|
||||
|
||||
steps := make([]*dagCompilerStep, 0, len(conf.Steps.ContainerList))
|
||||
for pos, container := range conf.Steps.ContainerList {
|
||||
// Skip if local and should not run local
|
||||
@@ -259,6 +265,15 @@ func (c *Compiler) Compile(conf *yaml_types.Workflow) (*backend_types.Config, er
|
||||
// generate stages out of steps
|
||||
stepStages, err := newDAGCompiler(steps).compile()
|
||||
if err != nil {
|
||||
// If the missing dep exists in the config but isn't in the surviving
|
||||
// step list, it was filtered out by its 'when' conditions. Surface a
|
||||
// more actionable error.
|
||||
var missingDepErr *ErrStepMissingDependency
|
||||
if errors.As(err, &missingDepErr) {
|
||||
if _, inConfig := stepNames[missingDepErr.dep]; inConfig {
|
||||
return nil, &ErrStepFilteredDependency{name: missingDepErr.name, dep: missingDepErr.dep}
|
||||
}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
@@ -298,6 +298,25 @@ func TestCompilerCompile(t *testing.T) {
|
||||
backConf: nil,
|
||||
expectedErr: "step 'dummy' depends on unknown step 'not exist'",
|
||||
},
|
||||
{
|
||||
name: "workflow with step depending on filtered-out step",
|
||||
fronConf: &yaml_types.Workflow{Steps: yaml_types.ContainerList{ContainerList: []*yaml_types.Container{
|
||||
{
|
||||
Name: "build",
|
||||
Image: "bash",
|
||||
When: constraint.When{Constraints: []constraint.Constraint{{
|
||||
Event: yaml_base_types.StringOrSlice{"tag"},
|
||||
}}},
|
||||
},
|
||||
{
|
||||
Name: "deploy",
|
||||
Image: "bash",
|
||||
DependsOn: constraint.DependsOn{{Name: "build"}},
|
||||
},
|
||||
}}},
|
||||
backConf: nil,
|
||||
expectedErr: "step 'deploy' depends on step 'build' which is filtered out by its conditions",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
||||
@@ -43,6 +43,20 @@ func (*ErrStepMissingDependency) Is(target error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
type ErrStepFilteredDependency struct {
|
||||
name,
|
||||
dep string
|
||||
}
|
||||
|
||||
func (err *ErrStepFilteredDependency) Error() string {
|
||||
return fmt.Sprintf("step '%s' depends on step '%s' which is filtered out by its conditions", err.name, err.dep)
|
||||
}
|
||||
|
||||
func (*ErrStepFilteredDependency) Is(target error) bool {
|
||||
_, ok := target.(*ErrStepFilteredDependency)
|
||||
return ok
|
||||
}
|
||||
|
||||
type ErrStepDependencyCycle struct {
|
||||
path []string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user