github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/notify/build_success_to_failure_handler.go (about) 1 package notify 2 3 import ( 4 "fmt" 5 6 "github.com/evergreen-ci/evergreen" 7 "github.com/evergreen-ci/evergreen/model/build" 8 "github.com/evergreen-ci/evergreen/web" 9 "github.com/mongodb/grip" 10 ) 11 12 // Handler for notifications generated specifically when a build fails and the 13 // previous finished build succeeded. Implements NotificationHandler from 14 // notification_handler.go. 15 type BuildSuccessToFailureHandler struct { 16 BuildNotificationHandler 17 Name string 18 } 19 20 func (self *BuildSuccessToFailureHandler) GetNotifications(ae *web.App, key *NotificationKey) ([]Email, error) { 21 var emails []Email 22 builds, err := getRecentlyFinishedBuilds(key) 23 if err != nil { 24 return nil, err 25 } 26 27 preface := mciFailurePreface 28 if key.NotificationRequester == evergreen.PatchVersionRequester { 29 preface = patchFailurePreface 30 } 31 32 for _, currentBuild := range builds { 33 // Copy by value to make pointer safe 34 curr := currentBuild 35 previousBuild, err := currentBuild.PreviousActivated(key.Project, 36 evergreen.RepotrackerVersionRequester) 37 if previousBuild == nil { 38 grip.Debugf("No previous completed build found for '%v' on %v %v notification", 39 currentBuild.Id, key.Project, key.NotificationName) 40 continue 41 } else if err != nil { 42 return nil, err 43 } 44 45 if !previousBuild.IsFinished() { 46 grip.Debugf("Build before '%s' (on %s %s notification) isn't finished", 47 currentBuild.Id, key.Project, key.NotificationName) 48 continue 49 } 50 51 // get the build's project to add to the notification subject line 52 branchName := UnknownProjectBranch 53 if projectRef, err := getProjectRef(currentBuild.Project); err != nil { 54 grip.Warningf("Unable to find project ref for build '%s': %+v", 55 currentBuild.Id, err) 56 } else if projectRef != nil { 57 branchName = projectRef.Branch 58 } 59 60 grip.Debugf("Previous completed build found for '%s on %s %s notification is %s", 61 currentBuild.Id, key.Project, key.NotificationName, previousBuild.Id) 62 63 if previousBuild.Status == evergreen.BuildSucceeded && 64 currentBuild.Status == evergreen.BuildFailed { 65 notification := TriggeredBuildNotification{ 66 Current: &curr, 67 Previous: previousBuild, 68 Key: *key, 69 Preface: fmt.Sprintf(preface, branchName), 70 Transition: transitionSubject, 71 } 72 email, err := self.TemplateNotification(ae, ¬ification) 73 if err != nil { 74 grip.Noticef("template error for build success to failure notification with '%s': %s", 75 currentBuild.Id, err.Error()) 76 continue 77 } 78 emails = append(emails, email) 79 } 80 } 81 82 return emails, nil 83 } 84 85 func (self *BuildSuccessToFailureHandler) TemplateNotification(ae *web.App, notification *TriggeredBuildNotification) (Email, error) { 86 changeInfo, err := self.GetChangeInfo(notification) 87 if err != nil { 88 return nil, err 89 } 90 return self.templateNotification(ae, notification, changeInfo) 91 } 92 93 func (self *BuildSuccessToFailureHandler) GetChangeInfo( 94 notification *TriggeredBuildNotification) ([]ChangeInfo, error) { 95 current := notification.Current 96 previous := current 97 if notification.Previous != nil { 98 previous = notification.Previous 99 } 100 101 intermediateBuilds, err := current.FindIntermediateBuilds(previous) 102 if err != nil { 103 return nil, err 104 } 105 allBuilds := make([]build.Build, len(intermediateBuilds)+1) 106 107 // include the current/previous build 108 allBuilds[len(allBuilds)-1] = *current 109 110 // copy any intermediate build(s) 111 if len(intermediateBuilds) != 0 { 112 copy(allBuilds[0:len(allBuilds)-1], intermediateBuilds) 113 } 114 return self.constructChangeInfo(allBuilds, ¬ification.Key) 115 }