From 237ac81df496df552c0d629ecb0e9fff3b8b69d2 Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Fri, 25 Oct 2024 10:56:03 -0400 Subject: [PATCH] feat: add sender rule for pipelines (#1206) * refactor(pipeline): use server API types for pipeline and migrate compiler types * gci * feat: add sender rule for pipelines --------- Co-authored-by: David May <49894298+wass3rw3rk@users.noreply.github.com> --- api/pipeline/compile.go | 28 +++++-- api/pipeline/compile_test.go | 38 +++++---- compiler/native/compile.go | 1 + compiler/types/pipeline/ruleset.go | 12 ++- compiler/types/pipeline/ruleset_test.go | 5 ++ compiler/types/yaml/ruleset.go | 5 ++ compiler/types/yaml/ruleset_test.go | 82 +++++++++++-------- .../types/yaml/testdata/ruleset_simple.yml | 3 + 8 files changed, 114 insertions(+), 60 deletions(-) diff --git a/api/pipeline/compile.go b/api/pipeline/compile.go index f21f0a811..23f997fcc 100644 --- a/api/pipeline/compile.go +++ b/api/pipeline/compile.go @@ -119,8 +119,14 @@ func prepareRuleData(c *gin.Context) *pipeline.RuleData { comment := c.Query("comment") // capture the event type parameter event := c.Query("event") + // capture the instance parameter + instance := c.Query("instance") + // capture the label parameter + labelSet := c.QueryArray("label") // capture the repo parameter ruleDataRepo := c.Query("repo") + // capture the sender parameter + sender := c.Query("sender") // capture the status type parameter status := c.Query("status") // capture the tag parameter @@ -134,20 +140,26 @@ func prepareRuleData(c *gin.Context) *pipeline.RuleData { if len(branch) > 0 || len(comment) > 0 || len(event) > 0 || + len(instance) > 0 || + len(labelSet) > 0 || len(pathSet) > 0 || len(ruleDataRepo) > 0 || + len(sender) > 0 || len(status) > 0 || len(tag) > 0 || len(target) > 0 { return &pipeline.RuleData{ - Branch: branch, - Comment: comment, - Event: event, - Path: pathSet, - Repo: ruleDataRepo, - Status: status, - Tag: tag, - Target: target, + Branch: branch, + Comment: comment, + Event: event, + Instance: instance, + Label: labelSet, + Path: pathSet, + Repo: ruleDataRepo, + Sender: sender, + Status: status, + Tag: tag, + Target: target, } } diff --git a/api/pipeline/compile_test.go b/api/pipeline/compile_test.go index 05a3de45d..877bed8c7 100644 --- a/api/pipeline/compile_test.go +++ b/api/pipeline/compile_test.go @@ -26,24 +26,30 @@ func TestPrepareRuleData(t *testing.T) { { name: "all params provided", parameters: map[string]string{ - "branch": "main", - "comment": "Test comment", - "event": "push", - "repo": "my-repo", - "status": "success", - "tag": "v1.0.0", - "target": "production", - "path": "README.md", + "branch": "main", + "comment": "Test comment", + "event": "push", + "instance": "vela-server", + "label": "bug", + "repo": "my-repo", + "sender": "octocat", + "status": "success", + "tag": "v1.0.0", + "target": "production", + "path": "README.md", }, want: &pipeline.RuleData{ - Branch: "main", - Comment: "Test comment", - Event: "push", - Repo: "my-repo", - Status: "success", - Tag: "v1.0.0", - Target: "production", - Path: []string{"README.md"}, + Branch: "main", + Comment: "Test comment", + Event: "push", + Instance: "vela-server", + Label: []string{"bug"}, + Repo: "my-repo", + Sender: "octocat", + Status: "success", + Tag: "v1.0.0", + Target: "production", + Path: []string{"README.md"}, }, }, { diff --git a/compiler/native/compile.go b/compiler/native/compile.go index e39d43718..49d071431 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -67,6 +67,7 @@ func (c *client) Compile(ctx context.Context, v interface{}) (*pipeline.Build, * Event: event, Path: c.files, Repo: c.repo.GetFullName(), + Sender: c.build.GetSender(), Tag: strings.TrimPrefix(c.build.GetRef(), "refs/tags/"), Target: c.build.GetDeploy(), Label: c.labels, diff --git a/compiler/types/pipeline/ruleset.go b/compiler/types/pipeline/ruleset.go index a6e5101f6..36d6c1302 100644 --- a/compiler/types/pipeline/ruleset.go +++ b/compiler/types/pipeline/ruleset.go @@ -34,6 +34,7 @@ type ( 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"` @@ -56,6 +57,7 @@ type ( 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"` @@ -113,6 +115,7 @@ func (r *Rules) Empty() bool { len(r.Event) == 0 && len(r.Path) == 0 && len(r.Repo) == 0 && + len(r.Sender) == 0 && len(r.Status) == 0 && len(r.Tag) == 0 && len(r.Target) == 0 && @@ -168,6 +171,11 @@ func (r *Rules) Match(from *RuleData, matcher, op string) (bool, error) { return false, err } + matchSender, err := r.Sender.MatchSingle(from.Sender, matcher, op) + if err != nil { + return false, err + } + matchTag, err := r.Tag.MatchSingle(from.Tag, matcher, op) if err != nil { return false, err @@ -190,9 +198,9 @@ func (r *Rules) Match(from *RuleData, matcher, op string) (bool, error) { switch op { case constants.OperatorOr: - return (matchBranch || matchComment || matchEvent || matchPath || matchRepo || matchTag || matchTarget || matchLabel || matchInstance || status), nil + return (matchBranch || matchComment || matchEvent || matchPath || matchRepo || matchSender || matchTag || matchTarget || matchLabel || matchInstance || status), nil default: - return (matchBranch && matchComment && matchEvent && matchPath && matchRepo && matchTag && matchTarget && matchLabel && matchInstance && status), nil + return (matchBranch && matchComment && matchEvent && matchPath && matchRepo && matchSender && matchTag && matchTarget && matchLabel && matchInstance && status), nil } } diff --git a/compiler/types/pipeline/ruleset_test.go b/compiler/types/pipeline/ruleset_test.go index d6618d444..5f9bf7bc2 100644 --- a/compiler/types/pipeline/ruleset_test.go +++ b/compiler/types/pipeline/ruleset_test.go @@ -79,6 +79,11 @@ func TestPipeline_Ruleset_Match(t *testing.T) { data: &RuleData{Branch: "dev", Comment: "ok to test", Event: "push", Repo: "octocat/hello-world", Status: "failure", Tag: "refs/heads/main", Target: ""}, want: true, }, + { + ruleset: &Ruleset{If: Rules{Sender: []string{"octocat"}}, Operator: "and"}, + data: &RuleData{Branch: "dev", Comment: "ok to test", Event: "push", Repo: "octocat/hello-world", Sender: "octocat", Status: "pending", Tag: "refs/heads/main", Target: ""}, + want: true, + }, // If with or operator { ruleset: &Ruleset{If: Rules{Branch: []string{"main"}, Event: []string{"push"}}, Operator: "or"}, diff --git a/compiler/types/yaml/ruleset.go b/compiler/types/yaml/ruleset.go index 348f6315b..ee3c014e3 100644 --- a/compiler/types/yaml/ruleset.go +++ b/compiler/types/yaml/ruleset.go @@ -27,6 +27,7 @@ type ( 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"` @@ -83,6 +84,7 @@ func (r *Ruleset) UnmarshalYAML(unmarshal func(interface{}) error) error { advanced.If.Event = append(advanced.If.Event, simple.Event...) advanced.If.Path = append(advanced.If.Path, simple.Path...) 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.Tag = append(advanced.If.Tag, simple.Tag...) advanced.If.Target = append(advanced.If.Target, simple.Target...) @@ -114,6 +116,7 @@ func (r *Rules) ToPipeline() *pipeline.Rules { Event: r.Event, Path: r.Path, Repo: r.Repo, + Sender: r.Sender, Status: r.Status, Tag: r.Tag, Target: r.Target, @@ -131,6 +134,7 @@ func (r *Rules) UnmarshalYAML(unmarshal func(interface{}) error) error { Event raw.StringSlice Path raw.StringSlice Repo raw.StringSlice + Sender raw.StringSlice Status raw.StringSlice Tag raw.StringSlice Target raw.StringSlice @@ -145,6 +149,7 @@ func (r *Rules) UnmarshalYAML(unmarshal func(interface{}) error) error { r.Comment = rules.Comment r.Path = rules.Path r.Repo = rules.Repo + r.Sender = rules.Sender r.Status = rules.Status r.Tag = rules.Tag r.Target = rules.Target diff --git a/compiler/types/yaml/ruleset_test.go b/compiler/types/yaml/ruleset_test.go index d1f559daa..6275046b0 100644 --- a/compiler/types/yaml/ruleset_test.go +++ b/compiler/types/yaml/ruleset_test.go @@ -26,6 +26,7 @@ func TestYaml_Ruleset_ToPipeline(t *testing.T) { Event: []string{"push", "pull_request:labeled"}, Path: []string{"foo.txt"}, Repo: []string{"github/octocat"}, + Sender: []string{"octocat"}, Status: []string{"success"}, Tag: []string{"v0.1.0"}, Target: []string{"production"}, @@ -38,6 +39,7 @@ func TestYaml_Ruleset_ToPipeline(t *testing.T) { Event: []string{"pull_request"}, Path: []string{"bar.txt"}, Repo: []string{"github/octocat"}, + Sender: []string{"octokitty"}, Status: []string{"failure"}, Tag: []string{"v0.2.0"}, Target: []string{"production"}, @@ -54,6 +56,7 @@ func TestYaml_Ruleset_ToPipeline(t *testing.T) { Event: []string{"push", "pull_request:labeled"}, Path: []string{"foo.txt"}, Repo: []string{"github/octocat"}, + Sender: []string{"octocat"}, Status: []string{"success"}, Tag: []string{"v0.1.0"}, Target: []string{"production"}, @@ -66,6 +69,7 @@ func TestYaml_Ruleset_ToPipeline(t *testing.T) { Event: []string{"pull_request"}, Path: []string{"bar.txt"}, Repo: []string{"github/octocat"}, + Sender: []string{"octokitty"}, Status: []string{"failure"}, Tag: []string{"v0.2.0"}, Target: []string{"production"}, @@ -98,14 +102,17 @@ 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"}, - Path: []string{"foo.txt"}, - Repo: []string{"github/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"}, + Tag: []string{"v0.1.0"}, + Target: []string{"production"}, }, Matcher: "filepath", Operator: "and", @@ -172,26 +179,30 @@ func TestYaml_Rules_ToPipeline(t *testing.T) { }{ { rules: &Rules{ - Branch: []string{"main"}, - Comment: []string{"test comment"}, - Event: []string{"push", "pull_request:labeled"}, - Path: []string{"foo.txt"}, - Repo: []string{"github/octocat"}, - Status: []string{"success"}, - Tag: []string{"v0.1.0"}, - Target: []string{"production"}, - Label: []string{"enhancement"}, + Branch: []string{"main"}, + Comment: []string{"test comment"}, + Event: []string{"push", "pull_request:labeled"}, + Instance: []string{"vela-server"}, + Path: []string{"foo.txt"}, + Repo: []string{"github/octocat"}, + Sender: []string{"octocat"}, + Status: []string{"success"}, + Tag: []string{"v0.1.0"}, + Target: []string{"production"}, + Label: []string{"enhancement"}, }, want: &pipeline.Rules{ - Branch: []string{"main"}, - Comment: []string{"test comment"}, - Event: []string{"push", "pull_request:labeled"}, - Path: []string{"foo.txt"}, - Repo: []string{"github/octocat"}, - Status: []string{"success"}, - Tag: []string{"v0.1.0"}, - Target: []string{"production"}, - Label: []string{"enhancement"}, + Branch: []string{"main"}, + Comment: []string{"test comment"}, + Event: []string{"push", "pull_request:labeled"}, + Instance: []string{"vela-server"}, + Path: []string{"foo.txt"}, + Repo: []string{"github/octocat"}, + Sender: []string{"octocat"}, + Status: []string{"success"}, + Tag: []string{"v0.1.0"}, + Target: []string{"production"}, + Label: []string{"enhancement"}, }, }, } @@ -223,14 +234,17 @@ 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"}, - Path: []string{"foo.txt"}, - Repo: []string{"github/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"}, + Tag: []string{"v0.1.0"}, + Target: []string{"production"}, }, }, { diff --git a/compiler/types/yaml/testdata/ruleset_simple.yml b/compiler/types/yaml/testdata/ruleset_simple.yml index 7696e49b1..acbe4e198 100644 --- a/compiler/types/yaml/testdata/ruleset_simple.yml +++ b/compiler/types/yaml/testdata/ruleset_simple.yml @@ -3,8 +3,11 @@ branch: main comment: "test comment" continue: true event: push +instance: vela-server +label: bug path: foo.txt repo: github/octocat +sender: octocat status: success tag: v0.1.0 target: production