diff --git a/server/model/step.go b/server/model/step.go index b0418c13a..e6189f095 100644 --- a/server/model/step.go +++ b/server/model/step.go @@ -53,7 +53,7 @@ func (p *Step) Running() bool { // Failing returns true if the process state is failed, killed or error. func (p *Step) Failing() bool { - return p.Failure == FailureFail && (p.State == StatusError || p.State == StatusKilled || p.State == StatusFailure) + return p.State == StatusError || p.State == StatusKilled || p.State == StatusFailure } // StepType identifies the type of step. diff --git a/server/model/step_test.go b/server/model/step_test.go index 0f8df8650..301d0326f 100644 --- a/server/model/step_test.go +++ b/server/model/step_test.go @@ -31,9 +31,9 @@ func TestStepStatus(t *testing.T) { step.Failure = FailureIgnore step.State = StatusError - assert.Equal(t, step.Failing(), false) + assert.Equal(t, step.Failing(), true) step.State = StatusFailure - assert.Equal(t, step.Failing(), false) + assert.Equal(t, step.Failing(), true) step.Failure = FailureFail step.State = StatusError assert.Equal(t, step.Failing(), true) diff --git a/server/pipeline/workflow_status.go b/server/pipeline/workflow_status.go index 6174aca13..143408a10 100644 --- a/server/pipeline/workflow_status.go +++ b/server/pipeline/workflow_status.go @@ -25,7 +25,9 @@ func WorkflowStatus(steps []*model.Step) model.StatusValue { status := model.StatusSuccess for _, p := range steps { - status = MergeStatusValues(status, p.State) + if p.Failure == model.FailureFail || !p.Failing() { + status = MergeStatusValues(status, p.State) + } } return status diff --git a/server/pipeline/workflow_status_test.go b/server/pipeline/workflow_status_test.go index b5740ca8b..09b21b1ed 100644 --- a/server/pipeline/workflow_status_test.go +++ b/server/pipeline/workflow_status_test.go @@ -25,6 +25,160 @@ import ( store_mocks "go.woodpecker-ci.org/woodpecker/v3/server/store/mocks" ) +func TestWorkflowStatus(t *testing.T) { + tests := []struct { + s []*model.Step + e model.StatusValue + }{ + { + s: []*model.Step{ + { + State: model.StatusFailure, + Failure: model.FailureIgnore, + }, + { + State: model.StatusSuccess, + Failure: model.FailureFail, + }, + }, + e: model.StatusSuccess, + }, + { + s: []*model.Step{ + { + State: model.StatusSuccess, + Failure: model.FailureFail, + }, + { + State: model.StatusSuccess, + Failure: model.FailureIgnore, + }, + }, + e: model.StatusSuccess, + }, + { + s: []*model.Step{ + { + State: model.StatusFailure, + Failure: model.FailureFail, + }, + { + State: model.StatusSuccess, + Failure: model.FailureFail, + }, + }, + e: model.StatusFailure, + }, + { + s: []*model.Step{ + { + State: model.StatusSuccess, + Failure: model.FailureFail, + }, + { + State: model.StatusPending, + Failure: model.FailureFail, + }, + }, + e: model.StatusPending, + }, + { + s: []*model.Step{ + { + State: model.StatusSuccess, + Failure: model.FailureFail, + }, + { + State: model.StatusPending, + Failure: model.FailureIgnore, + }, + }, + e: model.StatusPending, + }, + { + s: []*model.Step{ + { + State: model.StatusSuccess, + Failure: model.FailureIgnore, + }, + { + State: model.StatusPending, + Failure: model.FailureFail, + }, + }, + e: model.StatusPending, + }, + { + s: []*model.Step{ + { + State: model.StatusSuccess, + Failure: model.FailureIgnore, + }, + { + State: model.StatusPending, + Failure: model.FailureIgnore, + }, + }, + e: model.StatusPending, + }, + { + s: []*model.Step{ + { + State: model.StatusRunning, + Failure: model.FailureFail, + }, + { + State: model.StatusPending, + Failure: model.FailureFail, + }, + }, + e: model.StatusRunning, + }, + { + s: []*model.Step{ + { + State: model.StatusRunning, + Failure: model.FailureIgnore, + }, + { + State: model.StatusPending, + Failure: model.FailureIgnore, + }, + }, + e: model.StatusRunning, + }, + { + s: []*model.Step{ + { + State: model.StatusRunning, + Failure: model.FailureIgnore, + }, + { + State: model.StatusPending, + Failure: model.FailureFail, + }, + }, + e: model.StatusRunning, + }, + { + s: []*model.Step{ + { + State: model.StatusRunning, + Failure: model.FailureFail, + }, + { + State: model.StatusPending, + Failure: model.FailureIgnore, + }, + }, + e: model.StatusRunning, + }, + } + for _, tt := range tests { + assert.Equal(t, tt.e, WorkflowStatus(tt.s)) + } +} + func TestUpdateWorkflowStatusToRunning(t *testing.T) { t.Run("should update workflow to running status", func(t *testing.T) { workflow := model.Workflow{