From d54e1819cc7ecf2e6f986a6f711671691fc77cc0 Mon Sep 17 00:00:00 2001 From: Liam Clarke Date: Wed, 13 Mar 2024 12:31:32 +0000 Subject: [PATCH] PIPE-4359 Update config compilation pipeline values to add parameters Config compilation now accepts pipeline values and parameters in a single map with the expected prefixes. All standard values are now prefixed with `pipeline.`, and all parameters are prefixed with `pipeline.parameters.` as described in the Pipeline Values documentation. https://circleci.com/docs/pipeline-variables/ --- cmd/policy/policy.go | 2 +- config/commands.go | 6 ++--- config/config.go | 7 ++++-- config/pipeline.go | 26 ++++++++++++--------- config/pipeline_test.go | 52 +++++++++++++++++++++++++++++++++++++++++ local/local.go | 9 +++---- 6 files changed, 81 insertions(+), 21 deletions(-) create mode 100644 config/pipeline_test.go diff --git a/cmd/policy/policy.go b/cmd/policy/policy.go index 19147fbc3..9060ac750 100644 --- a/cmd/policy/policy.go +++ b/cmd/policy/policy.go @@ -521,7 +521,7 @@ This group of commands allows the management of polices to be verified against b ConfigYaml: string(data), Options: config.Options{ OwnerID: ownerID, - PipelineValues: pipelineValues, + PipelineValues: config.LocalPipelineValues(parameters), PipelineParameters: parameters, }, }, diff --git a/config/commands.go b/config/commands.go index 8da291eaf..bb046e1f0 100644 --- a/config/commands.go +++ b/config/commands.go @@ -82,7 +82,7 @@ func (c *ConfigCompiler) ProcessConfig(opts ProcessConfigOpts) (response *Config } //if no orgId provided use org slug - values := LocalPipelineValues() + values := LocalPipelineValues(params) if opts.VerboseOutput { fmt.Fprintln(os.Stderr, "Processing config with following values:") printValues(values) @@ -126,7 +126,7 @@ func (c *ConfigCompiler) ValidateConfig(opts ValidateConfigOpts) error { var response *ConfigResponse //if no orgId provided use org slug - values := LocalPipelineValues() + values := LocalPipelineValues(nil) if opts.VerboseOutput { fmt.Fprintln(os.Stderr, "Validating config with following values:") printValues(values) @@ -141,7 +141,7 @@ func (c *ConfigCompiler) ValidateConfig(opts ValidateConfigOpts) error { opts.ConfigPath, orgID, nil, - LocalPipelineValues(), + values, ) if err != nil { return err diff --git a/config/config.go b/config/config.go index 9d52be9a1..79048f878 100644 --- a/config/config.go +++ b/config/config.go @@ -5,9 +5,10 @@ import ( "io" "os" + "github.com/pkg/errors" + "github.com/CircleCI-Public/circleci-cli/api/collaborators" "github.com/CircleCI-Public/circleci-cli/settings" - "github.com/pkg/errors" ) var ( @@ -71,7 +72,9 @@ type CompileConfigRequest struct { } type Options struct { - OwnerID string `json:"owner_id,omitempty"` + OwnerID string `json:"owner_id,omitempty"` + // PipelineParameters are deprecated and will be removed in the future. + // Use PipelineValues instead. PipelineParameters map[string]interface{} `json:"pipeline_parameters,omitempty"` PipelineValues map[string]interface{} `json:"pipeline_values,omitempty"` } diff --git a/config/pipeline.go b/config/pipeline.go index 923630c4e..e6b09b659 100644 --- a/config/pipeline.go +++ b/config/pipeline.go @@ -12,9 +12,9 @@ type Values map[string]interface{} // Static typing is bypassed using an empty interface here due to pipeline parameters supporting multiple types. type Parameters map[string]interface{} -// vars should contain any pipeline parameters that should be accessible via -// << pipeline.parameters.foo >> -func LocalPipelineValues() Values { +// LocalPipelineValues returns a map of pipeline values that can be used for local validation. +// The given parameters will be prefixed with "pipeline.parameters." and accessible via << pipeline.parameters.foo >>. +func LocalPipelineValues(parameters Parameters) Values { revision := git.Revision() gitUrl := "https://github.com/CircleCI-Public/circleci-cli" projectType := "github" @@ -32,14 +32,18 @@ func LocalPipelineValues() Values { } vals := map[string]interface{}{ - "id": "00000000-0000-0000-0000-000000000001", - "number": 1, - "project.git_url": gitUrl, - "project.type": projectType, - "git.tag": git.Tag(), - "git.branch": git.Branch(), - "git.revision": revision, - "git.base_revision": revision, + "pipeline.id": "00000000-0000-0000-0000-000000000001", + "pipeline.number": 1, + "pipeline.project.git_url": gitUrl, + "pipeline.project.type": projectType, + "pipeline.git.tag": git.Tag(), + "pipeline.git.branch": git.Branch(), + "pipeline.git.revision": revision, + "pipeline.git.base_revision": revision, + } + + for k, v := range parameters { + vals[fmt.Sprintf("pipeline.parameters.%s", k)] = v } return vals diff --git a/config/pipeline_test.go b/config/pipeline_test.go new file mode 100644 index 000000000..6e2cd815e --- /dev/null +++ b/config/pipeline_test.go @@ -0,0 +1,52 @@ +package config + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "golang.org/x/exp/maps" +) + +func TestLocalPipelineValues(t *testing.T) { + tests := []struct { + name string + parameters Parameters + wantKeys []string + }{ + { + name: "standard values given nil parameters", + parameters: nil, + wantKeys: []string{ + "pipeline.id", + "pipeline.number", + "pipeline.project.git_url", + "pipeline.project.type", + "pipeline.git.tag", + "pipeline.git.branch", + "pipeline.git.revision", + "pipeline.git.base_revision", + }, + }, + { + name: "standard and prefixed parameters given map of parameters", + parameters: Parameters{"foo": "bar", "baz": "buzz"}, + wantKeys: []string{ + "pipeline.id", + "pipeline.number", + "pipeline.project.git_url", + "pipeline.project.type", + "pipeline.git.tag", + "pipeline.git.branch", + "pipeline.git.revision", + "pipeline.git.base_revision", + "pipeline.parameters.foo", + "pipeline.parameters.baz", + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.ElementsMatchf(t, tt.wantKeys, maps.Keys(LocalPipelineValues(tt.parameters)), "LocalPipelineValues(%v)", tt.parameters) + }) + } +} diff --git a/local/local.go b/local/local.go index 041357d8e..87d103d41 100644 --- a/local/local.go +++ b/local/local.go @@ -10,10 +10,11 @@ import ( "strings" "syscall" - "github.com/CircleCI-Public/circleci-cli/config" - "github.com/CircleCI-Public/circleci-cli/settings" "github.com/pkg/errors" "github.com/spf13/pflag" + + "github.com/CircleCI-Public/circleci-cli/config" + "github.com/CircleCI-Public/circleci-cli/settings" ) var picardRepo = "circleci/picard" @@ -46,13 +47,13 @@ func Execute(flags *pflag.FlagSet, cfg *settings.Config, args []string) error { //if no orgId provided use org slug orgID, _ := flags.GetString("org-id") if strings.TrimSpace(orgID) != "" { - configResponse, err = compiler.ConfigQuery(configPath, orgID, nil, config.LocalPipelineValues()) + configResponse, err = compiler.ConfigQuery(configPath, orgID, nil, config.LocalPipelineValues(nil)) if err != nil { return err } } else { orgSlug, _ := flags.GetString("org-slug") - configResponse, err = compiler.ConfigQuery(configPath, orgSlug, nil, config.LocalPipelineValues()) + configResponse, err = compiler.ConfigQuery(configPath, orgSlug, nil, config.LocalPipelineValues(nil)) if err != nil { return err }