@@ -1196,6 +1196,53 @@ func (c *Reconciler) updatePipelineRunStatusFromInformer(ctx context.Context, pr
1196
1196
return nil
1197
1197
}
1198
1198
1199
+ // filterTaskRunsForPipelineRun returns TaskRuns owned by the PipelineRun and their condition checks
1200
+ func filterTaskRunsForPipelineRun (logger * zap.SugaredLogger , pr * v1beta1.PipelineRun , trs []* v1beta1.TaskRun ) ([]* v1beta1.TaskRun , map [string ][]* v1beta1.TaskRun ) {
1201
+ var normalTaskRuns []* v1beta1.TaskRun
1202
+ conditionTaskRuns := make (map [string ][]* v1beta1.TaskRun )
1203
+
1204
+ for _ , tr := range trs {
1205
+ // Only process TaskRuns that are owned by this PipelineRun.
1206
+ // This skips TaskRuns that are indirectly created by the PipelineRun (e.g. by custom tasks).
1207
+ if len (tr .OwnerReferences ) < 1 || tr .OwnerReferences [0 ].UID != pr .ObjectMeta .UID {
1208
+ logger .Debugf ("Found a TaskRun %s that is not owned by this PipelineRun" , tr .Name )
1209
+ continue
1210
+ }
1211
+ lbls := tr .GetLabels ()
1212
+ pipelineTaskName := lbls [pipeline .PipelineTaskLabelKey ]
1213
+ if _ , ok := lbls [pipeline .ConditionCheckKey ]; ok {
1214
+ // Save condition for looping over them after this
1215
+ if _ , ok := conditionTaskRuns [pipelineTaskName ]; ! ok {
1216
+ // If it's the first condition taskrun, initialise the slice
1217
+ conditionTaskRuns [pipelineTaskName ] = []* v1beta1.TaskRun {}
1218
+ }
1219
+ conditionTaskRuns [pipelineTaskName ] = append (conditionTaskRuns [pipelineTaskName ], tr )
1220
+ } else {
1221
+ normalTaskRuns = append (normalTaskRuns , tr )
1222
+ }
1223
+ }
1224
+
1225
+ return normalTaskRuns , conditionTaskRuns
1226
+ }
1227
+
1228
+ // filterRunsForPipelineRun filters the given slice of Runs, returning only those owned by the given PipelineRun.
1229
+ func filterRunsForPipelineRun (logger * zap.SugaredLogger , pr * v1beta1.PipelineRun , runs []* v1alpha1.Run ) []* v1alpha1.Run {
1230
+ var runsToInclude []* v1alpha1.Run
1231
+
1232
+ // Loop over all the Runs associated to Tasks
1233
+ for _ , run := range runs {
1234
+ // Only process Runs that are owned by this PipelineRun.
1235
+ // This skips Runs that are indirectly created by the PipelineRun (e.g. by custom tasks).
1236
+ if len (run .OwnerReferences ) < 1 || run .OwnerReferences [0 ].UID != pr .ObjectMeta .UID {
1237
+ logger .Debugf ("Found a Run %s that is not owned by this PipelineRun" , run .Name )
1238
+ continue
1239
+ }
1240
+ runsToInclude = append (runsToInclude , run )
1241
+ }
1242
+
1243
+ return runsToInclude
1244
+ }
1245
+
1199
1246
func updatePipelineRunStatusFromTaskRuns (logger * zap.SugaredLogger , pr * v1beta1.PipelineRun , trs []* v1beta1.TaskRun ) {
1200
1247
// If no TaskRun was found, nothing to be done. We never remove taskruns from the status
1201
1248
if trs == nil || len (trs ) == 0 {
@@ -1286,6 +1333,38 @@ func updatePipelineRunStatusFromTaskRuns(logger *zap.SugaredLogger, pr *v1beta1.
1286
1333
}
1287
1334
}
1288
1335
1336
+ // getNewConditionChecksForTaskRun returns a map of condition task name to condition check status for each condition TaskRun
1337
+ // provided which isn't already present in the existing map of condition checks.
1338
+ func getNewConditionChecksForTaskRun (logger * zap.SugaredLogger , existingChecks map [string ]* v1beta1.PipelineRunConditionCheckStatus ,
1339
+ actualConditionTaskRuns []* v1beta1.TaskRun ) map [string ]* v1beta1.PipelineRunConditionCheckStatus {
1340
+ // If we don't have any condition task runs to process, just return nil.
1341
+ if len (actualConditionTaskRuns ) == 0 {
1342
+ return nil
1343
+ }
1344
+
1345
+ newChecks := make (map [string ]* v1beta1.PipelineRunConditionCheckStatus )
1346
+
1347
+ for i , foundTaskRun := range actualConditionTaskRuns {
1348
+ lbls := foundTaskRun .GetLabels ()
1349
+ if _ , ok := existingChecks [foundTaskRun .Name ]; ! ok {
1350
+ // The condition check was not found, so we need to add it
1351
+ // We only add the condition name, the status can now be gathered by the
1352
+ // normal reconcile process
1353
+ if conditionName , ok := lbls [pipeline .ConditionNameKey ]; ok {
1354
+ newChecks [foundTaskRun .Name ] = & v1beta1.PipelineRunConditionCheckStatus {
1355
+ ConditionName : fmt .Sprintf ("%s-%s" , conditionName , strconv .Itoa (i )),
1356
+ }
1357
+ } else {
1358
+ // The condition name label is missing, so we cannot recover this
1359
+ logger .Warnf ("found an orphaned condition taskrun %#v with missing %s label" ,
1360
+ foundTaskRun , pipeline .ConditionNameKey )
1361
+ }
1362
+ }
1363
+ }
1364
+
1365
+ return newChecks
1366
+ }
1367
+
1289
1368
func updatePipelineRunStatusFromRuns (logger * zap.SugaredLogger , pr * v1beta1.PipelineRun , runs []* v1alpha1.Run ) {
1290
1369
// If no Run was found, nothing to be done. We never remove runs from the status
1291
1370
if runs == nil || len (runs ) == 0 {
@@ -1313,3 +1392,96 @@ func updatePipelineRunStatusFromRuns(logger *zap.SugaredLogger, pr *v1beta1.Pipe
1313
1392
}
1314
1393
}
1315
1394
}
1395
+
1396
+ func updatePipelineRunStatusFromChildRefs (logger * zap.SugaredLogger , pr * v1beta1.PipelineRun , trs []* v1beta1.TaskRun , runs []* v1alpha1.Run ) {
1397
+ // If no TaskRun or Run was found, nothing to be done. We never remove child references from the status.
1398
+ // We do still return an empty map of TaskRun/Run names keyed by PipelineTask name for later functions.
1399
+ if len (trs ) == 0 && len (runs ) == 0 {
1400
+ return
1401
+ }
1402
+
1403
+ // Map PipelineTask names to TaskRun child references that were already in the status
1404
+ childRefByPipelineTask := make (map [string ]* v1beta1.ChildStatusReference )
1405
+
1406
+ for i := range pr .Status .ChildReferences {
1407
+ childRefByPipelineTask [pr .Status .ChildReferences [i ].PipelineTaskName ] = & pr .Status .ChildReferences [i ]
1408
+ }
1409
+
1410
+ taskRuns , conditionTaskRuns := filterTaskRunsForPipelineRun (logger , pr , trs )
1411
+
1412
+ // Loop over all the TaskRuns associated to Tasks
1413
+ for _ , tr := range taskRuns {
1414
+ lbls := tr .GetLabels ()
1415
+ pipelineTaskName := lbls [pipeline .PipelineTaskLabelKey ]
1416
+
1417
+ if _ , ok := childRefByPipelineTask [pipelineTaskName ]; ! ok {
1418
+ // This tr was missing from the status.
1419
+ // Add it without conditions, which are handled in the next loop
1420
+ logger .Infof ("Found a TaskRun %s that was missing from the PipelineRun status" , tr .Name )
1421
+
1422
+ // Since this was recovered now, add it to the map, or it might be overwritten
1423
+ childRefByPipelineTask [pipelineTaskName ] = & v1beta1.ChildStatusReference {
1424
+ TypeMeta : runtime.TypeMeta {
1425
+ APIVersion : v1beta1 .SchemeGroupVersion .String (),
1426
+ Kind : "TaskRun" ,
1427
+ },
1428
+ Name : tr .Name ,
1429
+ PipelineTaskName : pipelineTaskName ,
1430
+ }
1431
+ }
1432
+ }
1433
+
1434
+ // Loop over all the Runs associated to Tasks
1435
+ for _ , r := range filterRunsForPipelineRun (logger , pr , runs ) {
1436
+ lbls := r .GetLabels ()
1437
+ pipelineTaskName := lbls [pipeline .PipelineTaskLabelKey ]
1438
+
1439
+ if _ , ok := childRefByPipelineTask [pipelineTaskName ]; ! ok {
1440
+ // This run was missing from the status.
1441
+ // Add it without conditions, which are handled in the next loop
1442
+ logger .Infof ("Found a Run %s that was missing from the PipelineRun status" , r .Name )
1443
+
1444
+ // Since this was recovered now, add it to the map, or it might be overwritten
1445
+ childRefByPipelineTask [pipelineTaskName ] = & v1beta1.ChildStatusReference {
1446
+ TypeMeta : runtime.TypeMeta {
1447
+ APIVersion : v1alpha1 .SchemeGroupVersion .String (),
1448
+ Kind : "Run" ,
1449
+ },
1450
+ Name : r .Name ,
1451
+ PipelineTaskName : pipelineTaskName ,
1452
+ }
1453
+ }
1454
+ }
1455
+
1456
+ // Then loop by pipelinetask name over all the TaskRuns associated to Conditions
1457
+ for pipelineTaskName , actualConditionTaskRuns := range conditionTaskRuns {
1458
+ // GetTaskRunName will look in first ChildReferences and then TaskRuns to see if there's already a TaskRun name
1459
+ // for this pipelineTaskName, and if not, it will generate one.
1460
+ taskRunName := resources .GetTaskRunName (pr .Status .TaskRuns , pr .Status .ChildReferences , pipelineTaskName , pr .Name )
1461
+ if _ , ok := childRefByPipelineTask [pipelineTaskName ]; ! ok {
1462
+ childRefByPipelineTask [pipelineTaskName ] = & v1beta1.ChildStatusReference {
1463
+ TypeMeta : runtime.TypeMeta {
1464
+ APIVersion : v1beta1 .SchemeGroupVersion .String (),
1465
+ Kind : "TaskRun" ,
1466
+ },
1467
+ Name : taskRunName ,
1468
+ PipelineTaskName : pipelineTaskName ,
1469
+ }
1470
+ }
1471
+
1472
+ for k , v := range getNewConditionChecksForTaskRun (logger , childRefByPipelineTask [pipelineTaskName ].GetConditionChecks (), actualConditionTaskRuns ) {
1473
+ // Just append any new condition checks to the relevant ChildStatusReference.ConditionChecks.
1474
+ childRefByPipelineTask [pipelineTaskName ].ConditionChecks = append (childRefByPipelineTask [pipelineTaskName ].ConditionChecks ,
1475
+ & v1beta1.PipelineRunChildConditionCheckStatus {
1476
+ PipelineRunConditionCheckStatus : * v ,
1477
+ ConditionCheckName : k ,
1478
+ })
1479
+ }
1480
+ }
1481
+
1482
+ var newChildRefs []v1beta1.ChildStatusReference
1483
+ for k := range childRefByPipelineTask {
1484
+ newChildRefs = append (newChildRefs , * childRefByPipelineTask [k ])
1485
+ }
1486
+ pr .Status .ChildReferences = newChildRefs
1487
+ }
0 commit comments