Skip to content

Commit a59fa82

Browse files
committed
refactoring get condition status for pipeline
GetPipelineConditionStatus based on a new structure PipelineRunFacts PR # 3254 applied refactoring and introduced PipelineRunFacts to simplify PipelineRun. This is a follow up PR to further simplify GetPipelineConditionStatus.
1 parent 09c7fe2 commit a59fa82

File tree

1 file changed

+70
-51
lines changed

1 file changed

+70
-51
lines changed

pkg/reconciler/pipelinerun/resources/pipelinerunstate.go

+70-51
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ package resources
1818

1919
import (
2020
"fmt"
21-
"reflect"
2221

2322
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
2423
"github.com/tektoncd/pipeline/pkg/reconciler/pipeline/dag"
@@ -193,53 +192,30 @@ func (facts *PipelineRunFacts) GetPipelineConditionStatus(pr *v1beta1.PipelineRu
193192
}
194193
}
195194

196-
allTasks := []string{}
197-
withStatusTasks := []string{}
198-
skipTasks := []v1beta1.SkippedTask{}
199-
failedTasks := int(0)
200-
cancelledTasks := int(0)
201-
reason := v1beta1.PipelineRunReasonSuccessful.String()
202-
203-
// Check to see if all tasks are success or skipped
204-
//
205-
// The completion reason is also calculated here, but it will only be used
206-
// if all tasks are completed.
207-
//
208-
// The pipeline run completion reason is set from the taskrun completion reason
209-
// according to the following logic:
210-
//
211-
// - All successful: ReasonSucceeded
212-
// - Some successful, some skipped: ReasonCompleted
213-
// - Some cancelled, none failed: ReasonCancelled
214-
// - At least one failed: ReasonFailed
215-
for _, rprt := range facts.State {
216-
allTasks = append(allTasks, rprt.PipelineTask.Name)
217-
switch {
218-
case rprt.IsSuccessful():
219-
withStatusTasks = append(withStatusTasks, rprt.PipelineTask.Name)
220-
case rprt.Skip(facts):
221-
withStatusTasks = append(withStatusTasks, rprt.PipelineTask.Name)
222-
skipTasks = append(skipTasks, v1beta1.SkippedTask{Name: rprt.PipelineTask.Name})
223-
// At least one is skipped and no failure yet, mark as completed
224-
if reason == v1beta1.PipelineRunReasonSuccessful.String() {
225-
reason = v1beta1.PipelineRunReasonCompleted.String()
226-
}
227-
case rprt.IsCancelled():
228-
cancelledTasks++
229-
withStatusTasks = append(withStatusTasks, rprt.PipelineTask.Name)
230-
if reason != v1beta1.PipelineRunReasonFailed.String() {
231-
reason = v1beta1.PipelineRunReasonCancelled.String()
232-
}
233-
case rprt.IsFailure():
234-
withStatusTasks = append(withStatusTasks, rprt.PipelineTask.Name)
235-
failedTasks++
236-
reason = v1beta1.PipelineRunReasonFailed.String()
237-
}
238-
}
195+
// report the count in PipelineRun Status
196+
// get the count of successful tasks, failed tasks, cancelled tasks, skipped task, and incomplete tasks
197+
sTasks, fTasks, cTasks, skTasks, iTasks := facts.getPipelineTasksCount()
198+
// completed task is a collection of successful, failed, cancelled tasks (skipped tasks are reported separately)
199+
cmTasks := sTasks + fTasks + cTasks
239200

240-
if reflect.DeepEqual(allTasks, withStatusTasks) {
201+
// The completion reason is set from the TaskRun completion reason
202+
// by default, set it to ReasonRunning
203+
reason := v1beta1.PipelineRunReasonRunning.String()
204+
205+
if facts.checkAllTasksDone() {
241206
status := corev1.ConditionTrue
242-
if failedTasks > 0 || cancelledTasks > 0 {
207+
reason := v1beta1.PipelineRunReasonSuccessful.String()
208+
// Set reason to ReasonCompleted - At least one is skipped
209+
if skTasks > 0 {
210+
reason = v1beta1.PipelineRunReasonCompleted.String()
211+
}
212+
// Set reason to ReasonFailed - At least one failed
213+
if fTasks > 0 {
214+
reason = v1beta1.PipelineRunReasonFailed.String()
215+
status = corev1.ConditionFalse
216+
// Set reason to ReasonCancelled - At least one is cancelled and no failure yet
217+
} else if cTasks > 0 {
218+
reason = v1beta1.PipelineRunReasonCancelled.String()
243219
status = corev1.ConditionFalse
244220
}
245221
logger.Infof("All TaskRuns have finished for PipelineRun %s so it has finished", pr.Name)
@@ -248,28 +224,29 @@ func (facts *PipelineRunFacts) GetPipelineConditionStatus(pr *v1beta1.PipelineRu
248224
Status: status,
249225
Reason: reason,
250226
Message: fmt.Sprintf("Tasks Completed: %d (Failed: %d, Cancelled %d), Skipped: %d",
251-
len(allTasks)-len(skipTasks), failedTasks, cancelledTasks, len(skipTasks)),
227+
cmTasks, fTasks, cTasks, skTasks),
252228
}
253229
}
254230

255231
// Hasn't timed out; not all tasks have finished.... Must keep running then....
256232
// transition pipeline into stopping state when one of the tasks(dag/final) cancelled or one of the dag tasks failed
257233
// for a pipeline with final tasks, single dag task failure does not transition to interim stopping state
258234
// pipeline stays in running state until all final tasks are done before transitioning to failed state
259-
if cancelledTasks > 0 || (failedTasks > 0 && facts.CheckFinalTasksDone()) {
235+
if cTasks > 0 || (fTasks > 0 && facts.CheckFinalTasksDone()) {
260236
reason = v1beta1.PipelineRunReasonStopping.String()
261-
} else {
262-
reason = v1beta1.PipelineRunReasonRunning.String()
263237
}
238+
239+
// return the status
264240
return &apis.Condition{
265241
Type: apis.ConditionSucceeded,
266242
Status: corev1.ConditionUnknown,
267243
Reason: reason,
268244
Message: fmt.Sprintf("Tasks Completed: %d (Failed: %d, Cancelled %d), Incomplete: %d, Skipped: %d",
269-
len(withStatusTasks)-len(skipTasks), failedTasks, cancelledTasks, len(allTasks)-len(withStatusTasks), len(skipTasks)),
245+
cmTasks, fTasks, cTasks, iTasks, skTasks),
270246
}
271247
}
272248

249+
// GetSkippedTasks constructs a list of SkippedTask struct to be included in the PipelineRun Status
273250
func (facts *PipelineRunFacts) GetSkippedTasks() []v1beta1.SkippedTask {
274251
skipped := []v1beta1.SkippedTask{}
275252
for _, rprt := range facts.State {
@@ -329,6 +306,48 @@ func (state PipelineRunState) GetTaskRunsStatus(pr *v1beta1.PipelineRun) map[str
329306
return status
330307
}
331308

309+
// checkAllTasksDone returns true if all DAG and finally tasks have been visited and executed
310+
// tasks could have either executed successfully or failed or cancelled or skipped
311+
func (facts *PipelineRunFacts) checkAllTasksDone() bool {
312+
for _, t := range facts.State {
313+
if t.TaskRun == nil {
314+
if t.Skip(facts) {
315+
continue
316+
}
317+
return false
318+
}
319+
if !t.IsDone() && !t.IsCancelled() {
320+
return false
321+
}
322+
}
323+
return true
324+
}
325+
326+
// getPipelineTasksCount returns the count of successful tasks, failed tasks, cancelled tasks, skipped task, and incomplete tasks
327+
func (facts *PipelineRunFacts) getPipelineTasksCount() (int, int, int, int, int) {
328+
s, f, c, sk, i := 0, 0, 0, 0, 0
329+
for _, t := range facts.State {
330+
switch {
331+
// increment success counter since the task is successful
332+
case t.IsSuccessful():
333+
s++
334+
// increment failure counter since the task has failed
335+
case t.IsFailure():
336+
f++
337+
// increment cancelled counter since the task is cancelled
338+
case t.IsCancelled():
339+
c++
340+
// increment skip counter since the task is skipped
341+
case t.Skip(facts):
342+
sk++
343+
// increment incomplete counter since the task is pending and not executed yet
344+
default:
345+
i++
346+
}
347+
}
348+
return s, f, c, sk, i
349+
}
350+
332351
func (facts *PipelineRunFacts) isDAGTask(pipelineTaskName string) bool {
333352
if _, ok := facts.TasksGraph.Nodes[pipelineTaskName]; ok {
334353
return true

0 commit comments

Comments
 (0)