Skip to content

Commit

Permalink
enhance(compiler): add ruledata option to CompileLite (#1076)
Browse files Browse the repository at this point in the history
* enhance(compiler): add ruledata option to CompileLite

* remove template length check as it is unnecessary

* fix tests from latest merges to main

---------

Co-authored-by: Kelly Merrick <[email protected]>
  • Loading branch information
ecrupper and KellyMerrick committed Apr 5, 2024
1 parent f591935 commit 0d08fc3
Show file tree
Hide file tree
Showing 10 changed files with 674 additions and 196 deletions.
58 changes: 55 additions & 3 deletions api/pipeline/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ package pipeline
import (
"fmt"
"net/http"
"strings"

"github.com/gin-gonic/gin"
"github.com/go-vela/server/compiler"
"github.com/go-vela/server/router/middleware/org"
"github.com/go-vela/server/router/middleware/pipeline"
pMiddleware "github.com/go-vela/server/router/middleware/pipeline"
"github.com/go-vela/server/router/middleware/repo"
"github.com/go-vela/server/router/middleware/user"
"github.com/go-vela/server/util"
"github.com/go-vela/types"
"github.com/go-vela/types/pipeline"
"github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -72,7 +74,7 @@ func CompilePipeline(c *gin.Context) {
// capture middleware values
m := c.MustGet("metadata").(*types.Metadata)
o := org.Retrieve(c)
p := pipeline.Retrieve(c)
p := pMiddleware.Retrieve(c)
r := repo.Retrieve(c)
u := user.Retrieve(c)

Expand All @@ -94,8 +96,10 @@ func CompilePipeline(c *gin.Context) {
// create the compiler object
compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u)

ruleData := prepareRuleData(c)

// compile the pipeline
pipeline, _, err := compiler.CompileLite(p.GetData(), true)
pipeline, _, err := compiler.CompileLite(p.GetData(), ruleData, true)
if err != nil {
retErr := fmt.Errorf("unable to compile pipeline %s: %w", entry, err)

Expand All @@ -106,3 +110,51 @@ func CompilePipeline(c *gin.Context) {

writeOutput(c, pipeline)
}

// prepareRuleData is a helper function to prepare the rule data from the query parameters.
func prepareRuleData(c *gin.Context) *pipeline.RuleData {
// capture the branch name parameter
branch := c.Query("branch")
// capture the comment parameter
comment := c.Query("comment")
// capture the event type parameter
event := c.Query("event")
// capture the repo parameter
ruleDataRepo := c.Query("repo")
// capture the status type parameter
status := c.Query("status")
// capture the tag parameter
tag := c.Query("tag")
// capture the target parameter
target := c.Query("target")

var pathSet []string
// capture the path parameter
path := c.Query("path")
if len(path) > 0 {
pathSet = strings.Split(path, ",")
}

// if any ruledata query params were provided, create ruledata struct
if len(branch) > 0 ||
len(comment) > 0 ||
len(event) > 0 ||
len(path) > 0 ||
len(ruleDataRepo) > 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,
}
}

return nil
}
4 changes: 3 additions & 1 deletion api/pipeline/expand.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,10 @@ func ExpandPipeline(c *gin.Context) {
// create the compiler object
compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u)

ruleData := prepareRuleData(c)

// expand the templates in the pipeline
pipeline, _, err := compiler.CompileLite(p.GetData(), false)
pipeline, _, err := compiler.CompileLite(p.GetData(), ruleData, false)
if err != nil {
retErr := fmt.Errorf("unable to expand pipeline %s: %w", entry, err)

Expand Down
4 changes: 3 additions & 1 deletion api/pipeline/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,10 @@ func ValidatePipeline(c *gin.Context) {
// create the compiler object
compiler := compiler.FromContext(c).Duplicate().WithCommit(p.GetCommit()).WithMetadata(m).WithRepo(r).WithUser(u)

ruleData := prepareRuleData(c)

// validate the pipeline
pipeline, _, err := compiler.CompileLite(p.GetData(), false)
pipeline, _, err := compiler.CompileLite(p.GetData(), ruleData, false)
if err != nil {
retErr := fmt.Errorf("unable to validate pipeline %s: %w", entry, err)

Expand Down
2 changes: 1 addition & 1 deletion compiler/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Engine interface {
// CompileLite defines a function that produces an light executable
// representation of a pipeline from an object. This calls
// Parse internally to convert the object to a yaml configuration.
CompileLite(interface{}, bool) (*yaml.Build, *library.Pipeline, error)
CompileLite(interface{}, *pipeline.RuleData, bool) (*yaml.Build, *library.Pipeline, error)

// Duplicate defines a function that
// creates a clone of the Engine.
Expand Down
73 changes: 54 additions & 19 deletions compiler/native/compile.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, *library.Pipeline, err
}

// CompileLite produces a partial of an executable pipeline from a yaml configuration.
func (c *client) CompileLite(v interface{}, substitute bool) (*yaml.Build, *library.Pipeline, error) {
func (c *client) CompileLite(v interface{}, ruleData *pipeline.RuleData, substitute bool) (*yaml.Build, *library.Pipeline, error) {
p, data, err := c.Parse(v, c.repo.GetPipelineType(), new(yaml.Template))
if err != nil {
return nil, nil, err
Expand Down Expand Up @@ -125,36 +125,71 @@ func (c *client) CompileLite(v interface{}, substitute bool) (*yaml.Build, *libr
// create map of templates for easy lookup
templates := mapFromTemplates(p.Templates)

if len(templates) > 0 {
switch {
case len(p.Stages) > 0:
// inject the templates into the steps
p, err = c.ExpandStages(p, templates, nil)
switch {
case len(p.Stages) > 0:
// inject the templates into the steps
p, err = c.ExpandStages(p, templates, ruleData)
if err != nil {
return nil, _pipeline, err
}

if substitute {
// inject the substituted environment variables into the steps
p.Stages, err = c.SubstituteStages(p.Stages)
if err != nil {
return nil, _pipeline, err
}
}

if ruleData != nil {
purgedStages := new(yaml.StageSlice)

if substitute {
// inject the substituted environment variables into the steps
p.Stages, err = c.SubstituteStages(p.Stages)
if err != nil {
return nil, _pipeline, err
for _, stg := range p.Stages {
purgedSteps := new(yaml.StepSlice)

for _, s := range stg.Steps {
cRuleset := s.Ruleset.ToPipeline()
if match, err := cRuleset.Match(ruleData); err == nil && match {
*purgedSteps = append(*purgedSteps, s)
}
}

stg.Steps = *purgedSteps

if len(stg.Steps) > 0 {
*purgedStages = append(*purgedStages, stg)
}
}
case len(p.Steps) > 0:
// inject the templates into the steps
p, err = c.ExpandSteps(p, templates, nil, c.TemplateDepth)

p.Stages = *purgedStages
}

case len(p.Steps) > 0:
// inject the templates into the steps
p, err = c.ExpandSteps(p, templates, ruleData, c.TemplateDepth)
if err != nil {
return nil, _pipeline, err
}

if substitute {
// inject the substituted environment variables into the steps
p.Steps, err = c.SubstituteSteps(p.Steps)
if err != nil {
return nil, _pipeline, err
}
}

if substitute {
// inject the substituted environment variables into the steps
p.Steps, err = c.SubstituteSteps(p.Steps)
if err != nil {
return nil, _pipeline, err
if ruleData != nil {
purgedSteps := new(yaml.StepSlice)

for _, s := range p.Steps {
cRuleset := s.Ruleset.ToPipeline()
if match, err := cRuleset.Match(ruleData); err == nil && match {
*purgedSteps = append(*purgedSteps, s)
}
}

p.Steps = *purgedSteps
}
}

Expand Down
Loading

0 comments on commit 0d08fc3

Please sign in to comment.