Improve state handling in build_success.
@@ -31,28 +31,20 @@ func (bs *BuildSuccess) Collect() (*data.DataSet, error) {
return nil, fmt.Errorf("Cannot collect build success statistics for pipeline %s: %v", pipeline, err)
}
for _, build := range builds {
- platformStates := make(map[string]string)
- includeBuild := true
-
+ platformStates := make(map[string]*state)
for _, job := range build.Jobs {
- if *job.State != "passed" && *job.State != "failed" {
- includeBuild = false
- break
- }
platform := getPlatfrom(*job.Name)
if platform == "" {
continue
}
mergeState(platformStates, platform, *job.State)
}
- if includeBuild {
- err := result.AddRow(pipeline, *build.Number, platformStates["linux"], platformStates["macos"], platformStates["windows"], platformStates["rbe"])
+ err := result.AddRow(pipeline, *build.Number, getState(platformStates, "linux"), getState(platformStates, "macos"), getState(platformStates, "windows"), getState(platformStates, "rbe"))
if err != nil {
return nil, fmt.Errorf("Failed to add result for build %d: %v", *build.Number, err)
}
}
}
- }
return result, nil
}
@@ -70,19 +62,57 @@ func getPlatfrom(jobName string) string {
}
}
-func mergeState(platformStates map[string]string, platform, newState string) {
+type state struct {
+ Name string
+ Priority uint
+}
+
+var allStates = getAllStates()
+
+func getAllStates() map[string]*state {
+ // Our states are different from the Buildkite states (e.g. our "canceled" states includes "canceled" and "canceling").
+ /// They also have a priority that defines how multiple states for a given platform are aggregated into a single state.
+ states := make(map[string]*state)
+
+ canceled := &state{"canceled", 3}
+ states["canceled"] = canceled
+ states["canceling"] = canceled
+
+ states["failed"] = &state{"failed", 2}
+
+ running := &state{"running", 1}
+ states["running"] = running
+ states["scheduled"] = running
+ states["blocked"] = running
+
+ states["passed"] = &state{"passed", 0}
+
+ return states
+}
+
+func mergeState(platformStates map[string]*state, platform, buildkiteState string) {
+ newState, ok := allStates[buildkiteState]
+ if !ok {
+ return
+ }
oldState, ok := platformStates[platform]
if ok {
- if oldState == "failed" || newState == "failed" {
- platformStates[platform] = "failed"
- } else {
- platformStates[platform] = "passed"
+ if newState.Priority > oldState.Priority {
+ platformStates[platform] = newState
}
} else {
platformStates[platform] = newState
}
}
+func getState(platformStates map[string]*state, platform string) string {
+ state, ok := platformStates[platform]
+ if !ok || state == nil {
+ return ""
+ }
+ return state.Name
+}
+
// CREATE TABLE build_success (pipeline VARCHAR(255), build INT, linux VARCHAR(255), macos VARCHAR(255), windows VARCHAR(255), rbe VARCHAR(255), PRIMARY KEY(pipeline, build));
func CreateBuildSuccess(client *clients.BuildkiteClient, builds int, pipelines ...string) *BuildSuccess {
columns := []Column{Column{"pipeline", true}, Column{"build", true}, Column{"linux", false}, Column{"macos", false}, Column{"windows", false}, Column{"rbe", false}}
