diff --git a/cmd/server/flags.go b/cmd/server/flags.go index bf5f704c9..ae3c7b9c5 100644 --- a/cmd/server/flags.go +++ b/cmd/server/flags.go @@ -244,7 +244,7 @@ var flags = []cli.Flag{ EnvVars: []string{"WOODPECKER_STATUS_CONTEXT_FORMAT"}, Name: "status-context-format", Usage: "status context format", - Value: "{{ .context }}/{{ .event }}/{{ .pipeline }}", + Value: "{{ .context }}/{{ .event }}/{{ .workflow }}", }, &cli.BoolFlag{ EnvVars: []string{"WOODPECKER_MIGRATIONS_ALLOW_LONG"}, diff --git a/pipeline/stepBuilder.go b/pipeline/stepBuilder.go index 620ada31a..3e5afc584 100644 --- a/pipeline/stepBuilder.go +++ b/pipeline/stepBuilder.go @@ -302,6 +302,7 @@ func SetPipelineStepsOnPipeline(pipeline *model.Pipeline, pipelineItems []*Item) PID: pidSequence, PPID: item.Workflow.PID, State: model.StatusPending, + Failure: step.Failure, } if item.Workflow.State == model.StatusSkipped { step.State = model.StatusSkipped diff --git a/server/model/step.go b/server/model/step.go index c751b5b63..2922f3f11 100644 --- a/server/model/step.go +++ b/server/model/step.go @@ -26,6 +26,13 @@ type StepStore interface { StepClear(*Pipeline) error } +// Different ways to handle failure states +const ( + FailureIgnore = "ignore" + FailureFail = "fail" + // FailureCancel = "cancel" // Not implemented yet +) + // Step represents a process in the pipeline. type Step struct { ID int64 `json:"id" xorm:"pk autoincr 'step_id'"` @@ -36,6 +43,7 @@ type Step struct { Name string `json:"name" xorm:"step_name"` State StatusValue `json:"state" xorm:"step_state"` Error string `json:"error,omitempty" xorm:"VARCHAR(500) step_error"` + Failure string `json:"-" xorm:"step_failure"` ExitCode int `json:"exit_code" xorm:"step_exit_code"` Started int64 `json:"start_time,omitempty" xorm:"step_started"` Stopped int64 `json:"end_time,omitempty" xorm:"step_stopped"` @@ -57,5 +65,5 @@ func (p *Step) Running() bool { // Failing returns true if the process state is failed, killed or error. func (p *Step) Failing() bool { - return p.State == StatusError || p.State == StatusKilled || p.State == StatusFailure + return p.Failure == FailureFail && (p.State == StatusError || p.State == StatusKilled || p.State == StatusFailure) } diff --git a/server/model/workflow.go b/server/model/workflow.go index 067348492..b594631bd 100644 --- a/server/model/workflow.go +++ b/server/model/workflow.go @@ -61,7 +61,7 @@ func IsThereRunningStage(workflows []*Workflow) bool { return false } -// PipelineStatus determine pipeline status based on corresponding step list +// PipelineStatus determine pipeline status based on corresponding workflow list func PipelineStatus(workflows []*Workflow) StatusValue { status := StatusSuccess @@ -73,3 +73,17 @@ func PipelineStatus(workflows []*Workflow) StatusValue { return status } + +// WorkflowStatus determine workflow status based on corresponding step list +func WorkflowStatus(steps []*Step) StatusValue { + status := StatusSuccess + + for _, p := range steps { + if p.Failing() { + status = p.State + break + } + } + + return status +} diff --git a/server/pipeline/workflowStatus.go b/server/pipeline/workflowStatus.go index 7bf473f84..9ce2b23b2 100644 --- a/server/pipeline/workflowStatus.go +++ b/server/pipeline/workflowStatus.go @@ -36,7 +36,7 @@ func UpdateWorkflowStatusToDone(store model.UpdateWorkflowStore, workflow model. if state.Started == 0 { workflow.State = model.StatusSkipped } else { - workflow.State = model.StatusSuccess + workflow.State = model.WorkflowStatus(workflow.Children) } if workflow.Error != "" { workflow.State = model.StatusFailure diff --git a/server/store/datastore/migration/020_parent_steps_to_workflows.go b/server/store/datastore/migration/020_parent_steps_to_workflows.go index 19589a3f8..aa4e77cd9 100644 --- a/server/store/datastore/migration/020_parent_steps_to_workflows.go +++ b/server/store/datastore/migration/020_parent_steps_to_workflows.go @@ -20,7 +20,7 @@ import ( "github.com/woodpecker-ci/woodpecker/server/model" ) -type oldStep018 struct { +type oldStep020 struct { ID int64 `xorm:"pk autoincr 'step_id'"` PipelineID int64 `xorm:"UNIQUE(s) INDEX 'step_pipeline_id'"` PID int `xorm:"UNIQUE(s) 'step_pid'"` @@ -35,7 +35,7 @@ type oldStep018 struct { Environ map[string]string `xorm:"json 'step_environ'"` } -func (oldStep018) TableName() string { +func (oldStep020) TableName() string { return "steps" } @@ -47,11 +47,11 @@ var parentStepsToWorkflows = task{ return err } // make sure the columns exist before removing them - if err := sess.Sync(new(oldStep018)); err != nil { + if err := sess.Sync(new(oldStep020)); err != nil { return err } - var parentSteps []*oldStep018 + var parentSteps []*oldStep020 err := sess.Where("step_ppid = ?", 0).Find(&parentSteps) if err != nil { return err @@ -76,7 +76,7 @@ var parentStepsToWorkflows = task{ return err } - _, err = sess.Delete(&oldStep018{ID: p.ID}) + _, err = sess.Delete(&oldStep020{ID: p.ID}) if err != nil { return err }