From 9040349046883b2e8c807ff4a0184ddf33dc28af Mon Sep 17 00:00:00 2001 From: Easton Crupper <65553218+ecrupper@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:30:56 -0500 Subject: [PATCH] fix: abstract build component status updates for build approval and cancelation (#1064) --- api/build/cancel.go | 91 +++------------------------------------------ api/build/update.go | 74 ++++++++++++++++++++++++++++++++++++ api/webhook/post.go | 6 +++ 3 files changed, 86 insertions(+), 85 deletions(-) diff --git a/api/build/cancel.go b/api/build/cancel.go index c91b7c5fa..0126f819c 100644 --- a/api/build/cancel.go +++ b/api/build/cancel.go @@ -21,7 +21,6 @@ import ( "github.com/go-vela/server/router/middleware/user" "github.com/go-vela/server/util" "github.com/go-vela/types/constants" - "github.com/go-vela/types/library" "github.com/sirupsen/logrus" ) @@ -217,91 +216,13 @@ func CancelBuild(c *gin.Context) { return } - // retrieve the steps for the build from the step table - steps := []*library.Step{} - page := 1 - perPage := 100 - - for page > 0 { - // retrieve build steps (per page) from the database - stepsPart, _, err := database.FromContext(c).ListStepsForBuild(ctx, b, map[string]interface{}{}, page, perPage) - if err != nil { - retErr := fmt.Errorf("unable to retrieve steps for build %s: %w", entry, err) - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - - // add page of steps to list steps - steps = append(steps, stepsPart...) - - // assume no more pages exist if under 100 results are returned - if len(stepsPart) < 100 { - page = 0 - } else { - page++ - } - } - - // iterate over each step for the build - // setting anything running or pending to canceled - for _, step := range steps { - if step.GetStatus() == constants.StatusRunning || step.GetStatus() == constants.StatusPending { - step.SetStatus(constants.StatusCanceled) - - _, err = database.FromContext(c).UpdateStep(ctx, step) - if err != nil { - retErr := fmt.Errorf("unable to update step %s for build %s: %w", step.GetName(), entry, err) - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - } - } - - // retrieve the services for the build from the service table - services := []*library.Service{} - page = 1 - - for page > 0 { - // retrieve build services (per page) from the database - servicesPart, _, err := database.FromContext(c).ListServicesForBuild(ctx, b, map[string]interface{}{}, page, perPage) - if err != nil { - retErr := fmt.Errorf("unable to retrieve services for build %s: %w", entry, err) - util.HandleError(c, http.StatusNotFound, retErr) - - return - } - - // add page of services to the list of services - services = append(services, servicesPart...) - - // assume no more pages exist if under 100 results are returned - if len(servicesPart) < 100 { - page = 0 - } else { - page++ - } - } - - // iterate over each service for the build - // setting anything running or pending to canceled - for _, service := range services { - if service.GetStatus() == constants.StatusRunning || service.GetStatus() == constants.StatusPending { - service.SetStatus(constants.StatusCanceled) - - _, err = database.FromContext(c).UpdateService(ctx, service) - if err != nil { - retErr := fmt.Errorf("unable to update service %s for build %s: %w", - service.GetName(), - entry, - err, - ) - util.HandleError(c, http.StatusNotFound, retErr) + // update component statuses to canceled + err = UpdateComponentStatuses(c, b, constants.StatusCanceled) + if err != nil { + retErr := fmt.Errorf("unable to update component statuses for build %s: %w", entry, err) + util.HandleError(c, http.StatusInternalServerError, retErr) - return - } - } + return } c.JSON(http.StatusOK, b) diff --git a/api/build/update.go b/api/build/update.go index 9c26ae8a7..c9fb30aa8 100644 --- a/api/build/update.go +++ b/api/build/update.go @@ -181,3 +181,77 @@ func UpdateBuild(c *gin.Context) { } } } + +// UpdateComponentStatuses updates all components (steps and services) for a build to a given status. +func UpdateComponentStatuses(c *gin.Context, b *library.Build, status string) error { + ctx := c.Request.Context() + + // retrieve the steps for the build from the step table + steps := []*library.Step{} + page := 1 + perPage := 100 + + for page > 0 { + // retrieve build steps (per page) from the database + stepsPart, _, err := database.FromContext(c).ListStepsForBuild(ctx, b, map[string]interface{}{}, page, perPage) + if err != nil { + return err + } + + // add page of steps to list steps + steps = append(steps, stepsPart...) + + // assume no more pages exist if under 100 results are returned + if len(stepsPart) < 100 { + page = 0 + } else { + page++ + } + } + + // iterate over each step for the build + // setting status + for _, step := range steps { + step.SetStatus(status) + + _, err := database.FromContext(c).UpdateStep(ctx, step) + if err != nil { + return err + } + } + + // retrieve the services for the build from the service table + services := []*library.Service{} + page = 1 + + for page > 0 { + // retrieve build services (per page) from the database + servicesPart, _, err := database.FromContext(c).ListServicesForBuild(ctx, b, map[string]interface{}{}, page, perPage) + if err != nil { + return err + } + + // add page of services to the list of services + services = append(services, servicesPart...) + + // assume no more pages exist if under 100 results are returned + if len(servicesPart) < 100 { + page = 0 + } else { + page++ + } + } + + // iterate over each service for the build + // setting status + for _, service := range services { + service.SetStatus(status) + + _, err := database.FromContext(c).UpdateService(ctx, service) + if err != nil { + return err + } + } + + return nil +} diff --git a/api/webhook/post.go b/api/webhook/post.go index 935f5dd6c..965afeb72 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -1053,6 +1053,12 @@ func gatekeepBuild(c *gin.Context, b *library.Build, r *library.Repo, u *library return fmt.Errorf("unable to update build for %s/%d: %w", r.GetFullName(), b.GetNumber(), err) } + // update the build components to pending approval status + err = build.UpdateComponentStatuses(c, b, constants.StatusPendingApproval) + if err != nil { + return fmt.Errorf("unable to update build components for %s/%d: %w", r.GetFullName(), b.GetNumber(), err) + } + // send API call to set the status on the commit err = scm.FromContext(c).Status(c, u, b, r.GetOrg(), r.GetName()) if err != nil {