Skip to content

Commit dafc34c

Browse files
y-oksakukumada626
andauthored
fix(3125): merge parent build meta order by end time (#481)
* feat: merge parent build meta by end time order * feat: add multi parent build meta test * fix: endTime * fix: indent * fix: review * fix: review --------- Co-authored-by: Keisuke Kumada <kekumada@yahoo-corp.jp>
1 parent 0e8b012 commit dafc34c

File tree

4 files changed

+388
-52
lines changed

4 files changed

+388
-52
lines changed

launch.go

Lines changed: 76 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"path/filepath"
1313
"regexp"
1414
"runtime/debug"
15+
"sort"
1516
"strconv"
1617
"strings"
1718
"time"
@@ -293,53 +294,84 @@ func writeMetafile(metaSpace, metaFile, metaLog string, mergedMeta map[string]in
293294
return nil
294295
}
295296

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) {
298299
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
304301

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)
309314
}
310315

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+
312333
// 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)
329341
}
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")
330363

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)
340374
}
341-
} else {
342-
resultMeta = deepMergeJSON(resultMeta, parentBuild.Meta)
343375
}
344376
}
345377

@@ -499,23 +531,16 @@ func launch(api screwdriver.API, buildID int, rootDir, emitterPath, metaSpace, s
499531
}
500532
}
501533

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 {
503536
// 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)
510538

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)
514539
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), "", ""
516541
}
517542

518-
metaLog = fmt.Sprintf(`Build(%v)`, parentBuildIDs[0])
543+
metaLog = fmt.Sprintf(`Builds(%v)`, parentBuildIDs)
519544
}
520545

521546
// Initialize pr comments (Issue #1858)

0 commit comments

Comments
 (0)