Skip to content

Commit cc1fd14

Browse files
committed
Added Validation: Matrix parameters cannot be empty arrays
Added a check in Pipeline validation to verify that matrix parameters are not just arrays, but that they are not empty arrays. This won't change existing functionality/capabilities, but will get rid of the panic in the reconciler.
1 parent 2da10fc commit cc1fd14

File tree

5 files changed

+50
-13
lines changed

5 files changed

+50
-13
lines changed

docs/matrix.md

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ weight: 11
2424
## Overview
2525

2626
`Matrix` is used to fan out `Tasks` in a `Pipeline`. This doc will explain the details of `matrix` support in
27-
Tekton.
27+
Tekton.
2828

2929
Documentation for specifying `Matrix` in a `Pipeline`:
3030
- [Specifying `Matrix` in `Tasks`](pipelines.md#specifying-matrix-in-pipelinetasks)
@@ -40,12 +40,12 @@ A `Matrix` supports the following features:
4040
* [Concurrency Control](#concurrency-control)
4141
* [Parameters](#parameters)
4242
* [Context Variables](#context-variables)
43-
* [Results](#results)
43+
* [Results](#results)
4444

4545
### Concurrency Control
4646

4747
The default maximum count of `TaskRuns` or `Runs` from a given `Matrix` is **256**. To customize the maximum count of
48-
`TaskRuns` or `Runs` generated from a given `Matrix`, configure the `default-max-matrix-combinations-count` in
48+
`TaskRuns` or `Runs` generated from a given `Matrix`, configure the `default-max-matrix-combinations-count` in
4949
[config defaults](/config/config-defaults.yaml). When a `Matrix` in `PipelineTask` would generate more than the maximum
5050
`TaskRuns` or `Runs`, the `Pipeline` validation would fail.
5151

@@ -69,6 +69,7 @@ The `Matrix` will take `Parameters` of type `"array"` only, which will be suppli
6969
`PipelineTask` by substituting `Parameters` of type `"string"` in the underlying `Task`.
7070
The names of the `Parameters` in the `Matrix` must match the names of the `Parameters`
7171
in the underlying `Task` that they will be substituting.
72+
Note: The `Paramaters` of type `array` cannot be empty.
7273

7374
In the example below, the *test* `Task` takes *browser* and *platform* `Parameters` of type
7475
`"string"`. A `Pipeline` used to fan out the `Task` using `Matrix` would have two `Parameters`
@@ -92,7 +93,7 @@ spec:
9293
default:
9394
- chrome
9495
- safari
95-
- firefox
96+
- firefox
9697
tasks:
9798
- name: fetch-repository
9899
taskRef:
@@ -110,7 +111,7 @@ spec:
110111
...
111112
```
112113

113-
A `Parameter` can be passed to either the `matrix` or `params` field, not both.
114+
A `Parameter` can be passed to either the `matrix` or `params` field, not both.
114115

115116
For further details on specifying `Parameters` in the `Pipeline` and passing them to
116117
`PipelineTasks`, see [documentation](pipelines.md#specifying-parameters).
@@ -150,7 +151,7 @@ spec:
150151

151152
### Context Variables
152153

153-
Similarly to the `Parameters` in the `Params` field, the `Parameters` in the `Matrix` field will accept
154+
Similarly to the `Parameters` in the `Params` field, the `Parameters` in the `Matrix` field will accept
154155
[context variables](variables.md) that will be substituted, including:
155156

156157
* `PipelineRun` name, namespace and uid
@@ -161,7 +162,7 @@ Similarly to the `Parameters` in the `Params` field, the `Parameters` in the `Ma
161162

162163
#### Specifying Results in a Matrix
163164

164-
Consuming `Results` from previous `TaskRuns` or `Runs` in a `Matrix`, which would dynamically generate
165+
Consuming `Results` from previous `TaskRuns` or `Runs` in a `Matrix`, which would dynamically generate
165166
`TaskRuns` or `Runs` from the fanned out `PipelineTask`, is supported. Producing `Results` in from a
166167
`PipelineTask` with a `Matrix` is not yet supported - see [further details](#results-from-fanned-out-pipelinetasks).
167168

@@ -203,7 +204,7 @@ tasks:
203204

204205
Consuming `Results` from fanned out `PipelineTasks` will not be in the supported in the initial iteration
205206
of `Matrix`. Supporting consuming `Results` from fanned out `PipelineTasks` will be revisited after array
206-
and object `Results` are supported.
207+
and object `Results` are supported.
207208

208209
## Fan Out
209210

@@ -487,15 +488,15 @@ status:
487488
name: platforms-and-browsers
488489
taskRef:
489490
apiVersion: cel.tekton.dev/v1alpha1
490-
kind: CEL
491+
kind: CEL
491492
startTime: "2022-06-28T20:49:40Z"
492493
completionTime: "2022-06-28T20:49:41Z"
493494
conditions:
494495
- lastTransitionTime: "2022-06-28T20:49:41Z"
495496
message: 'Tasks Completed: 1 (Failed: 0, Cancelled 0), Skipped: 0'
496497
reason: Succeeded
497498
status: "True"
498-
type: Succeeded
499+
type: Succeeded
499500
childReferences:
500501
- apiVersion: tekton.dev/v1alpha1
501502
kind: Run
@@ -533,11 +534,11 @@ status:
533534

534535
## Retries
535536

536-
The `retries` field is used to specify the number of times a `PipelineTask` should be retried when its `TaskRun` or
537-
`Run` fails, see the [documentation][retries] for further details. When a `PipelineTask` is fanned out using `Matrix`,
537+
The `retries` field is used to specify the number of times a `PipelineTask` should be retried when its `TaskRun` or
538+
`Run` fails, see the [documentation][retries] for further details. When a `PipelineTask` is fanned out using `Matrix`,
538539
a given `TaskRun` or `Run` executed will be retried as much as the field in the `retries` field of the `PipelineTask`.
539540

540-
For example, the `PipelineTask` in this `PipelineRun` will be fanned out into three `TaskRuns` each of which will be
541+
For example, the `PipelineTask` in this `PipelineRun` will be fanned out into three `TaskRuns` each of which will be
541542
retried once:
542543

543544
```yaml

pkg/apis/pipeline/v1/param_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,9 @@ func validateParametersInTaskMatrix(matrix *Matrix) (errs *apis.FieldError) {
331331
if param.Value.Type != ParamTypeArray {
332332
errs = errs.Also(apis.ErrInvalidValue("parameters of type array only are allowed in matrix", "").ViaFieldKey("matrix", param.Name))
333333
}
334+
if param.Value.Type == ParamTypeArray && len(param.Value.ArrayVal) == 0 {
335+
errs = errs.Also(apis.ErrInvalidValue("empty arrays not allowed as parameters in matrix", "").ViaFieldKey("matrix", param.Name))
336+
}
334337
}
335338
}
336339
return errs

pkg/apis/pipeline/v1/pipeline_types_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,21 @@ func TestPipelineTask_validateMatrix(t *testing.T) {
645645
Name: "barfoo", Value: ParamValue{Type: ParamTypeArray, ArrayVal: []string{"bar", "foo"}},
646646
}}},
647647
},
648+
}, {
649+
name: "parameters in matrix are not empty arrays",
650+
pt: &PipelineTask{
651+
Name: "task",
652+
Matrix: &Matrix{
653+
Params: []Param{{
654+
Name: "foobar", Value: ParamValue{Type: ParamTypeArray, ArrayVal: []string{}},
655+
}, {
656+
Name: "barfoo", Value: ParamValue{Type: ParamTypeArray, ArrayVal: []string{}},
657+
}}},
658+
},
659+
wantErrs: &apis.FieldError{
660+
Message: "invalid value: empty arrays not allowed as parameters in matrix",
661+
Paths: []string{"matrix[barfoo]", "matrix[foobar]"},
662+
},
648663
}, {
649664
name: "parameters in matrix contain results references",
650665
pt: &PipelineTask{

pkg/apis/pipeline/v1beta1/param_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,9 @@ func validateParametersInTaskMatrix(matrix *Matrix) (errs *apis.FieldError) {
325325
if param.Value.Type != ParamTypeArray {
326326
errs = errs.Also(apis.ErrInvalidValue("parameters of type array only are allowed in matrix", "").ViaFieldKey("matrix", param.Name))
327327
}
328+
if param.Value.Type == ParamTypeArray && len(param.Value.ArrayVal) == 0 {
329+
errs = errs.Also(apis.ErrInvalidValue("empty arrays not allowed as parameters in matrix", "").ViaFieldKey("matrix", param.Name))
330+
}
328331
}
329332
}
330333
return errs

pkg/apis/pipeline/v1beta1/pipeline_types_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,21 @@ func TestPipelineTask_validateMatrix(t *testing.T) {
831831
Name: "barfoo", Value: ParamValue{Type: ParamTypeArray, ArrayVal: []string{"bar", "foo"}},
832832
}}},
833833
},
834+
}, {
835+
name: "parameters in matrix are not empty arrays",
836+
pt: &PipelineTask{
837+
Name: "task",
838+
Matrix: &Matrix{
839+
Params: []Param{{
840+
Name: "foobar", Value: ParamValue{Type: ParamTypeArray, ArrayVal: []string{}},
841+
}, {
842+
Name: "barfoo", Value: ParamValue{Type: ParamTypeArray, ArrayVal: []string{}},
843+
}}},
844+
},
845+
wantErrs: &apis.FieldError{
846+
Message: "invalid value: empty arrays not allowed as parameters in matrix",
847+
Paths: []string{"matrix[barfoo]", "matrix[foobar]"},
848+
},
834849
}, {
835850
name: "parameters in matrix contain results references",
836851
pt: &PipelineTask{

0 commit comments

Comments
 (0)