diff --git a/api/pipeline.go b/api/pipeline.go index 98b495ba9..575ca9968 100644 --- a/api/pipeline.go +++ b/api/pipeline.go @@ -265,7 +265,7 @@ func ExpandPipeline(ctx *gin.Context) { return } - pipeline, err := comp.CompileLite(config, true, false) + pipeline, err := comp.CompileLite(config, true, false, nil) if err != nil { retErr := fmt.Errorf("unable to validate pipeline configuration for %s: %w", repoName(ctx), err) util.HandleError(ctx, http.StatusBadRequest, retErr) @@ -349,7 +349,7 @@ func ValidatePipeline(ctx *gin.Context) { template = true } - pipeline, err := comp.CompileLite(config, template, false) + pipeline, err := comp.CompileLite(config, template, false, nil) if err != nil { retErr := fmt.Errorf("unable to validate pipeline configuration for %s: %w", repoName(ctx), err) util.HandleError(ctx, http.StatusBadRequest, retErr) @@ -428,7 +428,7 @@ func CompilePipeline(ctx *gin.Context) { return } - pipeline, err := comp.CompileLite(config, true, true) + pipeline, err := comp.CompileLite(config, true, true, nil) if err != nil { retErr := fmt.Errorf("unable to validate pipeline configuration for %s: %w", repoName(ctx), err) util.HandleError(ctx, http.StatusBadRequest, retErr) diff --git a/compiler/engine.go b/compiler/engine.go index f8795dd50..fa1778fba 100644 --- a/compiler/engine.go +++ b/compiler/engine.go @@ -25,7 +25,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, bool) (*yaml.Build, error) + CompileLite(interface{}, bool, bool, []string) (*yaml.Build, error) // Duplicate defines a function that // creates a clone of the Engine. diff --git a/compiler/native/compile.go b/compiler/native/compile.go index 7d8e41d51..96ec2f0cf 100644 --- a/compiler/native/compile.go +++ b/compiler/native/compile.go @@ -69,7 +69,7 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, error) { switch { case p.Metadata.RenderInline: - newPipeline, err := c.compileInline(p) + newPipeline, err := c.compileInline(p, nil) if err != nil { return nil, err } @@ -92,14 +92,14 @@ func (c *client) Compile(v interface{}) (*pipeline.Build, error) { } // CompileLite produces a partial of an executable pipeline from a yaml configuration. -func (c *client) CompileLite(v interface{}, template, substitute bool) (*yaml.Build, error) { +func (c *client) CompileLite(v interface{}, template, substitute bool, localTemplates []string) (*yaml.Build, error) { p, err := c.Parse(v, c.repo.GetPipelineType(), map[string]interface{}{}) if err != nil { return nil, err } if p.Metadata.RenderInline { - newPipeline, err := c.compileInline(p) + newPipeline, err := c.compileInline(p, localTemplates) if err != nil { return nil, err } @@ -116,6 +116,24 @@ func (c *client) CompileLite(v interface{}, template, substitute bool) (*yaml.Bu // create map of templates for easy lookup templates := mapFromTemplates(p.Templates) + if c.local { + for _, file := range localTemplates { + // local templates override format is : + // + // example: example:/path/to/template.yml + parts := strings.Split(file, ":") + + // make sure the template was configured + _, ok := templates[parts[0]] + if !ok { + return nil, fmt.Errorf("template with name %s is not configured", parts[0]) + } + + // override the source for the given template + templates[parts[0]].Source = parts[1] + } + } + switch { case len(p.Stages) > 0: // inject the templates into the steps @@ -158,17 +176,33 @@ func (c *client) CompileLite(v interface{}, template, substitute bool) (*yaml.Bu } // compileInline parses and expands out inline pipelines. -func (c *client) compileInline(p *yaml.Build) (*yaml.Build, error) { +func (c *client) compileInline(p *yaml.Build, localTemplates []string) (*yaml.Build, error) { newPipeline := *p newPipeline.Templates = yaml.TemplateSlice{} for _, template := range p.Templates { + if c.local { + for _, file := range localTemplates { + // local templates override format is : + // + // example: example:/path/to/template.yml + parts := strings.Split(file, ":") + + // make sure we're referencing the proper template + if parts[0] == template.Name { + // override the source for the given template + template.Source = parts[1] + } + } + } + bytes, err := c.getTemplate(template, template.Name) if err != nil { return nil, err } format := template.Format + // set the default format to golang if the user did not define anything if template.Format == "" { format = constants.PipelineTypeGo diff --git a/compiler/native/compile_test.go b/compiler/native/compile_test.go index b6befc253..2f213fbff 100644 --- a/compiler/native/compile_test.go +++ b/compiler/native/compile_test.go @@ -2977,7 +2977,7 @@ func Test_CompileLite(t *testing.T) { t.Errorf("Reading yaml file return err: %v", err) } - got, err := compiler.CompileLite(yaml, tt.args.template, tt.args.substitute) + got, err := compiler.CompileLite(yaml, tt.args.template, tt.args.substitute, nil) if (err != nil) != tt.wantErr { t.Errorf("CompileLite() error = %v, wantErr %v", err, tt.wantErr) return