Add option to ignore failures on steps (#1219)

closes #1181
closes #834 

Adds `ignore_failure` to pipeline steps. When it's set to true,
if the step fails the following steps continue to execute as if no failure had occurred.

---

failure enums idea:
* fail (default) = if other steps run in parallel, wait for them and
then let workflow fail
* cancel = if other steps run in parallel, kill them
* ignore = we mark the step as failed but it wont have any impact
This commit is contained in:
Sergio Fenoll 2022-11-15 19:47:27 +01:00 committed by GitHub
parent de8ea95dd3
commit f0e518a5a2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 42 additions and 1 deletions

View file

@ -206,6 +206,20 @@ Woodpecker provides the ability to store named parameters external to the YAML c
For more details check the [secrets docs](./40-secrets.md). For more details check the [secrets docs](./40-secrets.md).
### `failure`
Some of the pipeline steps may be allowed to fail without causing the whole pipeline to report a failure (e.g., a step executing a linting check). To enable this, add `failure: ignore` to your pipeline step. If Woodpecker encounters an error while executing the step, it will report it as failed but still execute the next steps of the pipeline, if any, without affecting the status of the pipeline.
```diff
pipeline:
backend:
image: golang
commands:
- go build
- go test
+ failure: ignore
```
### `when` - Conditional Execution ### `when` - Conditional Execution
Woodpecker supports defining a list of conditions for a pipeline step by using a `when` block. If at least one of the conditions in the `when` block evaluate to true the step is executed, otherwise it is skipped. A condition can be a check like: Woodpecker supports defining a list of conditions for a pipeline step by using a `when` block. If at least one of the conditions in the `when` block evaluate to true the step is executed, otherwise it is skipped. A condition can be a check like:

View file

@ -28,6 +28,7 @@ type Step struct {
CPUSet string `json:"cpu_set,omitempty"` CPUSet string `json:"cpu_set,omitempty"`
OnFailure bool `json:"on_failure,omitempty"` OnFailure bool `json:"on_failure,omitempty"`
OnSuccess bool `json:"on_success,omitempty"` OnSuccess bool `json:"on_success,omitempty"`
Failure string `json:"failure,omitempty"`
AuthConfig Auth `json:"auth_config,omitempty"` AuthConfig Auth `json:"auth_config,omitempty"`
NetworkMode string `json:"network_mode,omitempty"` NetworkMode string `json:"network_mode,omitempty"`
IpcMode string `json:"ipc_mode,omitempty"` IpcMode string `json:"ipc_mode,omitempty"`

View file

@ -32,6 +32,13 @@ const (
EventManual = "manual" EventManual = "manual"
) )
// Different ways to handle failure states
const (
FailureIgnore = "ignore"
FailureFail = "fail"
// FailureCancel = "cancel" // Not implemented yet
)
type ( type (
// Metadata defines runtime m. // Metadata defines runtime m.
Metadata struct { Metadata struct {

View file

@ -9,6 +9,7 @@ import (
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
backend "github.com/woodpecker-ci/woodpecker/pipeline/backend/types" backend "github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/compiler/settings" "github.com/woodpecker-ci/woodpecker/pipeline/frontend/yaml/compiler/settings"
) )
@ -139,6 +140,11 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section
// at least one constraint must include the status failure. // at least one constraint must include the status failure.
onFailure := container.When.IncludesStatus("failure") onFailure := container.When.IncludesStatus("failure")
failure := container.Failure
if container.Failure == "" {
failure = frontend.FailureFail
}
return &backend.Step{ return &backend.Step{
Name: name, Name: name,
Alias: container.Name, Alias: container.Name,
@ -167,6 +173,7 @@ func (c *Compiler) createProcess(name string, container *yaml.Container, section
AuthConfig: authConfig, AuthConfig: authConfig,
OnSuccess: onSuccess, OnSuccess: onSuccess,
OnFailure: onFailure, OnFailure: onFailure,
Failure: failure,
NetworkMode: networkMode, NetworkMode: networkMode,
IpcMode: ipcMode, IpcMode: ipcMode,
} }

View file

@ -41,6 +41,7 @@ type (
ExtraHosts []string `yaml:"extra_hosts,omitempty"` ExtraHosts []string `yaml:"extra_hosts,omitempty"`
Group string `yaml:"group,omitempty"` Group string `yaml:"group,omitempty"`
Image string `yaml:"image,omitempty"` Image string `yaml:"image,omitempty"`
Failure string `yaml:"failure,omitempty"`
Isolation string `yaml:"isolation,omitempty"` Isolation string `yaml:"isolation,omitempty"`
Labels types.SliceorMap `yaml:"labels,omitempty"` Labels types.SliceorMap `yaml:"labels,omitempty"`
MemLimit types.MemStringorInt `yaml:"mem_limit,omitempty"` MemLimit types.MemStringorInt `yaml:"mem_limit,omitempty"`

View file

@ -11,6 +11,7 @@ import (
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
backend "github.com/woodpecker-ci/woodpecker/pipeline/backend/types" backend "github.com/woodpecker-ci/woodpecker/pipeline/backend/types"
"github.com/woodpecker-ci/woodpecker/pipeline/frontend"
"github.com/woodpecker-ci/woodpecker/pipeline/multipart" "github.com/woodpecker-ci/woodpecker/pipeline/multipart"
) )
@ -193,7 +194,11 @@ func (r *Runtime) execAll(steps []*backend.Step) <-chan error {
} }
// Return the error after tracing it. // Return the error after tracing it.
return r.traceStep(processState, err, step) err = r.traceStep(processState, err, step)
if err != nil && step.Failure == frontend.FailureIgnore {
return nil
}
return err
}) })
} }

View file

@ -237,6 +237,12 @@
"detach": { "detach": {
"description": "Detach a step to run in background until pipeline finishes. Read more: https://woodpecker-ci.org/docs/usage/services#detachment", "description": "Detach a step to run in background until pipeline finishes. Read more: https://woodpecker-ci.org/docs/usage/services#detachment",
"type": "boolean" "type": "boolean"
},
"failure": {
"description": "How to handle the failure of this step. Read more: https://woodpecker-ci.org/docs/usage/pipeline-syntax#failure",
"type": "string",
"enum": ["fail", "ignore"],
"default": "fail"
} }
} }
}, },