diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index c4267286f6e..573745f4a61 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -2851,6 +2851,23 @@ PipelineSpec Note: PipelineSpec is in preview mode and not yet supported
+onError
OnError defines the exiting behavior of a PipelineRun on error +can be set to [ continue | stopAndFail ] +Note: OnError is in preview mode and not yet supported +TODO(#7165)
+string
alias)+(Appears on:PipelineTask) +
+PipelineTaskOnErrorType defines a list of supported failure handling behaviors of a PipelineTask on error
+Value | +Description | +
---|---|
"continue" |
+PipelineTaskContinue indicates to continue executing the rest of the DAG when the PipelineTask fails + |
+
"stopAndFail" |
+PipelineTaskStopAndFail indicates to stop and fail the PipelineRun if the PipelineTask fails + |
+
onError
OnError defines the exiting behavior of a PipelineRun on error +can be set to [ continue | stopAndFail ] +Note: OnError is in preview mode and not yet supported +TODO(#7165)
+string
alias)+(Appears on:PipelineTask) +
+PipelineTaskOnErrorType defines a list of supported failure handling behaviors of a PipelineTask on error
+diff --git a/docs/pipelines.md b/docs/pipelines.md index de114f4ec72..077d25d7cc6 100644 --- a/docs/pipelines.md +++ b/docs/pipelines.md @@ -21,6 +21,8 @@ weight: 203 - [Tekton Bundles](#tekton-bundles) - [Using the `runAfter` field](#using-the-runafter-field) - [Using the `retries` field](#using-the-retries-field) + - [Using the `onError` field](#using-the-onerror-field) + - [Produce results with `OnError`](#produce-results-with-onerror) - [Guard `Task` execution using `when` expressions](#guard-task-execution-using-when-expressions) - [Guarding a `Task` and its dependent `Tasks`](#guarding-a-task-and-its-dependent-tasks) - [Cascade `when` expressions to the specific dependent `Tasks`](#cascade-when-expressions-to-the-specific-dependent-tasks) @@ -606,6 +608,106 @@ tasks: name: build-push ``` +### Using the `onError` field + +> :seedling: **Specifying `onError` in `PipelineTasks` is an [alpha](additional-configs.md#alpha-features) feature.** The `enable-api-fields` feature flag must be set to `"alpha"` to specify `onError` in a `PipelineTask`. + +> :seedling: This feature is in **Preview Only** mode and not yet supported/implemented. + +When a `PipelineTask` fails, the rest of the `PipelineTasks` are skipped and the `PipelineRun` is declared a failure. If you would like to +ignore such `PipelineTask` failure and continue executing the rest of the `PipelineTasks`, you can specify `onError` for such a `PipelineTask`. + +`OnError` can be set to `stopAndFail` (default) and `continue`. The failure of a `PipelineTask` with `stopAndFail` would stop and fail the whole `PipelineRun`. A `PipelineTask` fails with `continue` does not fail the whole `PipelineRun`, and the rest of the `PipelineTask` will continue to execute. + +To ignore a `PipelineTask` failure, set `onError` to `continue`: + +``` yaml +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: demo +spec: + tasks: + - name: task1 + onError: continue + taskSpec: + steps: + - name: step1 + image: alpine + script: | + exit 1 +``` + +At runtime, the failure is ignored to determine the `PipelineRun` status. The `PipelineRun` `message` contains the ignored failure info: + +``` yaml +status: + conditions: + - lastTransitionTime: "2023-09-28T19:08:30Z" + message: 'Tasks Completed: 1 (Failed: 1 (Ignored: 1), Cancelled 0), Skipped: 0' + reason: Succeeded + status: "True" + type: Succeeded + ... +``` + +Note that the `TaskRun` status remains as it is irrelevant to `OnError`. Failed but ignored `TaskRuns` result in a `failed` status with reason +`FailureIgnored`. + +For example, the `TaskRun` created by the above `PipelineRun` has the following status: + +``` bash +$ kubectl get tr demo-run-task1 +NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME +demo-run-task1 False FailureIgnored 12m 12m +``` + +To specify `onError` for a `step`, please see [specifying onError for a step](./tasks.md#specifying-onerror-for-a-step). + +**Note:** Setting [`Retry`](#specifying-retries) and `OnError:continue` at the same time is **NOT** allowed. + +### Produce results with `OnError` + +When a `PipelineTask` is set to ignore error and the `PipelineTask` is able to initialize a result before failing, the result is made available to the consumer `PipelineTasks`. + +``` yaml + tasks: + - name: task1 + onError: continue + taskSpec: + results: + - name: result1 + steps: + - name: step1 + image: alpine + script: | + echo -n 123 | tee $(results.result1.path) + exit 1 +``` + +The consumer `PipelineTasks` can access the result by referencing `$(tasks.task1.results.result1)`. + +If the result is **NOT** initialized before failing, and there is a `PipelineTask` consuming it: + +``` yaml + tasks: + - name: task1 + onError: continue + taskSpec: + results: + - name: result1 + steps: + - name: step1 + image: alpine + script: | + exit 1 + echo -n 123 | tee $(results.result1.path) +``` + +- If the consuming `PipelineTask` has `OnError:stopAndFail`, the `PipelineRun` will fail with `InvalidTaskResultReference`. +- If the consuming `PipelineTask` has `OnError:continue`, the consuming `PipelineTask` will be skipped with reason `Results were missing`, +and the `PipelineRun` will continue to execute. + ### Guard `Task` execution using `when` expressions To run a `Task` only when certain conditions are met, it is possible to _guard_ task execution using the `when` field. The `when` field allows you to list a series of references to `when` expressions. diff --git a/pkg/apis/pipeline/v1/openapi_generated.go b/pkg/apis/pipeline/v1/openapi_generated.go index a48fd8bc68e..b5a14a692f1 100644 --- a/pkg/apis/pipeline/v1/openapi_generated.go +++ b/pkg/apis/pipeline/v1/openapi_generated.go @@ -1892,6 +1892,13 @@ func schema_pkg_apis_pipeline_v1_PipelineTask(ref common.ReferenceCallback) comm Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.PipelineSpec"), }, }, + "onError": { + SchemaProps: spec.SchemaProps{ + Description: "OnError defines the exiting behavior of a PipelineRun on error can be set to [ continue | stopAndFail ] Note: OnError is in preview mode and not yet supported", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/pkg/apis/pipeline/v1/pipeline_types.go b/pkg/apis/pipeline/v1/pipeline_types.go index 25613f1a41a..00482590884 100644 --- a/pkg/apis/pipeline/v1/pipeline_types.go +++ b/pkg/apis/pipeline/v1/pipeline_types.go @@ -27,6 +27,9 @@ import ( "knative.dev/pkg/kmeta" ) +// PipelineTaskOnErrorType defines a list of supported failure handling behaviors of a PipelineTask on error +type PipelineTaskOnErrorType string + const ( // PipelineTasksAggregateStatus is a param representing aggregate status of all dag pipelineTasks PipelineTasksAggregateStatus = "tasks.status" @@ -34,6 +37,10 @@ const ( PipelineTasks = "tasks" // PipelineFinallyTasks is a value representing a task is a member of "finally" section of the pipeline PipelineFinallyTasks = "finally" + // PipelineTaskStopAndFail indicates to stop and fail the PipelineRun if the PipelineTask fails + PipelineTaskStopAndFail PipelineTaskOnErrorType = "stopAndFail" + // PipelineTaskContinue indicates to continue executing the rest of the DAG when the PipelineTask fails + PipelineTaskContinue PipelineTaskOnErrorType = "continue" ) // +genclient @@ -238,6 +245,13 @@ type PipelineTask struct { // Note: PipelineSpec is in preview mode and not yet supported // +optional PipelineSpec *PipelineSpec `json:"pipelineSpec,omitempty"` + + // OnError defines the exiting behavior of a PipelineRun on error + // can be set to [ continue | stopAndFail ] + // Note: OnError is in preview mode and not yet supported + // TODO(#7165) + // +optional + OnError PipelineTaskOnErrorType `json:"onError,omitempty"` } // IsCustomTask checks whether an embedded TaskSpec is a Custom Task diff --git a/pkg/apis/pipeline/v1/pipeline_types_test.go b/pkg/apis/pipeline/v1/pipeline_types_test.go index 0b5ffdc6abd..d4f5ad55dbc 100644 --- a/pkg/apis/pipeline/v1/pipeline_types_test.go +++ b/pkg/apis/pipeline/v1/pipeline_types_test.go @@ -73,6 +73,98 @@ func TestPipelineTask_ValidateName(t *testing.T) { } } +func TestPipelineTask_OnError(t *testing.T) { + tests := []struct { + name string + p PipelineTask + expectedError *apis.FieldError + wc func(context.Context) context.Context + }{{ + name: "valid PipelineTask with onError:continue", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + TaskRef: &TaskRef{Name: "foo"}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "valid PipelineTask with onError:stopAndFail", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskStopAndFail, + TaskRef: &TaskRef{Name: "foo"}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "invalid OnError value", + p: PipelineTask{ + Name: "foo", + OnError: "invalid-val", + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrInvalidValue("invalid-val", "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\""), + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "OnError:stopAndFail and retries coexist - success", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskStopAndFail, + Retries: 1, + TaskRef: &TaskRef{Name: "foo"}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "OnError:continue and retries coexists - failure", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + Retries: 1, + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrGeneric("PipelineTask OnError cannot be set to \"continue\" when Retries is greater than 0"), + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "setting OnError in beta API version - failure", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrGeneric("OnError requires \"enable-api-fields\" feature gate to be \"alpha\" but it is \"beta\""), + wc: cfgtesting.EnableBetaAPIFields, + }, { + name: "setting OnError in stable API version - failure", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrGeneric("OnError requires \"enable-api-fields\" feature gate to be \"alpha\" but it is \"stable\""), + wc: cfgtesting.EnableStableAPIFields, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + if tt.wc != nil { + ctx = tt.wc(ctx) + } + err := tt.p.Validate(ctx) + if tt.expectedError == nil { + if err != nil { + t.Error("PipelineTask.Validate() returned error for valid pipeline task") + } + } else { + if err == nil { + t.Error("PipelineTask.Validate() did not return error for invalid pipeline task with OnError") + } + if d := cmp.Diff(tt.expectedError.Error(), err.Error(), cmpopts.IgnoreUnexported(apis.FieldError{})); d != "" { + t.Errorf("PipelineTask.Validate() errors diff %s", diff.PrintWantGot(d)) + } + } + }) + } +} + func TestPipelineTask_ValidateRefOrSpec(t *testing.T) { tests := []struct { name string diff --git a/pkg/apis/pipeline/v1/pipeline_validation.go b/pkg/apis/pipeline/v1/pipeline_validation.go index 39615dd8828..b3242982dbb 100644 --- a/pkg/apis/pipeline/v1/pipeline_validation.go +++ b/pkg/apis/pipeline/v1/pipeline_validation.go @@ -211,6 +211,17 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { NamespacedTaskKind: true, ClusterTaskRefKind: true, } + + if pt.OnError != "" { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.AlphaAPIFields)) + if pt.OnError != PipelineTaskContinue && pt.OnError != PipelineTaskStopAndFail { + errs = errs.Also(apis.ErrInvalidValue(pt.OnError, "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\"")) + } + if pt.OnError == PipelineTaskContinue && pt.Retries > 0 { + errs = errs.Also(apis.ErrGeneric("PipelineTask OnError cannot be set to \"continue\" when Retries is greater than 0")) + } + } + // Pipeline task having taskRef/taskSpec with APIVersion is classified as custom task switch { case pt.TaskRef != nil && !taskKinds[pt.TaskRef.Kind]: @@ -224,7 +235,7 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { default: errs = errs.Also(pt.validateTask(ctx)) } - return + return errs } func (pt *PipelineTask) validateMatrix(ctx context.Context) (errs *apis.FieldError) { diff --git a/pkg/apis/pipeline/v1/swagger.json b/pkg/apis/pipeline/v1/swagger.json index 43cc932c969..bb031c72730 100644 --- a/pkg/apis/pipeline/v1/swagger.json +++ b/pkg/apis/pipeline/v1/swagger.json @@ -885,6 +885,10 @@ "description": "Name is the name of this task within the context of a Pipeline. Name is used as a coordinate with the `from` and `runAfter` fields to establish the execution order of tasks relative to one another.", "type": "string" }, + "onError": { + "description": "OnError defines the exiting behavior of a PipelineRun on error can be set to [ continue | stopAndFail ] Note: OnError is in preview mode and not yet supported", + "type": "string" + }, "params": { "description": "Parameters declares parameters passed to this task.", "type": "array", diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go index a1ac309a000..74a6be3b64f 100644 --- a/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -2649,6 +2649,13 @@ func schema_pkg_apis_pipeline_v1beta1_PipelineTask(ref common.ReferenceCallback) Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.PipelineSpec"), }, }, + "onError": { + SchemaProps: spec.SchemaProps{ + Description: "OnError defines the exiting behavior of a PipelineRun on error can be set to [ continue | stopAndFail ] Note: OnError is in preview mode and not yet supported", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/pkg/apis/pipeline/v1beta1/pipeline_conversion.go b/pkg/apis/pipeline/v1beta1/pipeline_conversion.go index c4a993fa869..9f5c75a839f 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_conversion.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_conversion.go @@ -167,6 +167,7 @@ func (pt PipelineTask) convertTo(ctx context.Context, sink *v1.PipelineTask, met we.convertTo(ctx, &new) sink.When = append(sink.When, new) } + sink.OnError = (v1.PipelineTaskOnErrorType)(pt.OnError) sink.Retries = pt.Retries sink.RunAfter = pt.RunAfter sink.Params = nil @@ -215,6 +216,7 @@ func (pt *PipelineTask) convertFrom(ctx context.Context, source v1.PipelineTask, new.convertFrom(ctx, we) pt.WhenExpressions = append(pt.WhenExpressions, new) } + pt.OnError = (PipelineTaskOnErrorType)(source.OnError) pt.Retries = source.Retries pt.RunAfter = source.RunAfter pt.Params = nil diff --git a/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go b/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go index 7159723a961..e9ba9cc9032 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_conversion_test.go @@ -60,6 +60,7 @@ func TestPipelineConversion(t *testing.T) { Description: "test", Tasks: []v1beta1.PipelineTask{{ Name: "foo", + OnError: v1beta1.PipelineTaskContinue, TaskRef: &v1beta1.TaskRef{Name: "example.com/my-foo-task"}, }}, Params: []v1beta1.ParamSpec{{ @@ -138,11 +139,13 @@ func TestPipelineConversion(t *testing.T) { DisplayName: "pipeline-display-name", Description: "test", Tasks: []v1beta1.PipelineTask{{ - Name: "task-1", + Name: "task-1", + OnError: v1beta1.PipelineTaskContinue, }, { Name: "foo", DisplayName: "task-display-name", Description: "task-description", + OnError: v1beta1.PipelineTaskContinue, TaskRef: &v1beta1.TaskRef{Name: "example.com/my-foo-task"}, TaskSpec: &v1beta1.EmbeddedTask{ TaskSpec: v1beta1.TaskSpec{ diff --git a/pkg/apis/pipeline/v1beta1/pipeline_types.go b/pkg/apis/pipeline/v1beta1/pipeline_types.go index bbe837a94e5..a5c016b5905 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_types.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_types.go @@ -27,6 +27,9 @@ import ( "knative.dev/pkg/kmeta" ) +// PipelineTaskOnErrorType defines a list of supported failure handling behaviors of a PipelineTask on error +type PipelineTaskOnErrorType string + const ( // PipelineTasksAggregateStatus is a param representing aggregate status of all dag pipelineTasks PipelineTasksAggregateStatus = "tasks.status" @@ -34,6 +37,10 @@ const ( PipelineTasks = "tasks" // PipelineFinallyTasks is a value representing a task is a member of "finally" section of the pipeline PipelineFinallyTasks = "finally" + // PipelineTaskStopAndFail indicates to stop and fail the PipelineRun if the PipelineTask fails + PipelineTaskStopAndFail PipelineTaskOnErrorType = "stopAndFail" + // PipelineTaskContinue indicates to continue executing the rest of the DAG when the PipelineTask fails + PipelineTaskContinue PipelineTaskOnErrorType = "continue" ) // +genclient @@ -252,6 +259,13 @@ type PipelineTask struct { // Note: PipelineSpec is in preview mode and not yet supported // +optional PipelineSpec *PipelineSpec `json:"pipelineSpec,omitempty"` + + // OnError defines the exiting behavior of a PipelineRun on error + // can be set to [ continue | stopAndFail ] + // Note: OnError is in preview mode and not yet supported + // TODO(#7165) + // +optional + OnError PipelineTaskOnErrorType `json:"onError,omitempty"` } // IsCustomTask checks whether an embedded TaskSpec is a Custom Task diff --git a/pkg/apis/pipeline/v1beta1/pipeline_types_test.go b/pkg/apis/pipeline/v1beta1/pipeline_types_test.go index 34b887d4d27..e8b6e051f56 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_types_test.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_types_test.go @@ -73,6 +73,98 @@ func TestPipelineTask_ValidateName(t *testing.T) { } } +func TestPipelineTask_OnError(t *testing.T) { + tests := []struct { + name string + p PipelineTask + expectedError *apis.FieldError + wc func(context.Context) context.Context + }{{ + name: "valid PipelineTask with onError:continue", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + TaskRef: &TaskRef{Name: "foo"}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "valid PipelineTask with onError:stopAndFail", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskStopAndFail, + TaskRef: &TaskRef{Name: "foo"}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "invalid OnError value", + p: PipelineTask{ + Name: "foo", + OnError: "invalid-val", + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrInvalidValue("invalid-val", "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\""), + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "OnError:stopAndFail and retries coexist - success", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskStopAndFail, + Retries: 1, + TaskRef: &TaskRef{Name: "foo"}, + }, + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "OnError:continue and retries coexists - failure", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + Retries: 1, + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrGeneric("PipelineTask OnError cannot be set to \"continue\" when Retries is greater than 0"), + wc: cfgtesting.EnableAlphaAPIFields, + }, { + name: "setting OnError in beta API version - failure", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrGeneric("OnError requires \"enable-api-fields\" feature gate to be \"alpha\" but it is \"beta\""), + wc: cfgtesting.EnableBetaAPIFields, + }, { + name: "setting OnError in stable API version - failure", + p: PipelineTask{ + Name: "foo", + OnError: PipelineTaskContinue, + TaskRef: &TaskRef{Name: "foo"}, + }, + expectedError: apis.ErrGeneric("OnError requires \"enable-api-fields\" feature gate to be \"alpha\" but it is \"stable\""), + wc: cfgtesting.EnableStableAPIFields, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + if tt.wc != nil { + ctx = tt.wc(ctx) + } + err := tt.p.Validate(ctx) + if tt.expectedError == nil { + if err != nil { + t.Error("PipelineTask.Validate() returned error for valid pipeline task") + } + } else { + if err == nil { + t.Error("PipelineTask.Validate() did not return error for invalid pipeline task with OnError") + } + if d := cmp.Diff(tt.expectedError.Error(), err.Error(), cmpopts.IgnoreUnexported(apis.FieldError{})); d != "" { + t.Errorf("PipelineTask.Validate() errors diff %s", diff.PrintWantGot(d)) + } + } + }) + } +} + func TestPipelineTask_ValidateRefOrSpec(t *testing.T) { tests := []struct { name string diff --git a/pkg/apis/pipeline/v1beta1/pipeline_validation.go b/pkg/apis/pipeline/v1beta1/pipeline_validation.go index 87db505c027..572a3e76bd7 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_validation.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_validation.go @@ -159,6 +159,17 @@ func (pt PipelineTask) Validate(ctx context.Context) (errs *apis.FieldError) { NamespacedTaskKind: true, ClusterTaskKind: true, } + + if pt.OnError != "" { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "OnError", config.AlphaAPIFields)) + if pt.OnError != PipelineTaskContinue && pt.OnError != PipelineTaskStopAndFail { + errs = errs.Also(apis.ErrInvalidValue(pt.OnError, "OnError", "PipelineTask OnError must be either \"continue\" or \"stopAndFail\"")) + } + if pt.OnError == PipelineTaskContinue && pt.Retries > 0 { + errs = errs.Also(apis.ErrGeneric("PipelineTask OnError cannot be set to \"continue\" when Retries is greater than 0")) + } + } + cfg := config.FromContextOrDefaults(ctx) // Pipeline task having taskRef/taskSpec with APIVersion is classified as custom task switch { diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json index 8002b1f1b0b..97f789dbcbf 100644 --- a/pkg/apis/pipeline/v1beta1/swagger.json +++ b/pkg/apis/pipeline/v1beta1/swagger.json @@ -1278,6 +1278,10 @@ "description": "Name is the name of this task within the context of a Pipeline. Name is used as a coordinate with the `from` and `runAfter` fields to establish the execution order of tasks relative to one another.", "type": "string" }, + "onError": { + "description": "OnError defines the exiting behavior of a PipelineRun on error can be set to [ continue | stopAndFail ] Note: OnError is in preview mode and not yet supported", + "type": "string" + }, "params": { "description": "Parameters declares parameters passed to this task.", "type": "array",