@@ -18,7 +18,6 @@ package resources
18
18
19
19
import (
20
20
"fmt"
21
- "reflect"
22
21
23
22
"github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1"
24
23
"github.com/tektoncd/pipeline/pkg/reconciler/pipeline/dag"
@@ -203,53 +202,31 @@ func (facts *PipelineRunFacts) GetPipelineConditionStatus(pr *v1beta1.PipelineRu
203
202
}
204
203
}
205
204
206
- allTasks := []string {}
207
- withStatusTasks := []string {}
208
- skipTasks := []v1beta1.SkippedTask {}
209
- failedTasks := int (0 )
210
- cancelledTasks := int (0 )
211
- reason := v1beta1 .PipelineRunReasonSuccessful .String ()
212
-
213
- // Check to see if all tasks are success or skipped
214
- //
215
- // The completion reason is also calculated here, but it will only be used
216
- // if all tasks are completed.
217
- //
218
- // The pipeline run completion reason is set from the taskrun completion reason
219
- // according to the following logic:
220
- //
221
- // - All successful: ReasonSucceeded
222
- // - Some successful, some skipped: ReasonCompleted
223
- // - Some cancelled, none failed: ReasonCancelled
224
- // - At least one failed: ReasonFailed
225
- for _ , rprt := range facts .State {
226
- allTasks = append (allTasks , rprt .PipelineTask .Name )
227
- switch {
228
- case rprt .IsSuccessful ():
229
- withStatusTasks = append (withStatusTasks , rprt .PipelineTask .Name )
230
- case rprt .Skip (facts ):
231
- withStatusTasks = append (withStatusTasks , rprt .PipelineTask .Name )
232
- skipTasks = append (skipTasks , v1beta1.SkippedTask {Name : rprt .PipelineTask .Name })
233
- // At least one is skipped and no failure yet, mark as completed
234
- if reason == v1beta1 .PipelineRunReasonSuccessful .String () {
235
- reason = v1beta1 .PipelineRunReasonCompleted .String ()
236
- }
237
- case rprt .IsCancelled ():
238
- cancelledTasks ++
239
- withStatusTasks = append (withStatusTasks , rprt .PipelineTask .Name )
240
- if reason != v1beta1 .PipelineRunReasonFailed .String () {
241
- reason = v1beta1 .PipelineRunReasonCancelled .String ()
242
- }
243
- case rprt .IsFailure ():
244
- withStatusTasks = append (withStatusTasks , rprt .PipelineTask .Name )
245
- failedTasks ++
246
- reason = v1beta1 .PipelineRunReasonFailed .String ()
247
- }
248
- }
205
+ // report the count in PipelineRun Status
206
+ // get the count of successful tasks, failed tasks, cancelled tasks, skipped task, and incomplete tasks
207
+ sTasks , fTasks , cTasks , skTasks , iTasks := facts .getPipelineTasksCount ()
208
+ // completed task is a collection of successful, failed, cancelled tasks (skipped tasks are reported separately)
209
+ cmTasks := sTasks + fTasks + cTasks
249
210
250
- if reflect .DeepEqual (allTasks , withStatusTasks ) {
211
+ // The completion reason is set from the TaskRun completion reason
212
+ // by default, set it to ReasonRunning
213
+ reason := v1beta1 .PipelineRunReasonRunning .String ()
214
+
215
+ // check if the pipeline is finished executing all tasks i.e. no incomplete tasks
216
+ if iTasks == 0 {
251
217
status := corev1 .ConditionTrue
252
- if failedTasks > 0 || cancelledTasks > 0 {
218
+ reason := v1beta1 .PipelineRunReasonSuccessful .String ()
219
+ // Set reason to ReasonCompleted - At least one is skipped
220
+ if skTasks > 0 {
221
+ reason = v1beta1 .PipelineRunReasonCompleted .String ()
222
+ }
223
+ // Set reason to ReasonFailed - At least one failed
224
+ if fTasks > 0 {
225
+ reason = v1beta1 .PipelineRunReasonFailed .String ()
226
+ status = corev1 .ConditionFalse
227
+ // Set reason to ReasonCancelled - At least one is cancelled and no failure yet
228
+ } else if cTasks > 0 {
229
+ reason = v1beta1 .PipelineRunReasonCancelled .String ()
253
230
status = corev1 .ConditionFalse
254
231
}
255
232
logger .Infof ("All TaskRuns have finished for PipelineRun %s so it has finished" , pr .Name )
@@ -258,28 +235,29 @@ func (facts *PipelineRunFacts) GetPipelineConditionStatus(pr *v1beta1.PipelineRu
258
235
Status : status ,
259
236
Reason : reason ,
260
237
Message : fmt .Sprintf ("Tasks Completed: %d (Failed: %d, Cancelled %d), Skipped: %d" ,
261
- len ( allTasks ) - len ( skipTasks ), failedTasks , cancelledTasks , len ( skipTasks ) ),
238
+ cmTasks , fTasks , cTasks , skTasks ),
262
239
}
263
240
}
264
241
265
242
// Hasn't timed out; not all tasks have finished.... Must keep running then....
266
243
// transition pipeline into stopping state when one of the tasks(dag/final) cancelled or one of the dag tasks failed
267
244
// for a pipeline with final tasks, single dag task failure does not transition to interim stopping state
268
245
// pipeline stays in running state until all final tasks are done before transitioning to failed state
269
- if cancelledTasks > 0 || (failedTasks > 0 && facts .checkFinalTasksDone ()) {
246
+ if cTasks > 0 || (fTasks > 0 && facts .checkFinalTasksDone ()) {
270
247
reason = v1beta1 .PipelineRunReasonStopping .String ()
271
- } else {
272
- reason = v1beta1 .PipelineRunReasonRunning .String ()
273
248
}
249
+
250
+ // return the status
274
251
return & apis.Condition {
275
252
Type : apis .ConditionSucceeded ,
276
253
Status : corev1 .ConditionUnknown ,
277
254
Reason : reason ,
278
255
Message : fmt .Sprintf ("Tasks Completed: %d (Failed: %d, Cancelled %d), Incomplete: %d, Skipped: %d" ,
279
- len ( withStatusTasks ) - len ( skipTasks ), failedTasks , cancelledTasks , len ( allTasks ) - len ( withStatusTasks ), len ( skipTasks ) ),
256
+ cmTasks , fTasks , cTasks , iTasks , skTasks ),
280
257
}
281
258
}
282
259
260
+ // GetSkippedTasks constructs a list of SkippedTask struct to be included in the PipelineRun Status
283
261
func (facts * PipelineRunFacts ) GetSkippedTasks () []v1beta1.SkippedTask {
284
262
skipped := []v1beta1.SkippedTask {}
285
263
for _ , rprt := range facts .State {
@@ -336,6 +314,31 @@ func (facts *PipelineRunFacts) checkFinalTasksDone() bool {
336
314
return facts .checkTasksDone (facts .FinalTasksGraph )
337
315
}
338
316
317
+ // getPipelineTasksCount returns the count of successful tasks, failed tasks, cancelled tasks, skipped task, and incomplete tasks
318
+ func (facts * PipelineRunFacts ) getPipelineTasksCount () (int , int , int , int , int ) {
319
+ s , f , c , sk , i := 0 , 0 , 0 , 0 , 0
320
+ for _ , t := range facts .State {
321
+ switch {
322
+ // increment success counter since the task is successful
323
+ case t .IsSuccessful ():
324
+ s ++
325
+ // increment failure counter since the task has failed
326
+ case t .IsFailure ():
327
+ f ++
328
+ // increment cancelled counter since the task is cancelled
329
+ case t .IsCancelled ():
330
+ c ++
331
+ // increment skip counter since the task is skipped
332
+ case t .Skip (facts ):
333
+ sk ++
334
+ // increment incomplete counter since the task is pending and not executed yet
335
+ default :
336
+ i ++
337
+ }
338
+ }
339
+ return s , f , c , sk , i
340
+ }
341
+
339
342
// check if a specified pipelineTask is defined under tasks(DAG) section
340
343
func (facts * PipelineRunFacts ) isDAGTask (pipelineTaskName string ) bool {
341
344
if _ , ok := facts .TasksGraph .Nodes [pipelineTaskName ]; ok {
0 commit comments