Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1691,7 +1691,7 @@ func (m *mockLockURLGenerator) GenerateLockURL(_ string) string {

type mockWebhookSender struct{}

func (w *mockWebhookSender) Send(_ logging.SimpleLogging, _ webhooks.ApplyResult) error {
func (w *mockWebhookSender) Send(_ logging.SimpleLogging, _ webhooks.EventResult) error {
return nil
}

Expand Down
5 changes: 2 additions & 3 deletions server/events/mock_workingdir_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions server/events/mocks/mock_webhooks_sender.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

24 changes: 22 additions & 2 deletions server/events/project_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ type MultiEnvStepRunner interface {
// WebhooksSender sends webhook.
type WebhooksSender interface {
// Send sends the webhook.
Send(log logging.SimpleLogging, res webhooks.ApplyResult) error
Send(log logging.SimpleLogging, res webhooks.EventResult) error
}

//go:generate pegomock generate --package mocks -o mocks/mock_project_command_runner.go ProjectCommandRunner
Expand Down Expand Up @@ -610,6 +610,21 @@ func (p *DefaultProjectCommandRunner) doPlan(ctx command.ProjectContext) (*model

outputs, err := p.runSteps(ctx.Steps, ctx, projAbsPath)

webhookSendErr := p.Webhooks.Send(ctx.Log, webhooks.EventResult{ // nolint: errcheck
Event: webhooks.PlanEvent,
Workspace: ctx.Workspace,
User: ctx.User,
Repo: ctx.Pull.BaseRepo,
Pull: ctx.Pull,
Success: err == nil,
Directory: ctx.RepoRelDir,
ProjectName: ctx.ProjectName,
})

if webhookSendErr != nil {
ctx.Log.Err("error sending plan webhook; %v", webhookSendErr)
}

if err != nil {
if unlockErr := lockAttempt.UnlockFn(); unlockErr != nil {
ctx.Log.Err("error unlocking state after plan error: %v", unlockErr)
Expand Down Expand Up @@ -668,7 +683,8 @@ func (p *DefaultProjectCommandRunner) doApply(ctx command.ProjectContext) (apply

outputs, err := p.runSteps(ctx.Steps, ctx, absPath)

p.Webhooks.Send(ctx.Log, webhooks.ApplyResult{ // nolint: errcheck
webhookSendErr := p.Webhooks.Send(ctx.Log, webhooks.EventResult{ // nolint: errcheck
Event: webhooks.ApplyEvent,
Workspace: ctx.Workspace,
User: ctx.User,
Repo: ctx.Pull.BaseRepo,
Expand All @@ -678,6 +694,10 @@ func (p *DefaultProjectCommandRunner) doApply(ctx command.ProjectContext) (apply
ProjectName: ctx.ProjectName,
})

if webhookSendErr != nil {
ctx.Log.Err("error sending apply webhook; %v", webhookSendErr)
}

if err != nil {
return "", "", fmt.Errorf("%s\n%s", err, strings.Join(outputs, "\n"))
}
Expand Down
10 changes: 5 additions & 5 deletions server/events/webhooks/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ type HttpWebhook struct {
}

// Send sends the webhook to URL if workspace and branch matches their respective regex.
func (h *HttpWebhook) Send(_ logging.SimpleLogging, applyResult ApplyResult) error {
if !h.WorkspaceRegex.MatchString(applyResult.Workspace) || !h.BranchRegex.MatchString(applyResult.Pull.BaseBranch) {
func (h *HttpWebhook) Send(_ logging.SimpleLogging, eventResult EventResult) error {
if !h.WorkspaceRegex.MatchString(eventResult.Workspace) || !h.BranchRegex.MatchString(eventResult.Pull.BaseBranch) {
return nil
}
if err := h.doSend(applyResult); err != nil {
if err := h.doSend(eventResult); err != nil {
return errors.Wrap(err, fmt.Sprintf("sending webhook to %q", h.URL))
}
return nil
}

func (h *HttpWebhook) doSend(applyResult ApplyResult) error {
body, err := json.Marshal(applyResult)
func (h *HttpWebhook) doSend(eventResult EventResult) error {
body, err := json.Marshal(eventResult)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion server/events/webhooks/http_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
. "github.com/runatlantis/atlantis/testing"
)

var httpApplyResult = webhooks.ApplyResult{
var httpApplyResult = webhooks.EventResult{
Event: "apply",
Workspace: "production",
Repo: models.Repo{
FullName: "runatlantis/atlantis",
Expand Down
20 changes: 10 additions & 10 deletions server/events/webhooks/mocks/mock_sender.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 6 additions & 6 deletions server/events/webhooks/mocks/mock_slack_client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions server/events/webhooks/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ func NewSlack(wr *regexp.Regexp, br *regexp.Regexp, channel string, client Slack
}

// Send sends the webhook to Slack if workspace and branch matches their respective regex.
func (s *SlackWebhook) Send(_ logging.SimpleLogging, applyResult ApplyResult) error {
if !s.WorkspaceRegex.MatchString(applyResult.Workspace) || !s.BranchRegex.MatchString(applyResult.Pull.BaseBranch) {
func (s *SlackWebhook) Send(_ logging.SimpleLogging, eventResult EventResult) error {
if !s.WorkspaceRegex.MatchString(eventResult.Workspace) || !s.BranchRegex.MatchString(eventResult.Pull.BaseBranch) {
return nil
}
return s.Client.PostMessage(s.Channel, applyResult)
return s.Client.PostMessage(s.Channel, eventResult)
}
27 changes: 17 additions & 10 deletions server/events/webhooks/slack_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ package webhooks

import (
"fmt"
"strings"

"github.com/slack-go/slack"
)
Expand All @@ -30,7 +31,7 @@ const (
type SlackClient interface {
AuthTest() error
TokenIsSet() bool
PostMessage(channel string, applyResult ApplyResult) error
PostMessage(channel string, eventResult EventResult) error
}

//go:generate pegomock generate --package mocks -o mocks/mock_underlying_slack_client.go UnderlyingSlackClient
Expand Down Expand Up @@ -64,8 +65,8 @@ func (d *DefaultSlackClient) TokenIsSet() bool {
return d.Token != ""
}

func (d *DefaultSlackClient) PostMessage(channel string, applyResult ApplyResult) error {
attachments := d.createAttachments(applyResult)
func (d *DefaultSlackClient) PostMessage(channel string, eventResult EventResult) error {
attachments := d.createAttachments(eventResult)
_, _, err := d.Slack.PostMessage(
channel,
slack.MsgOptionAsUser(true),
Expand All @@ -75,19 +76,25 @@ func (d *DefaultSlackClient) PostMessage(channel string, applyResult ApplyResult
return err
}

func (d *DefaultSlackClient) createAttachments(applyResult ApplyResult) []slack.Attachment {
func (d *DefaultSlackClient) createAttachments(eventResult EventResult) []slack.Attachment {
var colour string
var successWord string
if applyResult.Success {
if eventResult.Success {
colour = slackSuccessColour
successWord = "succeeded"
} else {
colour = slackFailureColour
successWord = "failed"
}

text := fmt.Sprintf("Apply %s for <%s|%s>", successWord, applyResult.Pull.URL, applyResult.Repo.FullName)
directory := applyResult.Directory
eventName := string(eventResult.Event)
if eventName == "" {
eventName = "event"
}
eventName = strings.ToUpper(eventName[:1]) + eventName[1:]
text := fmt.Sprintf("%s %s for <%s|%s>", eventName, successWord, eventResult.Pull.URL, eventResult.Repo.FullName)

directory := eventResult.Directory
// Since "." looks weird, replace it with "/" to make it clear this is the root.
if directory == "." {
directory = "/"
Expand All @@ -99,17 +106,17 @@ func (d *DefaultSlackClient) createAttachments(applyResult ApplyResult) []slack.
Fields: []slack.AttachmentField{
{
Title: "Workspace",
Value: applyResult.Workspace,
Value: eventResult.Workspace,
Short: true,
},
{
Title: "Branch",
Value: applyResult.Pull.BaseBranch,
Value: eventResult.Pull.BaseBranch,
Short: true,
},
{
Title: "User",
Value: applyResult.User.Username,
Value: eventResult.User.Username,
Short: true,
},
{
Expand Down
4 changes: 2 additions & 2 deletions server/events/webhooks/slack_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import (

var underlying *mocks.MockUnderlyingSlackClient
var client webhooks.DefaultSlackClient
var result webhooks.ApplyResult
var result webhooks.EventResult

func TestAuthTest_Success(t *testing.T) {
t.Log("When the underlying client succeeds, function should succeed")
Expand Down Expand Up @@ -157,7 +157,7 @@ func setup(t *testing.T) {
Slack: underlying,
Token: "sometoken",
}
result = webhooks.ApplyResult{
result = webhooks.EventResult{
Workspace: "production",
Repo: models.Repo{
FullName: "runatlantis/atlantis",
Expand Down
4 changes: 2 additions & 2 deletions server/events/webhooks/slack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func TestSend_PostMessage(t *testing.T) {
BranchRegex: regex,
Channel: channel,
}
result := webhooks.ApplyResult{
result := webhooks.EventResult{
Workspace: "production",
Pull: models.PullRequest{
BaseBranch: "main",
Expand All @@ -65,7 +65,7 @@ func TestSend_NoopSuccess(t *testing.T) {
BranchRegex: regex,
Channel: channel,
}
result := webhooks.ApplyResult{
result := webhooks.EventResult{
Workspace: "production",
Pull: models.PullRequest{
BaseBranch: "main",
Expand Down
Loading