diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index d2f6a4d93b7..379383bb642 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -1802,7 +1802,7 @@ map[string]string

Params ([]github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param alias)

-(Appears on:IncludeParams, Matrix, PipelineRunSpec, PipelineTask, ResolverRef, TaskRunInputs, TaskRunSpec) +(Appears on:IncludeParams, Matrix, PipelineRunSpec, PipelineTask, ResolverRef, Step, TaskRunInputs, TaskRunSpec)

Params is a list of Param

@@ -4427,6 +4427,20 @@ Ref

Contains the reference to an existing StepAction.

+ + +params
+ + +Params + + + + +(Optional) +

Params declares parameters passed to this step action.

+ +

StepOutputConfig @@ -10215,7 +10229,7 @@ map[string]string

Params ([]github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param alias)

-(Appears on:RunSpec, CustomRunSpec, IncludeParams, Matrix, PipelineRunSpec, PipelineTask, ResolverRef, TaskRunSpec) +(Appears on:RunSpec, CustomRunSpec, IncludeParams, Matrix, PipelineRunSpec, PipelineTask, ResolverRef, Step, TaskRunSpec)

Params is a list of Param

@@ -13227,6 +13241,20 @@ Ref

Contains the reference to an existing StepAction.

+ + +params
+ + +Params + + + + +(Optional) +

Params declares parameters passed to this step action.

+ +

StepOutputConfig diff --git a/docs/stepactions.md b/docs/stepactions.md index c1acec55d5f..3da5c5197cd 100644 --- a/docs/stepactions.md +++ b/docs/stepactions.md @@ -206,6 +206,8 @@ When a `Step` is referencing a `StepAction`, it can contain the following fields - `securityContext` - `envFrom` - `timeout` +- `ref` +- `params` Using any of the above fields and referencing a `StepAction` is allowed and will not cause an error. For example, the `TaskRun` below will execute without any errors: @@ -220,6 +222,9 @@ spec: - name: action-runner ref: name: step-action + params: + - name: step-action-param + value: hello computeResources: requests: memory: 1Gi @@ -227,3 +232,29 @@ spec: timeout: 1h onError: continue ``` + +### Passing Params to StepAction + +A `StepAction` may require [params](#(declaring-parameters)). In this case, a `Task` needs to ensure that the `StepAction` has access to all the required `params`. +When referencing a `StepAction`, a `Step` can also provide it with `params`, just like how a `TaskRun` provides params to the underlying `Task`. + +```yaml +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: step-action +spec: + TaskSpec: + params: + - name: param-for-step-action + description: "this is a param that the step action needs." + steps: + - name: action-runner + ref: + name: step-action + params: + - name: step-action-param + value: $(params.param-for-step-action) +``` + +**Note:** If a `Step` declares `params` for an `inlined Step`, it will also lead to a validation error. This is because an `inlined Step` gets it's `params` from the `TaskRun`. diff --git a/pkg/apis/pipeline/v1/container_types.go b/pkg/apis/pipeline/v1/container_types.go index 922ac1c8d11..a3cfa06384a 100644 --- a/pkg/apis/pipeline/v1/container_types.go +++ b/pkg/apis/pipeline/v1/container_types.go @@ -138,6 +138,10 @@ type Step struct { // Contains the reference to an existing StepAction. //+optional Ref *Ref `json:"ref,omitempty"` + // Params declares parameters passed to this step action. + // +optional + // +listType=atomic + Params Params `json:"params,omitempty"` } // Ref can be used to refer to a specific instance of a StepAction. diff --git a/pkg/apis/pipeline/v1/openapi_generated.go b/pkg/apis/pipeline/v1/openapi_generated.go index f21c7a06c0c..8ed6ba86be0 100644 --- a/pkg/apis/pipeline/v1/openapi_generated.go +++ b/pkg/apis/pipeline/v1/openapi_generated.go @@ -2966,12 +2966,31 @@ func schema_pkg_apis_pipeline_v1_Step(ref common.ReferenceCallback) common.OpenA Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Ref"), }, }, + "params": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Params declares parameters passed to this step action.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param"), + }, + }, + }, + }, + }, }, Required: []string{"name"}, }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.WorkspaceUsage", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, } } diff --git a/pkg/apis/pipeline/v1/swagger.json b/pkg/apis/pipeline/v1/swagger.json index 79d8d7aad38..c48314355aa 100644 --- a/pkg/apis/pipeline/v1/swagger.json +++ b/pkg/apis/pipeline/v1/swagger.json @@ -1463,6 +1463,15 @@ "description": "OnError defines the exiting behavior of a container on error can be set to [ continue | stopAndFail ]", "type": "string" }, + "params": { + "description": "Params declares parameters passed to this step action.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.Param" + }, + "x-kubernetes-list-type": "atomic" + }, "ref": { "description": "Contains the reference to an existing StepAction.", "$ref": "#/definitions/v1.Ref" diff --git a/pkg/apis/pipeline/v1/task_validation.go b/pkg/apis/pipeline/v1/task_validation.go index 0eabc27c9a8..4f3ba830c75 100644 --- a/pkg/apis/pipeline/v1/task_validation.go +++ b/pkg/apis/pipeline/v1/task_validation.go @@ -300,6 +300,12 @@ func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.Fi }) } } else { + if len(s.Params) > 0 { + errs = errs.Also(&apis.FieldError{ + Message: "params cannot be used without Ref", + Paths: []string{"params"}, + }) + } if s.Image == "" { errs = errs.Also(apis.ErrMissingField("Image")) } diff --git a/pkg/apis/pipeline/v1/task_validation_test.go b/pkg/apis/pipeline/v1/task_validation_test.go index 05799e14e2e..d73019120c1 100644 --- a/pkg/apis/pipeline/v1/task_validation_test.go +++ b/pkg/apis/pipeline/v1/task_validation_test.go @@ -534,6 +534,16 @@ func TestTaskSpecStepActionReferenceValidate(t *testing.T) { Name: "stepAction", }, }}, + }, { + name: "valid use of params with Ref", + Steps: []v1.Step{{ + Ref: &v1.Ref{ + Name: "stepAction", + }, + Params: v1.Params{{ + Name: "param", + }}, + }}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1490,6 +1500,19 @@ func TestTaskSpecValidateErrorWithStepActionRef(t *testing.T) { Message: "env cannot be used with Ref", Paths: []string{"steps[0].env"}, }, + }, { + name: "Cannot use params without Ref", + Steps: []v1.Step{{ + Image: "my-image", + Params: v1.Params{{ + Name: "param", + }}, + }}, + enableStepActions: true, + expectedError: apis.FieldError{ + Message: "params cannot be used without Ref", + Paths: []string{"steps[0].params"}, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1/zz_generated.deepcopy.go index b1be9d45fe4..838f93869f2 100644 --- a/pkg/apis/pipeline/v1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1/zz_generated.deepcopy.go @@ -1290,6 +1290,13 @@ func (in *Step) DeepCopyInto(out *Step) { *out = new(Ref) (*in).DeepCopyInto(*out) } + if in.Params != nil { + in, out := &in.Params, &out.Params + *out = make(Params, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } diff --git a/pkg/apis/pipeline/v1beta1/container_conversion.go b/pkg/apis/pipeline/v1beta1/container_conversion.go index 0ec816b2548..620a655f124 100644 --- a/pkg/apis/pipeline/v1beta1/container_conversion.go +++ b/pkg/apis/pipeline/v1beta1/container_conversion.go @@ -65,6 +65,12 @@ func (s Step) convertTo(ctx context.Context, sink *v1.Step) { sink.Ref = &v1.Ref{} s.Ref.convertTo(ctx, sink.Ref) } + sink.Params = nil + for _, p := range s.Params { + new := v1.Param{} + p.convertTo(ctx, &new) + sink.Params = append(sink.Params, new) + } } func (s *Step) convertFrom(ctx context.Context, source v1.Step) { @@ -97,6 +103,12 @@ func (s *Step) convertFrom(ctx context.Context, source v1.Step) { newRef.convertFrom(ctx, *source.Ref) s.Ref = &newRef } + s.Params = nil + for _, p := range source.Params { + new := Param{} + new.ConvertFrom(ctx, p) + s.Params = append(s.Params, new) + } } func (s StepTemplate) convertTo(ctx context.Context, sink *v1.StepTemplate) { diff --git a/pkg/apis/pipeline/v1beta1/container_types.go b/pkg/apis/pipeline/v1beta1/container_types.go index 0bf6f502664..97bf664d0b3 100644 --- a/pkg/apis/pipeline/v1beta1/container_types.go +++ b/pkg/apis/pipeline/v1beta1/container_types.go @@ -232,6 +232,10 @@ type Step struct { // Contains the reference to an existing StepAction. //+optional Ref *Ref `json:"ref,omitempty"` + // Params declares parameters passed to this step action. + // +optional + // +listType=atomic + Params Params `json:"params,omitempty"` } // Ref can be used to refer to a specific instance of a StepAction. diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go index ae0e0b1fa93..f64529189c5 100644 --- a/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -3920,12 +3920,31 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Ref"), }, }, + "params": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Params declares parameters passed to this step action.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param"), + }, + }, + }, + }, + }, }, Required: []string{"name"}, }, }, Dependencies: []string{ - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage", "k8s.io/api/core/v1.ContainerPort", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.Lifecycle", "k8s.io/api/core/v1.Probe", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Param", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Ref", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepOutputConfig", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.WorkspaceUsage", "k8s.io/api/core/v1.ContainerPort", "k8s.io/api/core/v1.EnvFromSource", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.Lifecycle", "k8s.io/api/core/v1.Probe", "k8s.io/api/core/v1.ResourceRequirements", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeDevice", "k8s.io/api/core/v1.VolumeMount", "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, } } diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json index 5fc165feec6..0d5641dd2ed 100644 --- a/pkg/apis/pipeline/v1beta1/swagger.json +++ b/pkg/apis/pipeline/v1beta1/swagger.json @@ -2070,6 +2070,15 @@ "description": "OnError defines the exiting behavior of a container on error can be set to [ continue | stopAndFail ]", "type": "string" }, + "params": { + "description": "Params declares parameters passed to this step action.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1beta1.Param" + }, + "x-kubernetes-list-type": "atomic" + }, "ports": { "description": "List of ports to expose from the Step's container. Exposing a port here gives the system additional information about the network connections a container uses, but is primarily informational. Not specifying a port here DOES NOT prevent that port from being exposed. Any port which is listening on the default \"0.0.0.0\" address inside a container will be accessible from the network. Cannot be updated.\n\nDeprecated: This field will be removed in a future release.", "type": "array", diff --git a/pkg/apis/pipeline/v1beta1/task_conversion_test.go b/pkg/apis/pipeline/v1beta1/task_conversion_test.go index 043b595e2cc..5ec20da9acb 100644 --- a/pkg/apis/pipeline/v1beta1/task_conversion_test.go +++ b/pkg/apis/pipeline/v1beta1/task_conversion_test.go @@ -83,6 +83,9 @@ spec: steps: - ref: name: "step-action" + params: + - name: param1 + value: hello ` remoteStepActionTaskYAML := ` diff --git a/pkg/apis/pipeline/v1beta1/task_validation.go b/pkg/apis/pipeline/v1beta1/task_validation.go index 62944aec850..e623acbe115 100644 --- a/pkg/apis/pipeline/v1beta1/task_validation.go +++ b/pkg/apis/pipeline/v1beta1/task_validation.go @@ -306,6 +306,12 @@ func validateStep(ctx context.Context, s Step, names sets.String) (errs *apis.Fi }) } } else { + if len(s.Params) > 0 { + errs = errs.Also(&apis.FieldError{ + Message: "params cannot be used without Ref", + Paths: []string{"params"}, + }) + } if s.Image == "" { errs = errs.Also(apis.ErrMissingField("Image")) } diff --git a/pkg/apis/pipeline/v1beta1/task_validation_test.go b/pkg/apis/pipeline/v1beta1/task_validation_test.go index f47263654d3..4d09149fa7e 100644 --- a/pkg/apis/pipeline/v1beta1/task_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/task_validation_test.go @@ -538,6 +538,16 @@ func TestTaskSpecStepActionReferenceValidate(t *testing.T) { Name: "stepAction", }, }}, + }, { + name: "valid use of params with Ref", + Steps: []v1beta1.Step{{ + Ref: &v1beta1.Ref{ + Name: "stepAction", + }, + Params: v1beta1.Params{{ + Name: "param", + }}, + }}, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -1503,6 +1513,19 @@ func TestTaskSpecValidateErrorWithStepActionRef(t *testing.T) { Message: "env cannot be used with Ref", Paths: []string{"steps[0].env"}, }, + }, { + name: "Cannot use params without Ref", + Steps: []v1beta1.Step{{ + Image: "my-image", + Params: v1beta1.Params{{ + Name: "param", + }}, + }}, + enableStepActions: true, + expectedError: apis.FieldError{ + Message: "params cannot be used without Ref", + Paths: []string{"steps[0].params"}, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go index 060142c2e55..923c113107c 100644 --- a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go @@ -1762,6 +1762,13 @@ func (in *Step) DeepCopyInto(out *Step) { *out = new(Ref) (*in).DeepCopyInto(*out) } + if in.Params != nil { + in, out := &in.Params, &out.Params + *out = make(Params, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return }