// MarkEnd updates the task as being finished, performs a stepback if necessary, and updates the build status func MarkEnd(taskId, caller string, finishTime time.Time, detail *apimodels.TaskEndDetail, p *Project, deactivatePrevious bool) error { t, err := task.FindOne(task.ById(taskId)) if err != nil { return err } if t == nil { return fmt.Errorf("Task not found for taskId: %v", taskId) } if t.Status == detail.Status { evergreen.Logger.Logf(slogger.WARN, "Tried to mark task %v as finished twice", t.Id) return nil } t.Details = *detail err = t.MarkEnd(caller, finishTime, detail) if err != nil { return err } event.LogTaskFinished(t.Id, t.HostId, detail.Status) // update the cached version of the task, in its build document err = build.SetCachedTaskFinished(t.BuildId, t.Id, detail, t.TimeTaken) if err != nil { return fmt.Errorf("error updating build: %v", err.Error()) } // no need to activate/deactivate other task if this is a patch request's task if t.Requester == evergreen.PatchVersionRequester { err = UpdateBuildAndVersionStatusForTask(t.Id) if err != nil { return fmt.Errorf("Error updating build status (1): %v", err.Error()) } return nil } if detail.Status == evergreen.TaskFailed { shouldStepBack, err := getStepback(t.Id, p) if err != nil { return err } if shouldStepBack { err = doStepback(t, caller, detail, deactivatePrevious) if err != nil { return fmt.Errorf("Error during step back: %v", err.Error()) } } else { evergreen.Logger.Logf(slogger.DEBUG, "Not stepping backwards on task failure: %v", t.Id) } } else if deactivatePrevious { // if the task was successful, ignore running previous // activated tasks for this buildvariant err = DeactivatePreviousTasks(t.Id, caller) if err != nil { return fmt.Errorf("Error deactivating previous task: %v", err.Error()) } } // update the build if err := UpdateBuildAndVersionStatusForTask(t.Id); err != nil { return fmt.Errorf("Error updating build status (2): %v", err.Error()) } return nil }
func (t *Task) MarkEnd(caller string, finishTime time.Time, detail *apimodels.TaskEndDetail, p *Project, deactivatePrevious bool) error { if t.Status == detail.Status { evergreen.Logger.Logf(slogger.WARN, "Tried to mark task %v as finished twice", t.Id) return nil } t.Details = *detail err := t.markEnd(caller, finishTime, detail) if err != nil { return err } // update the cached version of the task, in its build document err = build.SetCachedTaskFinished(t.BuildId, t.Id, detail, t.TimeTaken) if err != nil { return fmt.Errorf("error updating build: %v", err.Error()) } // no need to activate/deactivate other task if this is a patch request's task if t.Requester == evergreen.PatchVersionRequester { err = t.UpdateBuildStatus() if err != nil { return fmt.Errorf("Error updating build status (1): %v", err.Error()) } return nil } // Do stepback if detail.Status == evergreen.TaskFailed { if shouldStepBack := t.getStepback(p); shouldStepBack { //See if there is a prior success for this particular task. //If there isn't, we should not activate the previous task because //it could trigger stepping backwards ad infinitum. _, err := PreviousCompletedTask(t, t.Project, []string{evergreen.TaskSucceeded}) if err != nil { if err == mgo.ErrNotFound { shouldStepBack = false } else { return fmt.Errorf("Error locating previous successful task: %v", err) } } if shouldStepBack { // activate the previous task to pinpoint regression err = t.ActivatePreviousTask(caller) if err != nil { return fmt.Errorf("Error activating previous task: %v", err) } } else { evergreen.Logger.Logf(slogger.DEBUG, "Not stepping backwards on task failure: %v", t.Id) } } } else if deactivatePrevious { // if the task was successful, ignore running previous // activated tasks for this buildvariant err = t.DeactivatePreviousTasks(caller) if err != nil { return fmt.Errorf("Error deactivating previous task: %v", err.Error()) } } // update the build if err := t.UpdateBuildStatus(); err != nil { return fmt.Errorf("Error updating build status (2): %v", err.Error()) } return nil }