Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

enhance(ruleset): add stage status rule for independent stages #1215

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 37 additions & 25 deletions compiler/types/pipeline/ruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,18 +29,19 @@ type (
//
// swagger:model PipelineRules
Rules struct {
Branch Ruletype `json:"branch,omitempty" yaml:"branch,omitempty"`
Comment Ruletype `json:"comment,omitempty" yaml:"comment,omitempty"`
Event Ruletype `json:"event,omitempty" yaml:"event,omitempty"`
Path Ruletype `json:"path,omitempty" yaml:"path,omitempty"`
Repo Ruletype `json:"repo,omitempty" yaml:"repo,omitempty"`
Sender Ruletype `json:"sender,omitempty" yaml:"sender,omitempty"`
Status Ruletype `json:"status,omitempty" yaml:"status,omitempty"`
Tag Ruletype `json:"tag,omitempty" yaml:"tag,omitempty"`
Target Ruletype `json:"target,omitempty" yaml:"target,omitempty"`
Label Ruletype `json:"label,omitempty" yaml:"label,omitempty"`
Instance Ruletype `json:"instance,omitempty" yaml:"instance,omitempty"`
Parallel bool `json:"-" yaml:"-"`
Branch Ruletype `json:"branch,omitempty" yaml:"branch,omitempty"`
Comment Ruletype `json:"comment,omitempty" yaml:"comment,omitempty"`
Event Ruletype `json:"event,omitempty" yaml:"event,omitempty"`
Path Ruletype `json:"path,omitempty" yaml:"path,omitempty"`
Repo Ruletype `json:"repo,omitempty" yaml:"repo,omitempty"`
Sender Ruletype `json:"sender,omitempty" yaml:"sender,omitempty"`
Status Ruletype `json:"status,omitempty" yaml:"status,omitempty"`
StageStatus Ruletype `json:"stage_status,omitempty" yaml:"stage_status,omitempty"`
Tag Ruletype `json:"tag,omitempty" yaml:"tag,omitempty"`
Target Ruletype `json:"target,omitempty" yaml:"target,omitempty"`
Label Ruletype `json:"label,omitempty" yaml:"label,omitempty"`
Instance Ruletype `json:"instance,omitempty" yaml:"instance,omitempty"`
Parallel bool `json:"-" yaml:"-"`
}

// Ruletype is the pipeline representation of an element
Expand All @@ -52,18 +53,19 @@ type (
// RuleData is the data to check our ruleset
// against for a step in a pipeline.
RuleData struct {
Branch string `json:"branch,omitempty" yaml:"branch,omitempty"`
Comment string `json:"comment,omitempty" yaml:"comment,omitempty"`
Event string `json:"event,omitempty" yaml:"event,omitempty"`
Path []string `json:"path,omitempty" yaml:"path,omitempty"`
Repo string `json:"repo,omitempty" yaml:"repo,omitempty"`
Sender string `json:"sender,omitempty" yaml:"sender,omitempty"`
Status string `json:"status,omitempty" yaml:"status,omitempty"`
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
Target string `json:"target,omitempty" yaml:"target,omitempty"`
Label []string `json:"label,omitempty" yaml:"label,omitempty"`
Instance string `json:"instance,omitempty" yaml:"instance,omitempty"`
Parallel bool `json:"-" yaml:"-"`
Branch string `json:"branch,omitempty" yaml:"branch,omitempty"`
Comment string `json:"comment,omitempty" yaml:"comment,omitempty"`
Event string `json:"event,omitempty" yaml:"event,omitempty"`
Path []string `json:"path,omitempty" yaml:"path,omitempty"`
Repo string `json:"repo,omitempty" yaml:"repo,omitempty"`
Sender string `json:"sender,omitempty" yaml:"sender,omitempty"`
Status string `json:"status,omitempty" yaml:"status,omitempty"`
StageStatus string `json:"stage_status,omitempty" yaml:"stage_status,omitempty"`
Tag string `json:"tag,omitempty" yaml:"tag,omitempty"`
Target string `json:"target,omitempty" yaml:"target,omitempty"`
Label []string `json:"label,omitempty" yaml:"label,omitempty"`
Instance string `json:"instance,omitempty" yaml:"instance,omitempty"`
Parallel bool `json:"-" yaml:"-"`
}
)

Expand Down Expand Up @@ -104,7 +106,7 @@ func (r *Ruleset) Match(from *RuleData) (bool, error) {
// NoStatus returns true if the status field is empty.
func (r *Rules) NoStatus() bool {
// return true if every ruletype is empty
return len(r.Status) == 0
return len(r.Status) == 0 && len(r.StageStatus) == 0
}

// Empty returns true if the provided ruletypes are empty.
Expand All @@ -117,6 +119,7 @@ func (r *Rules) Empty() bool {
len(r.Repo) == 0 &&
len(r.Sender) == 0 &&
len(r.Status) == 0 &&
len(r.StageStatus) == 0 &&
len(r.Tag) == 0 &&
len(r.Target) == 0 &&
len(r.Label) == 0 &&
Expand All @@ -134,6 +137,8 @@ func (r *Rules) Empty() bool {
// ruletypes from the rules match the provided ruledata. For
// both operators, when none of the ruletypes from the rules
// match the provided ruledata, the function returns false.
//
//nolint:gocyclo // this is going to be complex
func (r *Rules) Match(from *RuleData, matcher, op string) (bool, error) {
status := true

Expand All @@ -146,6 +151,13 @@ func (r *Rules) Match(from *RuleData, matcher, op string) (bool, error) {
}
}

if len(from.StageStatus) != 0 {
status, err = r.StageStatus.MatchSingle(from.StageStatus, matcher, op)
if err != nil {
return false, err
}
}

matchBranch, err := r.Branch.MatchSingle(from.Branch, matcher, op)
if err != nil {
return false, err
Expand Down
71 changes: 38 additions & 33 deletions compiler/types/yaml/ruleset.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,18 @@ type (
// Rules is the yaml representation of the ruletypes
// from a ruleset block for a step in a pipeline.
Rules struct {
Branch []string `yaml:"branch,omitempty,flow" json:"branch,omitempty" jsonschema:"description=Limits the execution of a step to matching build branches.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Comment []string `yaml:"comment,omitempty,flow" json:"comment,omitempty" jsonschema:"description=Limits the execution of a step to matching a pull request comment.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Event []string `yaml:"event,omitempty,flow" json:"event,omitempty" jsonschema:"description=Limits the execution of a step to matching build events.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Path []string `yaml:"path,omitempty,flow" json:"path,omitempty" jsonschema:"description=Limits the execution of a step to matching files changed in a repository.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Repo []string `yaml:"repo,omitempty,flow" json:"repo,omitempty" jsonschema:"description=Limits the execution of a step to matching repos.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Sender []string `yaml:"sender,omitempty,flow" json:"sender,omitempty" jsonschema:"description=Limits the execution of a step to matching build senders.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Status []string `yaml:"status,omitempty,flow" json:"status,omitempty" jsonschema:"enum=[failure],enum=[success],description=Limits the execution of a step to matching build statuses.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Tag []string `yaml:"tag,omitempty,flow" json:"tag,omitempty" jsonschema:"description=Limits the execution of a step to matching build tag references.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Target []string `yaml:"target,omitempty,flow" json:"target,omitempty" jsonschema:"description=Limits the execution of a step to matching build deployment targets.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Label []string `yaml:"label,omitempty,flow" json:"label,omitempty" jsonschema:"description=Limits step execution to match on pull requests labels.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Instance []string `yaml:"instance,omitempty,flow" json:"instance,omitempty" jsonschema:"description=Limits step execution to match on certain instances.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Branch []string `yaml:"branch,omitempty,flow" json:"branch,omitempty" jsonschema:"description=Limits the execution of a step to matching build branches.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Comment []string `yaml:"comment,omitempty,flow" json:"comment,omitempty" jsonschema:"description=Limits the execution of a step to matching a pull request comment.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Event []string `yaml:"event,omitempty,flow" json:"event,omitempty" jsonschema:"description=Limits the execution of a step to matching build events.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Path []string `yaml:"path,omitempty,flow" json:"path,omitempty" jsonschema:"description=Limits the execution of a step to matching files changed in a repository.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Repo []string `yaml:"repo,omitempty,flow" json:"repo,omitempty" jsonschema:"description=Limits the execution of a step to matching repos.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Sender []string `yaml:"sender,omitempty,flow" json:"sender,omitempty" jsonschema:"description=Limits the execution of a step to matching build senders.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Status []string `yaml:"status,omitempty,flow" json:"status,omitempty" jsonschema:"enum=[failure],enum=[success],description=Limits the execution of a step to matching build statuses.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
StageStatus []string `yaml:"stage_status,omitempty,flow" json:"stage_status,omitempty" jsonschema:"description=Limits the execution of a step to matching stage statuses.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Tag []string `yaml:"tag,omitempty,flow" json:"tag,omitempty" jsonschema:"description=Limits the execution of a step to matching build tag references.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Target []string `yaml:"target,omitempty,flow" json:"target,omitempty" jsonschema:"description=Limits the execution of a step to matching build deployment targets.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Label []string `yaml:"label,omitempty,flow" json:"label,omitempty" jsonschema:"description=Limits step execution to match on pull requests labels.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
Instance []string `yaml:"instance,omitempty,flow" json:"instance,omitempty" jsonschema:"description=Limits step execution to match on certain instances.\nReference: https://go-vela.github.io/docs/reference/yaml/steps/#the-ruleset-key"`
}
)

Expand Down Expand Up @@ -86,6 +87,7 @@ func (r *Ruleset) UnmarshalYAML(unmarshal func(interface{}) error) error {
advanced.If.Repo = append(advanced.If.Repo, simple.Repo...)
advanced.If.Sender = append(advanced.If.Sender, simple.Sender...)
advanced.If.Status = append(advanced.If.Status, simple.Status...)
advanced.If.StageStatus = append(advanced.If.StageStatus, simple.StageStatus...)
advanced.If.Tag = append(advanced.If.Tag, simple.Tag...)
advanced.If.Target = append(advanced.If.Target, simple.Target...)
advanced.If.Label = append(advanced.If.Label, simple.Label...)
Expand All @@ -111,35 +113,37 @@ func (r *Ruleset) UnmarshalYAML(unmarshal func(interface{}) error) error {
// type to a pipeline Rules type.
func (r *Rules) ToPipeline() *pipeline.Rules {
return &pipeline.Rules{
Branch: r.Branch,
Comment: r.Comment,
Event: r.Event,
Path: r.Path,
Repo: r.Repo,
Sender: r.Sender,
Status: r.Status,
Tag: r.Tag,
Target: r.Target,
Label: r.Label,
Instance: r.Instance,
Branch: r.Branch,
Comment: r.Comment,
Event: r.Event,
Path: r.Path,
Repo: r.Repo,
Sender: r.Sender,
Status: r.Status,
StageStatus: r.StageStatus,
Tag: r.Tag,
Target: r.Target,
Label: r.Label,
Instance: r.Instance,
}
}

// UnmarshalYAML implements the Unmarshaler interface for the Rules type.
func (r *Rules) UnmarshalYAML(unmarshal func(interface{}) error) error {
// rules struct we try unmarshalling to
rules := new(struct {
Branch raw.StringSlice
Comment raw.StringSlice
Event raw.StringSlice
Path raw.StringSlice
Repo raw.StringSlice
Sender raw.StringSlice
Status raw.StringSlice
Tag raw.StringSlice
Target raw.StringSlice
Label raw.StringSlice
Instance raw.StringSlice
Branch raw.StringSlice
Comment raw.StringSlice
Event raw.StringSlice
Path raw.StringSlice
Repo raw.StringSlice
Sender raw.StringSlice
Status raw.StringSlice
StageStatus raw.StringSlice `yaml:"stage_status"`
Tag raw.StringSlice
Target raw.StringSlice
Label raw.StringSlice
Instance raw.StringSlice
})

// attempt to unmarshal rules
Expand All @@ -151,6 +155,7 @@ func (r *Rules) UnmarshalYAML(unmarshal func(interface{}) error) error {
r.Repo = rules.Repo
r.Sender = rules.Sender
r.Status = rules.Status
r.StageStatus = rules.StageStatus
r.Tag = rules.Tag
r.Target = rules.Target
r.Label = rules.Label
Expand Down
46 changes: 24 additions & 22 deletions compiler/types/yaml/ruleset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,17 +102,18 @@ func TestYaml_Ruleset_UnmarshalYAML(t *testing.T) {
file: "testdata/ruleset_simple.yml",
want: &Ruleset{
If: Rules{
Branch: []string{"main"},
Comment: []string{"test comment"},
Event: []string{"push"},
Instance: []string{"vela-server"},
Label: []string{"bug"},
Path: []string{"foo.txt"},
Repo: []string{"github/octocat"},
Sender: []string{"octocat"},
Status: []string{"success"},
Tag: []string{"v0.1.0"},
Target: []string{"production"},
Branch: []string{"main"},
Comment: []string{"test comment"},
Event: []string{"push"},
Instance: []string{"vela-server"},
Label: []string{"bug"},
Path: []string{"foo.txt"},
Repo: []string{"github/octocat"},
Sender: []string{"octocat"},
Status: []string{"success"},
StageStatus: []string{"failure"},
Tag: []string{"v0.1.0"},
Target: []string{"production"},
},
Matcher: "filepath",
Operator: "and",
Expand Down Expand Up @@ -234,17 +235,18 @@ func TestYaml_Rules_UnmarshalYAML(t *testing.T) {
failure: false,
file: "testdata/ruleset_simple.yml",
want: &Rules{
Branch: []string{"main"},
Comment: []string{"test comment"},
Event: []string{"push"},
Instance: []string{"vela-server"},
Label: []string{"bug"},
Path: []string{"foo.txt"},
Repo: []string{"github/octocat"},
Sender: []string{"octocat"},
Status: []string{"success"},
Tag: []string{"v0.1.0"},
Target: []string{"production"},
Branch: []string{"main"},
Comment: []string{"test comment"},
Event: []string{"push"},
Instance: []string{"vela-server"},
Label: []string{"bug"},
Path: []string{"foo.txt"},
Repo: []string{"github/octocat"},
Sender: []string{"octocat"},
Status: []string{"success"},
StageStatus: []string{"failure"},
Tag: []string{"v0.1.0"},
Target: []string{"production"},
},
},
{
Expand Down
1 change: 1 addition & 0 deletions compiler/types/yaml/testdata/ruleset_simple.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ path: foo.txt
repo: github/octocat
sender: octocat
status: success
stage_status: failure
tag: v0.1.0
target: production
Loading