-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
commit_status_updater.go
137 lines (118 loc) · 6.39 KB
/
commit_status_updater.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright 2017 HootSuite Media Inc.
//
// Licensed under the Apache License, Version 2.0 (the License);
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an AS IS BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Modified hereafter by contributors to runatlantis/atlantis.
package events
import (
"fmt"
"github.com/runatlantis/atlantis/server/core/runtime"
"github.com/runatlantis/atlantis/server/events/command"
"github.com/runatlantis/atlantis/server/events/models"
"github.com/runatlantis/atlantis/server/events/vcs"
"github.com/runatlantis/atlantis/server/logging"
"golang.org/x/text/cases"
"golang.org/x/text/language"
)
//go:generate pegomock generate github.com/runatlantis/atlantis/server/events --package mocks -o mocks/mock_commit_status_updater.go CommitStatusUpdater
// CommitStatusUpdater updates the status of a commit with the VCS host. We set
// the status to signify whether the plan/apply succeeds.
type CommitStatusUpdater interface {
// UpdateCombined updates the combined status of the head commit of pull.
// A combined status represents all the projects modified in the pull.
UpdateCombined(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, status models.CommitStatus, cmdName command.Name) error
// UpdateCombinedCount updates the combined status to reflect the
// numSuccess out of numTotal.
UpdateCombinedCount(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, status models.CommitStatus, cmdName command.Name, numSuccess int, numTotal int) error
UpdatePreWorkflowHook(logger logging.SimpleLogging, pull models.PullRequest, status models.CommitStatus, hookDescription string, runtimeDescription string, url string) error
UpdatePostWorkflowHook(logger logging.SimpleLogging, pull models.PullRequest, status models.CommitStatus, hookDescription string, runtimeDescription string, url string) error
}
// DefaultCommitStatusUpdater implements CommitStatusUpdater.
type DefaultCommitStatusUpdater struct {
Client vcs.Client
// StatusName is the name used to identify Atlantis when creating PR statuses.
StatusName string
}
// ensure DefaultCommitStatusUpdater implements runtime.StatusUpdater interface
// cause runtime.StatusUpdater is extracted for resolving circular dependency
var _ runtime.StatusUpdater = (*DefaultCommitStatusUpdater)(nil)
func (d *DefaultCommitStatusUpdater) UpdateCombined(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, status models.CommitStatus, cmdName command.Name) error {
src := fmt.Sprintf("%s/%s", d.StatusName, cmdName.String())
var descripWords string
switch status {
case models.PendingCommitStatus:
descripWords = genProjectStatusDescription(cmdName.String(), "in progress...")
case models.FailedCommitStatus:
descripWords = genProjectStatusDescription(cmdName.String(), "failed.")
case models.SuccessCommitStatus:
descripWords = genProjectStatusDescription(cmdName.String(), "succeeded.")
}
return d.Client.UpdateStatus(logger, repo, pull, status, src, descripWords, "")
}
func (d *DefaultCommitStatusUpdater) UpdateCombinedCount(logger logging.SimpleLogging, repo models.Repo, pull models.PullRequest, status models.CommitStatus, cmdName command.Name, numSuccess int, numTotal int) error {
src := fmt.Sprintf("%s/%s", d.StatusName, cmdName.String())
cmdVerb := "unknown"
switch cmdName {
case command.Plan:
cmdVerb = "planned"
case command.PolicyCheck:
cmdVerb = "policies checked"
case command.Apply:
cmdVerb = "applied"
}
return d.Client.UpdateStatus(logger, repo, pull, status, src, fmt.Sprintf("%d/%d projects %s successfully.", numSuccess, numTotal, cmdVerb), "")
}
func (d *DefaultCommitStatusUpdater) UpdateProject(ctx command.ProjectContext, cmdName command.Name, status models.CommitStatus, url string, result *command.ProjectResult) error {
projectID := ctx.ProjectName
if projectID == "" {
projectID = fmt.Sprintf("%s/%s", ctx.RepoRelDir, ctx.Workspace)
}
src := fmt.Sprintf("%s/%s: %s", d.StatusName, cmdName.String(), projectID)
var descripWords string
switch status {
case models.PendingCommitStatus:
descripWords = genProjectStatusDescription(cmdName.String(), "in progress...")
case models.FailedCommitStatus:
descripWords = genProjectStatusDescription(cmdName.String(), "failed.")
case models.SuccessCommitStatus:
if result != nil && result.PlanSuccess != nil {
descripWords = result.PlanSuccess.DiffSummary()
} else {
descripWords = genProjectStatusDescription(cmdName.String(), "succeeded.")
}
}
return d.Client.UpdateStatus(ctx.Log, ctx.BaseRepo, ctx.Pull, status, src, descripWords, url)
}
func genProjectStatusDescription(cmdName, description string) string {
return fmt.Sprintf("%s %s", cases.Title(language.English).String(cmdName), description)
}
func (d *DefaultCommitStatusUpdater) UpdatePreWorkflowHook(log logging.SimpleLogging, pull models.PullRequest, status models.CommitStatus, hookDescription string, runtimeDescription string, url string) error {
return d.updateWorkflowHook(log, pull, status, hookDescription, runtimeDescription, "pre_workflow_hook", url)
}
func (d *DefaultCommitStatusUpdater) UpdatePostWorkflowHook(log logging.SimpleLogging, pull models.PullRequest, status models.CommitStatus, hookDescription string, runtimeDescription string, url string) error {
return d.updateWorkflowHook(log, pull, status, hookDescription, runtimeDescription, "post_workflow_hook", url)
}
func (d *DefaultCommitStatusUpdater) updateWorkflowHook(log logging.SimpleLogging, pull models.PullRequest, status models.CommitStatus, hookDescription string, runtimeDescription string, workflowType string, url string) error {
src := fmt.Sprintf("%s/%s: %s", d.StatusName, workflowType, hookDescription)
var descripWords string
if runtimeDescription != "" {
descripWords = runtimeDescription
} else {
switch status {
case models.PendingCommitStatus:
descripWords = "in progress..."
case models.FailedCommitStatus:
descripWords = "failed."
case models.SuccessCommitStatus:
descripWords = "succeeded."
}
}
return d.Client.UpdateStatus(log, pull.BaseRepo, pull, status, src, descripWords, url)
}