feat: Comment on pull request if pre-workflow hooks fail (#5659)

Signed-off-by: Moritz Wirth <mw@flanga.io>
Signed-off-by: Bruno Schaatsbergen <git@ebschaatsbergen.com>
Signed-off-by: Moritz Wirth <27090954+mowirth@users.noreply.github.com>
Signed-off-by: PePe Amengual <2208324+jamengual@users.noreply.github.com>
Signed-off-by: Ryan Barry <ryan@nuclearice.com>
Signed-off-by: Rui Chen <rui@chenrui.dev>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Bruno Schaatsbergen <git@bschaatsbergen.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: PePe Amengual <2208324+jamengual@users.noreply.github.com>
Co-authored-by: Ryan Barry <ryan@nuclearice.com>
Co-authored-by: Rui Chen <rui@chenrui.dev>
This commit is contained in:
Moritz Wirth
2025-08-07 20:43:33 +02:00
committed by GitHub
parent be8036aa15
commit 0fb41570b5
3 changed files with 54 additions and 23 deletions

View File

@@ -2,24 +2,24 @@
# Manual edits may be lost in future updates.
provider "registry.terraform.io/hashicorp/null" {
version = "3.2.3"
constraints = "3.2.3"
version = "3.2.4"
constraints = "3.2.4"
hashes = [
"h1:+AnORRgFbRO6qqcfaQyeX80W0eX3VmjadjnUFUJTiXo=",
"h1:I0Um8UkrMUb81Fxq/dxbr3HLP2cecTH2WMJiwKSrwQY=",
"h1:nKUqWEza6Lcv3xRlzeiRQrHtqvzX1BhIzjaOVXRYQXQ=",
"h1:obXguGZUWtNAO09f1f9Cb7hsPCOGXuGdN8bn/ohKRBQ=",
"zh:22d062e5278d872fe7aed834f5577ba0a5afe34a3bdac2b81f828d8d3e6706d2",
"zh:23dead00493ad863729495dc212fd6c29b8293e707b055ce5ba21ee453ce552d",
"zh:28299accf21763ca1ca144d8f660688d7c2ad0b105b7202554ca60b02a3856d3",
"zh:55c9e8a9ac25a7652df8c51a8a9a422bd67d784061b1de2dc9fe6c3cb4e77f2f",
"zh:756586535d11698a216291c06b9ed8a5cc6a4ec43eee1ee09ecd5c6a9e297ac1",
"h1:127ts0CG8hFk1bHIfrBsKxcnt9bAYQCq3udWM+AACH8=",
"h1:L5V05xwp/Gto1leRryuesxjMfgZwjb7oool4WS1UEFQ=",
"h1:hkf5w5B6q8e2A42ND2CjAvgvSN3puAosDmOJb3zCVQM=",
"h1:wTNrZnwQdOOT/TW9pa+7GgJeFK2OvTvDmx78VmUmZXM=",
"zh:59f6b52ab4ff35739647f9509ee6d93d7c032985d9f8c6237d1f8a59471bbbe2",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:9d5eea62fdb587eeb96a8c4d782459f4e6b73baeece4d04b4a40e44faaee9301",
"zh:a6355f596a3fb8fc85c2fb054ab14e722991533f87f928e7169a486462c74670",
"zh:b5a65a789cff4ada58a5baffc76cb9767dc26ec6b45c00d2ec8b1b027f6db4ed",
"zh:db5ab669cf11d0e9f81dc380a6fdfcac437aea3d69109c7aef1a5426639d2d65",
"zh:de655d251c470197bcbb5ac45d289595295acb8f829f6c781d4a75c8c8b7c7dd",
"zh:f5c68199f2e6076bce92a12230434782bf768103a427e9bb9abee99b116af7b5",
"zh:795c897119ff082133150121d39ff26cb5f89a730a2c8c26f3a9c1abf81a9c43",
"zh:7b9c7b16f118fbc2b05a983817b8ce2f86df125857966ad356353baf4bff5c0a",
"zh:85e33ab43e0e1726e5f97a874b8e24820b6565ff8076523cc2922ba671492991",
"zh:9d32ac3619cfc93eb3c4f423492a8e0f79db05fec58e449dee9b2d5873d5f69f",
"zh:9e15c3c9dd8e0d1e3731841d44c34571b6c97f5b95e8296a45318b94e5287a6e",
"zh:b4c2ab35d1b7696c30b64bf2c0f3a62329107bd1a9121ce70683dec58af19615",
"zh:c43723e8cc65bcdf5e0c92581dcbbdcbdcf18b8d2037406a5f2033b1e22de442",
"zh:ceb5495d9c31bfb299d246ab333f08c7fb0d67a4f82681fbf47f2a21c3e11ab5",
"zh:e171026b3659305c558d9804062762d168f50ba02b88b231d20ec99578a6233f",
"zh:ed0fe2acdb61330b01841fa790be00ec6beaac91d41f311fb8254f74eb6a711f",
]
}

View File

@@ -29,7 +29,7 @@ import (
"github.com/runatlantis/atlantis/server/metrics"
"github.com/runatlantis/atlantis/server/recovery"
"github.com/runatlantis/atlantis/server/utils"
tally "github.com/uber-go/tally/v4"
"github.com/uber-go/tally/v4"
gitlab "gitlab.com/gitlab-org/api/client-go"
)
@@ -208,12 +208,18 @@ func (c *DefaultCommandRunner) RunAutoplanCommand(baseRepo models.Repo, headRepo
ctx.Log.Warn("unable to update plan commit status: %s", err)
}
err = c.PreWorkflowHooksCommandRunner.RunPreHooks(ctx, cmd)
preWorkflowHooksErr := c.PreWorkflowHooksCommandRunner.RunPreHooks(ctx, cmd)
if err != nil {
if preWorkflowHooksErr != nil {
if c.FailOnPreWorkflowHookError {
ctx.Log.Err("'fail-on-pre-workflow-hook-error' set, so not running %s command.", command.Plan)
// Create comment on pull request about the pre-workflow hook failure
errMsg := fmt.Sprintf("```\nError: Pre-workflow hook failed: %s\n```", preWorkflowHooksErr.Error())
if err := c.VCSClient.CreateComment(ctx.Log, ctx.Pull.BaseRepo, ctx.Pull.Num, errMsg, ""); err != nil {
ctx.Log.Warn("Unable to create comment about pre-workflow hook failure: %s", err)
}
// Update the plan or apply commit status to failed
switch cmd.Name {
case command.Plan:
@@ -372,12 +378,18 @@ func (c *DefaultCommandRunner) RunCommentCommand(baseRepo models.Repo, maybeHead
}
}
err = c.PreWorkflowHooksCommandRunner.RunPreHooks(ctx, cmd)
preWorkflowHooksErr := c.PreWorkflowHooksCommandRunner.RunPreHooks(ctx, cmd)
if err != nil {
if preWorkflowHooksErr != nil {
if c.FailOnPreWorkflowHookError {
ctx.Log.Err("'fail-on-pre-workflow-hook-error' set, so not running %s command.", cmd.Name.String())
// Create comment on pull request about the pre-workflow hook failure
errMsg := fmt.Sprintf("```\nError: Pre-workflow hook failed: %s\n```", preWorkflowHooksErr.Error())
if err := c.VCSClient.CreateComment(ctx.Log, ctx.Pull.BaseRepo, ctx.Pull.Num, errMsg, ""); err != nil {
ctx.Log.Warn("Unable to create comment about pre-workflow hook failure: %s", err)
}
// Update the plan or apply commit status to failed
switch cmd.Name {
case command.Plan:

View File

@@ -304,6 +304,20 @@ func TestRunCommentCommand_GithubPullParseErr(t *testing.T) {
Any[logging.SimpleLogging](), Eq(testdata.GithubRepo), Eq(testdata.Pull.Num), Eq("`Error: extracting required fields from comment data: err`"), Eq(""))
}
func TestRunCommentCommand_CommentPreWorkflowHookFailure(t *testing.T) {
t.Log("if there is a pre-workflowhook failure with failure enabled it is commented back on the pull request")
vcsClient := setup(t)
ch.FailOnPreWorkflowHookError = true
When(preWorkflowHooksCommandRunner.RunPreHooks(Any[*command.Context](), Any[*events.CommentCommand]())).ThenReturn(errors.New("err"))
ch.RunCommentCommand(testdata.GithubRepo, &testdata.GithubRepo, nil, testdata.User, 1, &events.CommentCommand{Name: command.Plan})
_, _, _, comment, _ := vcsClient.VerifyWasCalledOnce().CreateComment(
Any[logging.SimpleLogging](), Any[models.Repo](), Any[int](), Any[string](), Any[string]()).GetCapturedArguments()
Assert(t, strings.Contains(comment, "Error: Pre-workflow hook failed"), fmt.Sprintf("comment should be about a pre-workflow hook failure but was %q", comment))
}
func TestRunCommentCommand_TeamAllowListChecker(t *testing.T) {
t.Run("nil checker", func(t *testing.T) {
vcsClient := setup(t)
@@ -835,7 +849,7 @@ func TestRunAutoplanCommand_FailedPreWorkflowHook_FailOnPreWorkflowHookError_Fal
}
func TestRunAutoplanCommand_FailedPreWorkflowHook_FailOnPreWorkflowHookError_True(t *testing.T) {
setup(t)
vcsClient := setup(t)
tmp := t.TempDir()
boltDB, err := db.New(tmp)
t.Cleanup(func() {
@@ -859,6 +873,11 @@ func TestRunAutoplanCommand_FailedPreWorkflowHook_FailOnPreWorkflowHookError_Tru
lockingLocker.VerifyWasCalled(Never()).UnlockByPull(Any[string](), Any[int]())
commitUpdater.VerifyWasCalledOnce().UpdateCombined(Any[logging.SimpleLogging](), Any[models.Repo](), Any[models.PullRequest](),
Eq(models.PendingCommitStatus), Eq(command.Plan))
_, _, _, comment, _ := vcsClient.VerifyWasCalledOnce().CreateComment(
Any[logging.SimpleLogging](), Any[models.Repo](), Any[int](), Any[string](), Any[string]()).GetCapturedArguments()
Assert(t, strings.Contains(comment, "Error: Pre-workflow hook failed"), fmt.Sprintf("comment should be about a pre-workflow hook failure but was %q", comment))
}
func TestRunCommentCommand_FailedPreWorkflowHook_FailOnPreWorkflowHookError_False(t *testing.T) {