Skip to content

Commit

Permalink
PPP-3372 Add evaluate variables stage (#90)
Browse files Browse the repository at this point in the history
* Add types for evaluate variables stage

* Test building evaluate variables stage

* Build evaluate variables stage

* More eval variables tests

* Refactor eval variables to match spec

* Remove redundant test

* Update eval variables yaml field name

* Add doc for evaluate variables stage
  • Loading branch information
mgruesen authored Feb 16, 2022
1 parent 0e31253 commit 7d6f7e9
Show file tree
Hide file tree
Showing 5 changed files with 99 additions and 3 deletions.
20 changes: 20 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,26 @@ parameters:

This configures your pipeline to have parameters in the UI / enable pipeline expressions.

### <a name="evaluatevariables"></a> Evaluate Variables Stage

The evaluate variables stage allows you to evaluate complex expressions and use them throughout your pipeline:

```yaml
- name: "evaluate variables"
variables:
- key: "my-fun-key"
value: ${my-complex-expression}
```

You can reference the variable by the key name:

```yaml
- name: "Some other stage"
someField: ${ my-fun-key }
```

### <a name="configurator"></a> Configurator

Files under the `configuratorFiles` section are expected to be in the [k8s-configurator format](https://github.com/namely/k8s-configurator/blob/master/README.md#input-file-and-envs). These will be run through k8s-configurator to generate the environment-specific manifest. By default, the environment used by k8s-configurator will be determined by the account used in this stage. However, you may set the optional `env` property for configuratorFiles to override this.

```yaml
Expand Down
22 changes: 22 additions & 0 deletions pipeline/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,14 @@ func (b *Builder) Pipeline() (*types.SpinnakerPipeline, error) {
stageIndex = stageIndex + 1
}

if stage.EvaluateVariables != nil {
s, err = b.buildEvaluateVariablesStage(stageIndex, stage)
if err != nil {
return sp, fmt.Errorf("failed to build evaluate variables stage with error: %v", err)
}
stageIndex++
}

if stage.RunSpinnakerPipeline != nil {
s, err = b.buildRunSpinnakerPipelineStage(stageIndex, stage)
if err != nil {
Expand Down Expand Up @@ -621,6 +629,20 @@ func (b *Builder) buildJenkinsStage(index int, s config.Stage) (*types.JenkinsSt
return stage, nil
}

func (b *Builder) buildEvaluateVariablesStage(index int, s config.Stage) (*types.EvaluateVariablesStage, error) {
stage := &types.EvaluateVariablesStage{
StageMetadata: buildStageMetadata(s, "evaluatevariables", index, b.isLinear),
FailOnFailedExpressions: true,
Variables: make(map[string]string),
}

for _, p := range s.EvaluateVariables.Variables {
stage.Variables[p.Key] = p.Value
}

return stage, nil
}

func (b *Builder) buildRunSpinnakerPipelineStage(index int, s config.Stage) (*types.RunSpinnakerPipelineStage, error) {

// Set default values
Expand Down
41 changes: 38 additions & 3 deletions pipeline/builder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
appsv1 "k8s.io/api/apps/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
batchv1 "k8s.io/api/batch/v1"
batchv1beta1 "k8s.io/api/batch/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
)

Expand Down Expand Up @@ -471,7 +471,7 @@ func TestBuilderPipelineStages(t *testing.T) {
{
Name: "hello",
Resources: &config.Resources{
Limits: &config.Resource{Memory: "300Mi", CPU: "300m"},
Limits: &config.Resource{Memory: "300Mi", CPU: "300m"},
Requests: &config.Resource{Memory: "500Mi", CPU: "500m"},
},
},
Expand Down Expand Up @@ -508,7 +508,7 @@ func TestBuilderPipelineStages(t *testing.T) {
{
Name: "pi",
Resources: &config.Resources{
Limits: &config.Resource{Memory: "300Mi", CPU: "300m"},
Limits: &config.Resource{Memory: "300Mi", CPU: "300m"},
Requests: &config.Resource{Memory: "500Mi", CPU: "500m"},
},
},
Expand Down Expand Up @@ -1190,6 +1190,41 @@ func TestBuilderPipelineStages(t *testing.T) {
})
})

t.Run("EvaluateVariables stage is parsed correctly", func(t *testing.T) {
t.Run("Properties are assigned", func(t *testing.T) {
pipeline := &config.Pipeline{
Stages: []config.Stage{
{
Name: "Test EvaluateVariables Stage",
EvaluateVariables: &config.EvaluateVariablesStage{
Variables: []config.PassthroughParameter{
{
Key: "myfunkey",
Value: "${mycomplexexpression}",
},
},
},
},
},
}

builder := builder.New(pipeline)
spinnaker, err := builder.Pipeline()
require.NoError(t, err, "error generating EvaluateVariables pipeline json")

stg := spinnaker.Stages[0].(*types.EvaluateVariablesStage)
assert.Equal(t, "Test EvaluateVariables Stage", stg.Name)
assert.Equal(t, "evaluatevariables", stg.Type)

variables := stg.Variables
assert.Equal(t, "${mycomplexexpression}", variables["myfunkey"])

assert.True(t, stg.FailOnFailedExpressions)

t.Logf("%+v\n", stg)
})
})

t.Run("RunSpinnakerPipeline stage is parsed correctly", func(t *testing.T) {
t.Run("Properties are assigned", func(t *testing.T) {

Expand Down
13 changes: 13 additions & 0 deletions pipeline/builder/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -556,3 +556,16 @@ type OptionalStageSupport struct {
Expression string `json:"expression"`
Type string `json:"type"`
}

// EvaluateVariablesStage parses complex expressions for reuse throughout a pipeline
type EvaluateVariablesStage struct {
StageMetadata

FailOnFailedExpressions bool `json:"failOnFailedExpessions"`

Variables map[string]string `json:"variables,omitempty"`
}

func (evs EvaluateVariablesStage) spinnakerStage() {}

var _ Stage = EvaluateVariablesStage{}
6 changes: 6 additions & 0 deletions pipeline/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ type Stage struct {
WebHook *WebHookStage `yaml:"webHook,omitempty"`
Jenkins *JenkinsStage `yaml:"jenkins,omitempty"`
RunSpinnakerPipeline *RunSpinnakerPipelineStage `yaml:"spinnaker,omitempty"`
EvaluateVariables *EvaluateVariablesStage `yaml:"variables,omitempty"`
}

// Notification config from pipeline configuration on a stage or pipeline
Expand Down Expand Up @@ -366,3 +367,8 @@ func findImageDescription(containerName string, refs []ImageDescriptionRef) *Ima

return nil
}

// EvaluateVariablesStage parses complex expressions for reuse throughout a pipeline
type EvaluateVariablesStage struct {
Variables []PassthroughParameter `yaml:"variables,omitempty"`
}

0 comments on commit 7d6f7e9

Please sign in to comment.