@@ -12,6 +12,7 @@ import (
12
12
"path/filepath"
13
13
"regexp"
14
14
"runtime/debug"
15
+ "sort"
15
16
"strconv"
16
17
"strings"
17
18
"time"
@@ -293,53 +294,84 @@ func writeMetafile(metaSpace, metaFile, metaLog string, mergedMeta map[string]in
293
294
return nil
294
295
}
295
296
296
- // SetExternalMeta checks if parent build is external and sets meta in external file accordingly
297
- func SetExternalMeta (api screwdriver.API , pipelineID , parentBuildID int , mergedMeta map [string ]interface {}, metaSpace , metaLog string , join bool ) (map [string ]interface {}, error ) {
297
+ // setParentBuildsMeta checks if parent build is external and sets meta in external file accordingly
298
+ func setParentBuildsMeta (api screwdriver.API , pipelineID int , parentBuildIDs [] int , mergedMeta map [string ]interface {}, metaSpace , metaLog string ) (map [string ]interface {}, error ) {
298
299
var resultMeta = mergedMeta
299
- log .Printf ("Fetching Parent Build %d" , parentBuildID )
300
- parentBuild , err := api .BuildFromID (parentBuildID )
301
- if err != nil {
302
- return resultMeta , fmt .Errorf ("Fetching Parent Build ID %d: %v" , parentBuildID , err )
303
- }
300
+ var isJoin = len (parentBuildIDs ) > 1
304
301
305
- log .Printf ("Fetching Parent Job %d" , parentBuild .JobID )
306
- parentJob , err := api .JobFromID (parentBuild .JobID )
307
- if err != nil {
308
- return resultMeta , fmt .Errorf ("Fetching Job ID %d: %v" , parentBuild .JobID , err )
302
+ parentBuilds := []screwdriver.Build {}
303
+
304
+ for _ , parentBuildId := range parentBuildIDs {
305
+ log .Printf ("Fetching Parent Build %d" , parentBuildId )
306
+
307
+ parentBuild , err := api .BuildFromID (parentBuildId )
308
+
309
+ if err != nil {
310
+ return resultMeta , fmt .Errorf ("Fetching Parent Build ID %d: %v" , parentBuildId , err )
311
+ }
312
+
313
+ parentBuilds = append (parentBuilds , parentBuild )
309
314
}
310
315
311
- if parentBuild .Meta != nil {
316
+ // Sort by Endtime ASC
317
+ // Last finished parent build is priority
318
+ sort .SliceStable (parentBuilds , func (i , j int ) bool {
319
+ return parentBuilds [i ].Endtime .Before (parentBuilds [j ].Endtime )
320
+ })
321
+
322
+ for _ , parentBuild := range parentBuilds {
323
+ if parentBuild .Meta == nil {
324
+ continue
325
+ }
326
+
327
+ log .Printf ("Fetching Parent Job %d" , parentBuild .JobID )
328
+ parentJob , err := api .JobFromID (parentBuild .JobID )
329
+ if err != nil {
330
+ return resultMeta , fmt .Errorf ("Fetching Job ID %d: %v" , parentBuild .JobID , err )
331
+ }
332
+
312
333
// Check if build is from external pipeline
313
- if pipelineID != parentJob .PipelineID {
314
- // Write to "sd@123:component.json", where sd@123:component is the triggering job
315
- externalMetaFile := "sd@" + strconv .Itoa (parentJob .PipelineID ) + ":" + parentJob .Name + ".json"
316
- writeMetafile (metaSpace , externalMetaFile , metaLog , parentBuild .Meta )
317
- if join {
318
- marshallValue , err := json .Marshal (parentBuild .Meta )
319
- if err != nil {
320
- return resultMeta , fmt .Errorf ("Cloning meta of Parent Build ID %d: %v" , parentBuildID , err )
321
- }
322
- var externalParentBuildMeta map [string ]interface {}
323
- json .Unmarshal (marshallValue , & externalParentBuildMeta )
324
-
325
- // Always exclude parameters from external meta
326
- delete (externalParentBuildMeta , "parameters" )
327
-
328
- resultMeta = deepMergeJSON (resultMeta , externalParentBuildMeta )
334
+ if pipelineID == parentJob .PipelineID {
335
+ resultMeta = deepMergeJSON (resultMeta , parentBuild .Meta )
336
+ } else {
337
+ resultMeta , err = handleExternalPipelineMeta (parentBuild , parentJob , resultMeta , metaSpace , metaLog , isJoin )
338
+
339
+ if err != nil {
340
+ return resultMeta , fmt .Errorf ("Merging meta of External Parent Build ID %d: %v" , parentBuild .ID , err )
329
341
}
342
+ }
343
+ }
344
+
345
+ return resultMeta , nil
346
+ }
347
+
348
+ func handleExternalPipelineMeta (parentBuild screwdriver.Build , parentJob screwdriver.Job , resultMeta map [string ]interface {}, metaSpace , metaLog string , isJoin bool ) (map [string ]interface {}, error ) {
349
+ // Write to "sd@123:component.json", where sd@123:component is the triggering job
350
+ externalMetaFile := "sd@" + strconv .Itoa (parentJob .PipelineID ) + ":" + parentJob .Name + ".json"
351
+ writeMetafile (metaSpace , externalMetaFile , metaLog , parentBuild .Meta )
352
+
353
+ if isJoin {
354
+ marshallValue , err := json .Marshal (parentBuild .Meta )
355
+ if err != nil {
356
+ return resultMeta , fmt .Errorf ("Cloning meta of Parent Build ID %d: %v" , parentBuild .ID , err )
357
+ }
358
+ var externalParentBuildMeta map [string ]interface {}
359
+ json .Unmarshal (marshallValue , & externalParentBuildMeta )
360
+
361
+ // Always exclude parameters from external meta
362
+ delete (externalParentBuildMeta , "parameters" )
330
363
331
- // delete local version of external meta
332
- pIDString := strconv .Itoa (parentJob .PipelineID )
333
- pjn := parentJob .Name
334
- if sdMeta , ok := resultMeta ["sd" ]; ok {
335
- if externalPipelineMeta , ok := sdMeta .(map [string ]interface {})[pIDString ]; ok {
336
- if _ , ok := externalPipelineMeta .(map [string ]interface {})[pjn ]; ok {
337
- delete (externalPipelineMeta .(map [string ]interface {}), pjn )
338
- }
339
- }
364
+ resultMeta = deepMergeJSON (resultMeta , externalParentBuildMeta )
365
+ }
366
+
367
+ // delete local version of external meta
368
+ pIDString := strconv .Itoa (parentJob .PipelineID )
369
+ pjn := parentJob .Name
370
+ if sdMeta , ok := resultMeta ["sd" ]; ok {
371
+ if externalPipelineMeta , ok := sdMeta .(map [string ]interface {})[pIDString ]; ok {
372
+ if _ , ok := externalPipelineMeta .(map [string ]interface {})[pjn ]; ok {
373
+ delete (externalPipelineMeta .(map [string ]interface {}), pjn )
340
374
}
341
- } else {
342
- resultMeta = deepMergeJSON (resultMeta , parentBuild .Meta )
343
375
}
344
376
}
345
377
@@ -499,23 +531,16 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s
499
531
}
500
532
}
501
533
502
- if len (parentBuildIDs ) > 1 { // If has multiple parent build IDs, merge their metadata (join case)
534
+ // If has parent build IDs, merge their metadata
535
+ if len (parentBuildIDs ) > 0 {
503
536
// Get meta from all parent builds
504
- for _ , pbID := range parentBuildIDs {
505
- mergedMeta , err = SetExternalMeta (api , pipeline .ID , pbID , mergedMeta , metaSpace , metaLog , true )
506
- if err != nil {
507
- return fmt .Errorf ("Setting meta for Parent Build ID %d: %v" , pbID , err ), "" , ""
508
- }
509
- }
537
+ mergedMeta , err = setParentBuildsMeta (api , pipeline .ID , parentBuildIDs , mergedMeta , metaSpace , metaLog )
510
538
511
- metaLog = fmt .Sprintf (`Builds(%v)` , parentBuildIDs )
512
- } else if len (parentBuildIDs ) == 1 { // If has parent build, fetch from parent build
513
- mergedMeta , err = SetExternalMeta (api , pipeline .ID , parentBuildIDs [0 ], mergedMeta , metaSpace , metaLog , false )
514
539
if err != nil {
515
- return fmt .Errorf ("Setting meta for Parent Build ID %d: %v" , parentBuildIDs [ 0 ] , err ), "" , ""
540
+ return fmt .Errorf ("Setting meta for Parent Build ID %d: %v" , parentBuildIDs , err ), "" , ""
516
541
}
517
542
518
- metaLog = fmt .Sprintf (`Build (%v)` , parentBuildIDs [ 0 ] )
543
+ metaLog = fmt .Sprintf (`Builds (%v)` , parentBuildIDs )
519
544
}
520
545
521
546
// Initialize pr comments (Issue #1858)
0 commit comments