// ingestBuild encapsulates many of the steps of ingesting a build: // - Record the mapping between the codename (build.Builder) and the internal target name. // - If no matching build exists, assign a new build number for this build and insert it. // - Otherwise, update the existing build to match the given build. func ingestBuild(build *buildbot.Build, commitHash, target string) error { // Store build.Builder (the codename) with its pair build.Target.Name in a local leveldb to serve redirects. if err := codenameDB.Put([]byte(build.Builder), []byte(target), nil); err != nil { glog.Errorf("Failed to write codename to data store: %s", err) } buildNumber, err := db.GetBuildNumberForCommit(build.Master, build.Builder, commitHash) if err != nil { return fmt.Errorf("Failed to find the build in the database: %s", err) } glog.Infof("GetBuildForCommit at hash: %s returned %d", commitHash, buildNumber) var cachedBuild *buildbot.Build if buildNumber != -1 { cachedBuild, err = db.GetBuildFromDB(build.Master, build.Builder, buildNumber) if err != nil { return fmt.Errorf("Failed to retrieve build from database: %s", err) } } if cachedBuild == nil { // This is a new build we've never seen before, so add it to the buildbot database. // TODO(benjaminwagner): This logic won't work well for concurrent requests. Revisit // after borenet's "giant datahopper change." // First calculate a new unique build.Number. number, err := db.GetMaxBuildNumber(build.Master, build.Builder) if err != nil { return fmt.Errorf("Failed to find next build number: %s", err) } build.Number = number + 1 glog.Infof("Writing new build to the database: %s %d", build.Builder, build.Number) } else { // If the state of the build has changed then write it to the buildbot database. glog.Infof("Writing updated build to the database: %s %d", build.Builder, build.Number) } if err := buildbot.IngestBuild(db, build, repos); err != nil { return fmt.Errorf("Failed to ingest build: %s", err) } return nil }