Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TEP-0076] Add array support for emitting results #4818

Merged
merged 1 commit into from
May 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 38 additions & 14 deletions docs/tasks.md
Original file line number Diff line number Diff line change
Expand Up @@ -330,7 +330,7 @@ steps:
echo "I am supposed to sleep for 60 seconds!"
sleep 60
timeout: 5s
```
```

#### Specifying `onError` for a `step`

Expand Down Expand Up @@ -450,7 +450,7 @@ Parameter names:

For example, `foo.Is-Bar_` is a valid parameter name, but `barIsBa$` or `0banana` are not.

> NOTE:
> NOTE:
> 1. Parameter names are **case insensitive**. For example, `APPLE` and `apple` will be treated as equal. If they appear in the same TaskSpec's params, it will be rejected as invalid.
> 2. If a parameter name contains dots (.), it must be referenced by using the [bracket notation](#substituting-parameters-and-resources) with either single or double quotes i.e. `$(params['foo.bar'])`, `$(params["foo.bar"])`. See the following example for more information.

Expand Down Expand Up @@ -684,6 +684,30 @@ or [at the `Pipeline` level](./pipelines.md#configuring-execution-results-at-the
**Note:** The maximum size of a `Task's` results is limited by the container termination message feature of Kubernetes,
as results are passed back to the controller via this mechanism. At present, the limit is
["4096 bytes"](https://github.com/kubernetes/kubernetes/blob/96e13de777a9eb57f87889072b68ac40467209ac/pkg/kubelet/container/runtime.go#L632).

**Note:** The result type currently support `string` and `array` (`array` is alpha gated feature), you can write `array` results via JSON escaped format. In the example below, the task specifies one files in the `results` field and write `array` to the file. And `array` is currently supported in Task level not in Pipeline level.

```
kind: Task
apiVersion: tekton.dev/v1beta1
metadata:
name: write-array
annotations:
description: |
A simple task that writes array
spec:
results:
- name: array-results
type: array
description: The array results
steps:
- name: write-array
image: bash:latest
script: |
#!/usr/bin/env bash
echo -n "[\"hello\",\"world\"]" | tee $(results.array-results.path)
```

Results are written to the termination message encoded as JSON objects and Tekton uses those objects
to pass additional information to the controller. As such, `Task` results are best suited for holding
small amounts of data, such as commit SHAs, branch names, ephemeral namespaces, and so on.
Expand Down Expand Up @@ -1181,10 +1205,10 @@ log into the `Pod` and add a `Step` that pauses the `Task` at the desired stage.

### Running Step Containers as a Non Root User

All steps that do not require to be run as a root user should make use of TaskRun features to
designate the container for a step runs as a user without root permissions. As a best practice,
running containers as non root should be built into the container image to avoid any possibility
of the container being run as root. However, as a further measure of enforcing this practice,
All steps that do not require to be run as a root user should make use of TaskRun features to
designate the container for a step runs as a user without root permissions. As a best practice,
running containers as non root should be built into the container image to avoid any possibility
of the container being run as root. However, as a further measure of enforcing this practice,
steps can make use of a `securityContext` to specify how the container should run.

An example of running Task steps as a non root user is shown below:
Expand Down Expand Up @@ -1228,17 +1252,17 @@ spec:
runAsUser: 1001
```

In the example above, the step `show-user-2000` specifies via a `securityContext` that the container
for the step should run as user 2000. A `securityContext` must still be specified via a TaskRun `podTemplate`
for this TaskRun to run in a Kubernetes environment that enforces running containers as non root as a requirement.
In the example above, the step `show-user-2000` specifies via a `securityContext` that the container
for the step should run as user 2000. A `securityContext` must still be specified via a TaskRun `podTemplate`
for this TaskRun to run in a Kubernetes environment that enforces running containers as non root as a requirement.

The `runAsNonRoot` property specified via the `podTemplate` above validates that steps part of this TaskRun are
running as non root users and will fail to start any step container that attempts to run as root. Only specifying
`runAsNonRoot: true` will not actually run containers as non root as the property simply validates that steps are not
The `runAsNonRoot` property specified via the `podTemplate` above validates that steps part of this TaskRun are
running as non root users and will fail to start any step container that attempts to run as root. Only specifying
`runAsNonRoot: true` will not actually run containers as non root as the property simply validates that steps are not
running as root. It is the `runAsUser` property that is actually used to set the non root user ID for the container.

If a step defines its own `securityContext`, it will be applied for the step container over the `securityContext`
specified at the pod level via the TaskRun `podTemplate`.
If a step defines its own `securityContext`, it will be applied for the step container over the `securityContext`
specified at the pod level via the TaskRun `podTemplate`.

More information about Pod and Container Security Contexts can be found via the [Kubernetes website](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-pod).

Expand Down
39 changes: 39 additions & 0 deletions examples/v1beta1/taskruns/alpha/emit-array-results.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
kind: Task
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition to the Task, please add an example Pipeline. The results are more of a communication means between two tasks (or pipelineTasks). The example are great way to share the usage of the new features.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @pritidesai, thanks for your comment!
In this PR array results passed between tasks are not implemented. This commit focuses on enabling emitting array results from entrypoint->controller.
I'm planning to add it (also array indexing) as well as examples in the followup PR.
Or should I add it in this PR? What do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe I should remove this example and add both examples for next pr?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @Yongxuanzhang for the explanation.

In this PR array results passed between tasks are not implemented.

You mean just the indexing is not supported in this PR or in general, the consumer will get an array result as a string value? I am trying to understand what happens when a consumer refers to such array result in a traditional way i.e. $tasks.taskA.results.arrayResult.

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang May 17, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So with this PR, if referred $tasks.taskA.results.arrayResult in params and it is an array, the users will get a string of $tasks.taskA.results.arrayResult not the array or the string format of the array.

It is also something related to this issue.
This is a bit tricky part and it would be better to be addressed in a separate PR. Since $tasks.taskA.results.arrayResult or $tasks.taskA.results.arrayResult[*] will be treated as string type in ArrayOrString.

So this PR only enables the Task level results array, not sure if this is a real case.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I realized that the doc I added may be confusing as well, support emitting array results may let users think that they can pass array results between tasks within a pipeline, but it is not implemented in this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this PR only enables the Task level results array, not sure if this is a real case.

It might be or might not be, we do not advice such usage but its not restricted either.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should I fix the readme to clarify this? @pritidesai

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thank you @Yongxuanzhang I added comment ⬆️

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added more clarification in the doc

apiVersion: tekton.dev/v1beta1
metadata:
name: write-array
annotations:
description: |
A simple task that writes array
spec:
results:
- name: array-results
type: array
description: The array results
steps:
- name: write-array
image: bash:latest
script: |
#!/usr/bin/env bash
echo -n "[\"hello\",\"world\"]" | tee $(results.array-results.path)
- name: check-results-array
image: ubuntu
script: |
#!/bin/bash
VALUE=$(cat $(results.array-results.path))
EXPECTED=[\"hello\",\"world\"]
diff=$(diff <(printf "%s\n" "${VALUE[@]}") <(printf "%s\n" "${EXPECTED[@]}"))
if [[ -z "$diff" ]]; then
echo "TRUE"
else
echo "FALSE"
fi
---
kind: TaskRun
apiVersion: tekton.dev/v1beta1
metadata:
name: write-array-tr
spec:
taskRef:
name: write-array
kind: task
7 changes: 4 additions & 3 deletions pkg/apis/pipeline/v1beta1/openapi_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

44 changes: 35 additions & 9 deletions pkg/apis/pipeline/v1beta1/param_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,17 +141,43 @@ type ArrayOrString struct {

// UnmarshalJSON implements the json.Unmarshaller interface.
func (arrayOrString *ArrayOrString) UnmarshalJSON(value []byte) error {
switch value[0] {
case '[':
arrayOrString.Type = ParamTypeArray
return json.Unmarshal(value, &arrayOrString.ArrayVal)
case '{':
arrayOrString.Type = ParamTypeObject
return json.Unmarshal(value, &arrayOrString.ObjectVal)
default:
// ArrayOrString is used for Results Value as well, the results can be any kind of
// data so we need to check if it is empty.
if len(value) == 0 {
arrayOrString.Type = ParamTypeString
return json.Unmarshal(value, &arrayOrString.StringVal)
return nil
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would this impact parameters with no values? is it covered by alternate validation to make sure a required parameter is specified - please confirm that the parameter validation has a test to check for no empty value for required params.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Could you point me to a case where parameters has no values?
Correct if I'm wrong, if the parameters has no values then it will be captured by validation check
For example, this won't work. And won't reach this function. This case is special for results since user can write custom data to result path and it could be empty

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: validation-1
spec:
  taskSpec:
    params:
      - name: foo
        type: string
        default:
    steps:
      - name: echo-params
        image: bash
        args:
          [
            "echo",
           "$(params.foo)"]

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang May 19, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So validation will check if the param is empty:

func missingParamsNames(neededParams []string, providedParams []string, paramSpecs []v1beta1.ParamSpec) []string {
missingParamsNames := list.DiffLeft(neededParams, providedParams)
var missingParamsNamesWithNoDefaults []string
for _, param := range missingParamsNames {
for _, inputResourceParam := range paramSpecs {
if inputResourceParam.Name == param && inputResourceParam.Default == nil {
missingParamsNamesWithNoDefaults = append(missingParamsNamesWithNoDefaults, param)
}
}
}
return missingParamsNamesWithNoDefaults
}

if value[0] == '[' {
// We're trying to Unmarshal to []string, but for cases like []int or other types
// of nested array which we don't support yet, we should continue and Unmarshal
// it to String. If the Type being set doesn't match what it actually should be,
// it will be captured by validation in reconciler.
// if failed to unmarshal to array, we will convert the value to string and marshal it to string
var a []string
if err := json.Unmarshal(value, &a); err == nil {
arrayOrString.Type = ParamTypeArray
arrayOrString.ArrayVal = a
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realized the errors didn't get thrown here. This should be err != nil then return nil

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason I did this is because for case like nested lists or lists using not string element, the UnmarshalJson won't work.
Like [1,2,3] with int elements, but I think we should Unmarshal it into a whole string. So if we encountered err when trying to unmarshal to array, we will continue and unmarshal it to a string.

I agree this part of code is not writing very well.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see. Then this should be fine. We will capture the type mismatch when you validate the results against PropertiesSpec. So it definitely worths adding more comments here and in filterResultsAndResources() to explain the details

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! Thanks for the suggestions!

}
}
if value[0] == '{' {
// if failed to unmarshal to map, we will convert the value to string and marshal it to string
var m map[string]string
if err := json.Unmarshal(value, &m); err == nil {
arrayOrString.Type = ParamTypeObject
arrayOrString.ObjectVal = m
return nil
}
}
Yongxuanzhang marked this conversation as resolved.
Show resolved Hide resolved

// By default we unmarshal to string
arrayOrString.Type = ParamTypeString
if err := json.Unmarshal(value, &arrayOrString.StringVal); err == nil {
return nil
}
arrayOrString.StringVal = string(value)

return nil
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function does look weird. Can we avoid using switch:

	if value[0] == '[' {
		// We're trying to Unmarshal to []string, but for cases like []int or other types
		// of nested array which we don't support yet, we should continue and Unmarshal
		// it to String. If the Type being set doesn't match what it actually should be,
		// it will be captured somewhere else.
		// if failed to unmarshal to array, we will convert the value to string and marshal it to string
		if err := json.Unmarshal(value, &arrayOrString.ArrayVal); err == nil {
			arrayOrString.Type = ParamTypeArray
			return nil
		}
	}
	if value[0] == '{' {
		// if failed to unmarshal to map, we will convert the value to string and marshal it to string
		if err := json.Unmarshal(value, &arrayOrString.ObjectVal); err == nil {
			arrayOrString.Type = ParamTypeObject
			return nil
		}
	}
	arrayOrString.ArrayVal = nil
	arrayOrString.ObjectVal = nil
	arrayOrString.Type = ParamTypeString
	arrayOrString.StringVal = string(value)

Also, the unmarshalling does set the arrayOrString.ArrayVal to an array of equal length of the value in case of failure. And that is the reason we need to set it to nil explicitly. Will be great if we find a way unmarshal does not change the ArrayVal but not a blocker for this PR.

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang May 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I changed it to use if, and the json.Unmarshal(value, &arrayOrString.StringVal) is needed, we cannot directly call arrayOrString.StringVal = string(value). It is necessary for correct string values

Yes, it is a bit weird that we need to set it to nil since we tried to unmarshal to array and it will create an empty array. It will be worth figuring out a better idea of this as you suggested

}

// MarshalJSON implements the json.Marshaller interface.
Expand Down
47 changes: 47 additions & 0 deletions pkg/apis/pipeline/v1beta1/param_types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ func TestArrayOrString_UnmarshalJSON(t *testing.T) {
input map[string]interface{}
result v1beta1.ArrayOrString
}{
{
input: map[string]interface{}{"val": 123},
result: *v1beta1.NewArrayOrString("123"),
},
{
input: map[string]interface{}{"val": "123"},
result: *v1beta1.NewArrayOrString("123"),
Expand Down Expand Up @@ -282,6 +286,49 @@ func TestArrayOrString_UnmarshalJSON(t *testing.T) {
}
}

func TestArrayOrString_UnmarshalJSON_Directly(t *testing.T) {
cases := []struct {
desc string
input string
expected v1beta1.ArrayOrString
}{
{desc: "empty value", input: ``, expected: *v1beta1.NewArrayOrString("")},
{desc: "int value", input: `1`, expected: *v1beta1.NewArrayOrString("1")},
{desc: "int array", input: `[1,2,3]`, expected: *v1beta1.NewArrayOrString("[1,2,3]")},
{desc: "nested array", input: `[1,\"2\",3]`, expected: *v1beta1.NewArrayOrString(`[1,\"2\",3]`)},
{desc: "string value", input: `hello`, expected: *v1beta1.NewArrayOrString("hello")},
{desc: "array value", input: `["hello","world"]`, expected: *v1beta1.NewArrayOrString("hello", "world")},
{desc: "object value", input: `{"hello":"world"}`, expected: *v1beta1.NewObject(map[string]string{"hello": "world"})},
}
Yongxuanzhang marked this conversation as resolved.
Show resolved Hide resolved

for _, c := range cases {
aos := v1beta1.ArrayOrString{}
if err := aos.UnmarshalJSON([]byte(c.input)); err != nil {
t.Errorf("Failed to unmarshal input '%v': %v", c.input, err)
}
if !reflect.DeepEqual(aos, c.expected) {
t.Errorf("Failed to unmarshal input '%v': expected %+v, got %+v", c.input, c.expected, aos)
}
}
}

func TestArrayOrString_UnmarshalJSON_Error(t *testing.T) {
cases := []struct {
desc string
input string
}{
{desc: "empty value", input: "{\"val\": }"},
{desc: "wrong beginning value", input: "{\"val\": @}"},
}

for _, c := range cases {
var result ArrayOrStringHolder
if err := json.Unmarshal([]byte(c.input), &result); err == nil {
t.Errorf("Should return err but got nil '%v'", c.input)
}
}
}

func TestArrayOrString_MarshalJSON(t *testing.T) {
cases := []struct {
input v1beta1.ArrayOrString
Expand Down
6 changes: 4 additions & 2 deletions pkg/apis/pipeline/v1beta1/result_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ type TaskRunResult struct {
Type ResultsType `json:"type,omitempty"`

// Value the given value of the result
Value string `json:"value"`
Value ArrayOrString `json:"value"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a API change to me. It seems like we need to follow https://github.com/tektoncd/pipeline/blob/main/api_compatibility_policy.md#alpha-beta-and-ga for adding new feature and deprecation rules. Pinging @dibyom for confirmation. This is a field that users can specify. I think we should add a separate field for the new ArrayOrString and implement on the new field

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang May 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is a change, but it won't have effect on users or introduce breaking changes. And our TEP0076 requires us to change this Value I believe?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We came to a conclusion that this won't be breaking the API change policy. However, we definitely are blocked by the design about whether we want to have a brand new struct on this or just rename StringOrArray.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok but it doesn't block this PR right, I'm still using StringOrArray. We need to figure out that in Chuang's

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah sure!

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang May 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc:@ywluogg, I remember you send email to remind the changes, so we should send emails specifically about cli for this?

Copy link
Member Author

@Yongxuanzhang Yongxuanzhang May 24, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like api mismatch between the pipeline and cli, it should be fixed when we release this change and then bump the pipeline version for cli? Am I correct? @pritidesai

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @tektoncd/cli-maintainers

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like api mismatch between the pipeline and cli, it should be fixed when we release this change and then bump the pipeline version for cli? Am I correct? @pritidesai

I think It will be fixed when CLI bumps the pipelines version (which will have these changes) and update their usage/implementation to change the type of the results from string to StringOrArray. The error reported here is coming from:

./pkg/cmd/taskrun/list.go:                              return fmt.Errorf("failed to list TaskRuns from namespace %s: %v", p.Namespace(), err)

}

// ResultsType indicates the type of a result;
Expand All @@ -54,7 +54,9 @@ type ResultsType string
// Valid ResultsType:
const (
ResultsTypeString ResultsType = "string"
ResultsTypeArray ResultsType = "array"
ResultsTypeObject ResultsType = "object"
)

// AllResultsTypes can be used for ResultsTypes validation.
var AllResultsTypes = []ResultsType{ResultsTypeString}
var AllResultsTypes = []ResultsType{ResultsTypeString, ResultsTypeArray, ResultsTypeObject}
15 changes: 7 additions & 8 deletions pkg/apis/pipeline/v1beta1/result_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,21 @@ import (
"context"
"fmt"

"github.com/tektoncd/pipeline/pkg/apis/config"
"knative.dev/pkg/apis"
)

// Validate implements apis.Validatable
func (tr TaskResult) Validate(_ context.Context) *apis.FieldError {
func (tr TaskResult) Validate(ctx context.Context) (errs *apis.FieldError) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ywluogg I made some new changes to this func, so we can fail fast if the alpha gate is not enabled

if !resultNameFormatRegex.MatchString(tr.Name) {
return apis.ErrInvalidKeyName(tr.Name, "name", fmt.Sprintf("Name must consist of alphanumeric characters, '-', '_', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my-name', or 'my_name', regex used for validation is '%s')", ResultNameFormat))
}
// Validate the result type
validType := false
for _, allowedType := range AllResultsTypes {
if tr.Type == allowedType {
validType = true
}
// Array and Object is alpha feature
if tr.Type == ResultsTypeArray || tr.Type == ResultsTypeObject {
return errs.Also(ValidateEnabledAPIFields(ctx, "results type", config.AlphaAPIFields))
}
if !validType {

if tr.Type != ResultsTypeString {
pritidesai marked this conversation as resolved.
Show resolved Hide resolved
return apis.ErrInvalidValue(tr.Type, "type", fmt.Sprintf("type must be string"))
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/apis/pipeline/v1beta1/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -2605,8 +2605,8 @@
},
"value": {
"description": "Value the given value of the result",
"type": "string",
"default": ""
"default": {},
"$ref": "#/definitions/v1beta1.ArrayOrString"
}
}
},
Expand Down
28 changes: 27 additions & 1 deletion pkg/apis/pipeline/v1beta1/task_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func TestTaskSpecValidate(t *testing.T) {
}},
},
}, {
name: "valid result type",
name: "valid result type string",
fields: fields{
Steps: []v1beta1.Step{{
Image: "my-image",
Expand All @@ -317,6 +317,32 @@ func TestTaskSpecValidate(t *testing.T) {
Description: "my great result",
}},
},
}, {
name: "valid result type array",
fields: fields{
Steps: []v1beta1.Step{{
Image: "my-image",
Args: []string{"arg"},
}},
Results: []v1beta1.TaskResult{{
Name: "MY-RESULT",
Type: v1beta1.ResultsTypeArray,
Description: "my great result",
}},
},
}, {
name: "valid result type object",
fields: fields{
Steps: []v1beta1.Step{{
Image: "my-image",
Args: []string{"arg"},
}},
Results: []v1beta1.TaskResult{{
Name: "MY-RESULT",
Type: v1beta1.ResultsTypeObject,
Description: "my great result",
}},
},
}, {
name: "valid task name context",
fields: fields{
Expand Down
5 changes: 4 additions & 1 deletion pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading