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
}