From 2139c9c8b8243ca62372f8485d585db3351225b4 Mon Sep 17 00:00:00 2001 From: davidvader Date: Thu, 12 Sep 2024 12:20:04 -0500 Subject: [PATCH] fix: avoid double responses --- api/webhook/post.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/api/webhook/post.go b/api/webhook/post.go index cb45e9c18..d4a847178 100644 --- a/api/webhook/post.go +++ b/api/webhook/post.go @@ -489,8 +489,6 @@ func PostWebhook(c *gin.Context) { } } - c.JSON(http.StatusCreated, b) - // regardless of whether the build is published to queue, we want to attempt to auto-cancel if no errors defer func() { if err == nil && build.ShouldAutoCancel(p.Metadata.AutoCancel, b, repo.GetBranch()) { @@ -531,6 +529,10 @@ func PostWebhook(c *gin.Context) { } }() + // track if we have already responded to the http request + // helps prevent multiple responses to the same request in the event of errors + responded := false + // if the webhook was from a Pull event from a forked repository, verify it is allowed to run if webhook.PullRequest.IsFromFork { l.Tracef("inside %s workflow for fork PR build %s/%d", repo.GetApproveBuild(), repo.GetFullName(), b.GetNumber()) @@ -540,8 +542,12 @@ func PostWebhook(c *gin.Context) { err = gatekeepBuild(c, b, repo) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) + } else { + c.JSON(http.StatusCreated, b) } + responded = true + return case constants.ApproveForkNoWrite: // determine if build sender has write access to parent repo. If not, this call will result in an error @@ -550,8 +556,12 @@ func PostWebhook(c *gin.Context) { err = gatekeepBuild(c, b, repo) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) + } else { + c.JSON(http.StatusCreated, b) } + responded = true + return } @@ -564,14 +574,20 @@ func PostWebhook(c *gin.Context) { contributor, err := scm.FromContext(c).RepoContributor(ctx, repo.GetOwner(), b.GetSender(), repo.GetOrg(), repo.GetName()) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) + + responded = true } if !contributor { err = gatekeepBuild(c, b, repo) if err != nil { util.HandleError(c, http.StatusInternalServerError, err) + } else if !responded { + c.JSON(http.StatusCreated, b) } + responded = true + return } @@ -597,6 +613,11 @@ func PostWebhook(c *gin.Context) { item, b.GetHost(), ) + + // respond only when necessary + if !responded { + c.JSON(http.StatusCreated, b) + } } // handleRepositoryEvent is a helper function that processes repository events from the SCM and updates