Skip to content

Commit

Permalink
Merge pull request #904 from runatlantis/status-names
Browse files Browse the repository at this point in the history
Set custom PR status name
  • Loading branch information
lkysow authored Jan 20, 2020
2 parents 8232630 + ec92e43 commit 8eb5bb8
Show file tree
Hide file tree
Showing 14 changed files with 74 additions and 13 deletions.
9 changes: 9 additions & 0 deletions cmd/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ const (
SSLCertFileFlag = "ssl-cert-file"
SSLKeyFileFlag = "ssl-key-file"
TFDownloadURLFlag = "tf-download-url"
VCSStatusName = "vcs-status-name"
TFEHostnameFlag = "tfe-hostname"
TFETokenFlag = "tfe-token"
WriteGitCredsFlag = "write-git-creds"
Expand All @@ -89,6 +90,7 @@ const (
DefaultPort = 4141
DefaultTFDownloadURL = "https://releases.hashicorp.com"
DefaultTFEHostname = "app.terraform.io"
DefaultVCSStatusName = "atlantis"
)

var stringFlags = map[string]stringFlag{
Expand Down Expand Up @@ -221,6 +223,10 @@ var stringFlags = map[string]stringFlag{
description: "Terraform version to default to (ex. v0.12.0). Will download if not yet on disk." +
" If not set, Atlantis uses the terraform binary in its PATH.",
},
VCSStatusName: {
description: "Name used to identify Atlantis for pull request statuses.",
defaultValue: DefaultVCSStatusName,
},
}

var boolFlags = map[string]boolFlag{
Expand Down Expand Up @@ -463,6 +469,9 @@ func (s *ServerCmd) setDefaults(c *server.UserConfig) {
if c.TFDownloadURL == "" {
c.TFDownloadURL = DefaultTFDownloadURL
}
if c.VCSStatusName == "" {
c.VCSStatusName = DefaultVCSStatusName
}
if c.TFEHostname == "" {
c.TFEHostname = DefaultTFEHostname
}
Expand Down
16 changes: 16 additions & 0 deletions cmd/server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ func TestExecute_Defaults(t *testing.T) {
Equals(t, "https://releases.hashicorp.com", passedConfig.TFDownloadURL)
Equals(t, "app.terraform.io", passedConfig.TFEHostname)
Equals(t, "", passedConfig.TFEToken)
Equals(t, "atlantis", passedConfig.VCSStatusName)
Equals(t, false, passedConfig.WriteGitCreds)
}

Expand Down Expand Up @@ -519,6 +520,7 @@ func TestExecute_Flags(t *testing.T) {
cmd.TFDownloadURLFlag: "https://my-hostname.com",
cmd.TFEHostnameFlag: "my-hostname",
cmd.TFETokenFlag: "my-token",
cmd.VCSStatusName: "my-status",
cmd.WriteGitCredsFlag: true,
})
err := c.Execute()
Expand Down Expand Up @@ -559,6 +561,7 @@ func TestExecute_Flags(t *testing.T) {
Equals(t, "https://my-hostname.com", passedConfig.TFDownloadURL)
Equals(t, "my-hostname", passedConfig.TFEHostname)
Equals(t, "my-token", passedConfig.TFEToken)
Equals(t, "my-status", passedConfig.VCSStatusName)
Equals(t, true, passedConfig.WriteGitCreds)
}

Expand Down Expand Up @@ -600,6 +603,7 @@ ssl-key-file: key-file
tf-download-url: https://my-hostname.com
tfe-hostname: my-hostname
tfe-token: my-token
vcs-status-name: my-status
write-git-creds: true
`)
defer os.Remove(tmpFile) // nolint: errcheck
Expand Down Expand Up @@ -644,6 +648,7 @@ write-git-creds: true
Equals(t, "https://my-hostname.com", passedConfig.TFDownloadURL)
Equals(t, "my-hostname", passedConfig.TFEHostname)
Equals(t, "my-token", passedConfig.TFEToken)
Equals(t, "my-status", passedConfig.VCSStatusName)
Equals(t, true, passedConfig.WriteGitCreds)
}

Expand Down Expand Up @@ -684,6 +689,7 @@ ssl-key-file: key-file
tf-download-url: https://my-hostname.com
tfe-hostname: my-hostname
tfe-token: my-token
vcs-status-name: my-status
write-git-creds: true
`)
defer os.Remove(tmpFile) // nolint: errcheck
Expand Down Expand Up @@ -725,6 +731,7 @@ write-git-creds: true
"TF_DOWNLOAD_URL": "https://override-my-hostname.com",
"TFE_HOSTNAME": "override-my-hostname",
"TFE_TOKEN": "override-my-token",
"VCS_STATUS_NAME": "override-status-name",
"WRITE_GIT_CREDS": "false",
} {
os.Setenv("ATLANTIS_"+name, value) // nolint: errcheck
Expand Down Expand Up @@ -769,6 +776,7 @@ write-git-creds: true
Equals(t, "https://override-my-hostname.com", passedConfig.TFDownloadURL)
Equals(t, "override-my-hostname", passedConfig.TFEHostname)
Equals(t, "override-my-token", passedConfig.TFEToken)
Equals(t, "override-status-name", passedConfig.VCSStatusName)
Equals(t, false, passedConfig.WriteGitCreds)
}

Expand Down Expand Up @@ -808,8 +816,10 @@ slack-token: slack-token
ssl-cert-file: cert-file
ssl-key-file: key-file
tf-download-url: https://my-hostname.com
status-name: status-name
tfe-hostname: my-hostname
tfe-token: my-token
vcs-status-name: my-status
write-git-creds: true
`)

Expand Down Expand Up @@ -850,6 +860,7 @@ write-git-creds: true
cmd.TFDownloadURLFlag: "https://override-my-hostname.com",
cmd.TFEHostnameFlag: "override-my-hostname",
cmd.TFETokenFlag: "override-my-token",
cmd.VCSStatusName: "override-status-name",
cmd.WriteGitCredsFlag: false,
})
err := c.Execute()
Expand Down Expand Up @@ -888,6 +899,7 @@ write-git-creds: true
Equals(t, "https://override-my-hostname.com", passedConfig.TFDownloadURL)
Equals(t, "override-my-hostname", passedConfig.TFEHostname)
Equals(t, "override-my-token", passedConfig.TFEToken)
Equals(t, "override-status-name", passedConfig.VCSStatusName)
Equals(t, false, passedConfig.WriteGitCreds)

}
Expand Down Expand Up @@ -929,8 +941,10 @@ func TestExecute_FlagEnvVarOverride(t *testing.T) {
"SSL_CERT_FILE": "cert-file",
"SSL_KEY_FILE": "key-file",
"TF_DOWNLOAD_URL": "https://my-hostname.com",
"STATUS_NAME": "status-name",
"TFE_HOSTNAME": "my-hostname",
"TFE_TOKEN": "my-token",
"VCS_STATUS_NAME": "my-status",
"WRITE_GIT_CREDS": "true",
}
for name, value := range envVars {
Expand Down Expand Up @@ -979,6 +993,7 @@ func TestExecute_FlagEnvVarOverride(t *testing.T) {
cmd.TFDownloadURLFlag: "https://override-my-hostname.com",
cmd.TFEHostnameFlag: "override-my-hostname",
cmd.TFETokenFlag: "override-my-token",
cmd.VCSStatusName: "override-status-name",
cmd.WriteGitCredsFlag: false,
})
err := c.Execute()
Expand Down Expand Up @@ -1019,6 +1034,7 @@ func TestExecute_FlagEnvVarOverride(t *testing.T) {
Equals(t, "https://override-my-hostname.com", passedConfig.TFDownloadURL)
Equals(t, "override-my-hostname", passedConfig.TFEHostname)
Equals(t, "override-my-token", passedConfig.TFEToken)
Equals(t, "override-status-name", passedConfig.VCSStatusName)
Equals(t, false, passedConfig.WriteGitCreds)
}

Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,11 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3
golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0 h1:Dh6fw+p6FyRl5x/FvNswO1ji0lIGzm3KP8Y9VkS9PTE=
golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a h1:3IG7HNvPBDvrxpnTWA6zpeNCS5ydX6cdt6oOiGlC8qg=
golang.org/x/tools v0.0.0-20191113232020-e2727e816f5a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.0.0-20180910000450-7ca32eb868bf/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181030000543-1d582fd0359e/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
google.golang.org/api v0.0.0-20181220000619-583d854617af/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
Expand Down
9 changes: 9 additions & 0 deletions runatlantis.io/docs/server-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -448,6 +448,15 @@ Values are chosen in this order:
```
A token for Terraform Cloud/Terraform Enteprise integration. See [Terraform Cloud](terraform-cloud.html) for more details.

* ### `--vcs-status-name`
```bash
atlantis server --vcs-status-name="atlantis-dev"
```
Name used to identify Atlantis when updating a pull request status. Defaults to `atlantis`.

This is useful when running multiple Atlantis servers against a single repository so you can
give each Atlantis server its own unique name to prevent the statuses clashing.

* ### `--write-git-creds`
```bash
atlantis server --write-git-creds
Expand Down
2 changes: 1 addition & 1 deletion server/events/command_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ func setup(t *testing.T) *vcsmocks.MockClient {
ThenReturn(pullLogger)
ch = events.DefaultCommandRunner{
VCSClient: vcsClient,
CommitStatusUpdater: &events.DefaultCommitStatusUpdater{vcsClient},
CommitStatusUpdater: &events.DefaultCommitStatusUpdater{vcsClient, "atlantis"},
EventParser: eventParsing,
MarkdownRenderer: &events.MarkdownRenderer{},
GithubPullGetter: githubGetter,
Expand Down
8 changes: 5 additions & 3 deletions server/events/commit_status_updater.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@ type CommitStatusUpdater interface {
// DefaultCommitStatusUpdater implements CommitStatusUpdater.
type DefaultCommitStatusUpdater struct {
Client vcs.Client
// StatusName is the name used to identify Atlantis when creating PR statuses.
StatusName string
}

func (d *DefaultCommitStatusUpdater) UpdateCombined(repo models.Repo, pull models.PullRequest, status models.CommitStatus, command models.CommandName) error {
src := fmt.Sprintf("atlantis/%s", command.String())
src := fmt.Sprintf("%s/%s", d.StatusName, command.String())
var descripWords string
switch status {
case models.PendingCommitStatus:
Expand All @@ -58,7 +60,7 @@ func (d *DefaultCommitStatusUpdater) UpdateCombined(repo models.Repo, pull model
}

func (d *DefaultCommitStatusUpdater) UpdateCombinedCount(repo models.Repo, pull models.PullRequest, status models.CommitStatus, command models.CommandName, numSuccess int, numTotal int) error {
src := fmt.Sprintf("atlantis/%s", command.String())
src := fmt.Sprintf("%s/%s", d.StatusName, command.String())
cmdVerb := "planned"
if command == models.ApplyCommand {
cmdVerb = "applied"
Expand All @@ -71,7 +73,7 @@ func (d *DefaultCommitStatusUpdater) UpdateProject(ctx models.ProjectCommandCont
if projectID == "" {
projectID = fmt.Sprintf("%s/%s", ctx.RepoRelDir, ctx.Workspace)
}
src := fmt.Sprintf("atlantis/%s: %s", cmdName.String(), projectID)
src := fmt.Sprintf("%s/%s: %s", d.StatusName, cmdName.String(), projectID)
var descripWords string
switch status {
case models.PendingCommitStatus:
Expand Down
27 changes: 22 additions & 5 deletions server/events/commit_status_updater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ func TestUpdateCombined(t *testing.T) {
t.Run(c.expDescrip, func(t *testing.T) {
RegisterMockTestingT(t)
client := mocks.NewMockClient()
s := events.DefaultCommitStatusUpdater{Client: client}
s := events.DefaultCommitStatusUpdater{Client: client, StatusName: "atlantis"}
err := s.UpdateCombined(models.Repo{}, models.PullRequest{}, c.status, c.command)
Ok(t, err)

Expand Down Expand Up @@ -132,11 +132,11 @@ func TestUpdateCombinedCount(t *testing.T) {
t.Run(c.expDescrip, func(t *testing.T) {
RegisterMockTestingT(t)
client := mocks.NewMockClient()
s := events.DefaultCommitStatusUpdater{Client: client}
s := events.DefaultCommitStatusUpdater{Client: client, StatusName: "atlantis-test"}
err := s.UpdateCombinedCount(models.Repo{}, models.PullRequest{}, c.status, c.command, c.numSuccess, c.numTotal)
Ok(t, err)

expSrc := fmt.Sprintf("atlantis/%s", c.command)
expSrc := fmt.Sprintf("%s/%s", s.StatusName, c.command)
client.VerifyWasCalledOnce().UpdateStatus(models.Repo{}, models.PullRequest{}, c.status, expSrc, c.expDescrip, "")
})
}
Expand Down Expand Up @@ -169,7 +169,7 @@ func TestDefaultCommitStatusUpdater_UpdateProjectSrc(t *testing.T) {
for _, c := range cases {
t.Run(c.expSrc, func(t *testing.T) {
client := mocks.NewMockClient()
s := events.DefaultCommitStatusUpdater{Client: client}
s := events.DefaultCommitStatusUpdater{Client: client, StatusName: "atlantis"}
err := s.UpdateProject(models.ProjectCommandContext{
ProjectName: c.projectName,
RepoRelDir: c.repoRelDir,
Expand Down Expand Up @@ -227,7 +227,7 @@ func TestDefaultCommitStatusUpdater_UpdateProject(t *testing.T) {
for _, c := range cases {
t.Run(c.expDescrip, func(t *testing.T) {
client := mocks.NewMockClient()
s := events.DefaultCommitStatusUpdater{Client: client}
s := events.DefaultCommitStatusUpdater{Client: client, StatusName: "atlantis"}
err := s.UpdateProject(models.ProjectCommandContext{
RepoRelDir: ".",
Workspace: "default",
Expand All @@ -240,3 +240,20 @@ func TestDefaultCommitStatusUpdater_UpdateProject(t *testing.T) {
})
}
}

// Test that we can set the status name.
func TestDefaultCommitStatusUpdater_UpdateProjectCustomStatusName(t *testing.T) {
RegisterMockTestingT(t)
client := mocks.NewMockClient()
s := events.DefaultCommitStatusUpdater{Client: client, StatusName: "custom"}
err := s.UpdateProject(models.ProjectCommandContext{
RepoRelDir: ".",
Workspace: "default",
},
models.ApplyCommand,
models.SuccessCommitStatus,
"url")
Ok(t, err)
client.VerifyWasCalledOnce().UpdateStatus(models.Repo{}, models.PullRequest{},
models.SuccessCommitStatus, "custom/apply: ./default", "Apply succeeded.", "url")
}
1 change: 1 addition & 0 deletions server/events/matchers/models_pullrequest.go

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

1 change: 1 addition & 0 deletions server/events/matchers/models_repo.go

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

1 change: 1 addition & 0 deletions server/events/matchers/ptr_to_logging_simplelogger.go

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

3 changes: 1 addition & 2 deletions server/events/project_command_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@ import (
"testing"

"github.com/hashicorp/go-version"
"github.com/runatlantis/atlantis/server/events/runtime"

. "github.com/petergtz/pegomock"
"github.com/runatlantis/atlantis/server/events"
"github.com/runatlantis/atlantis/server/events/mocks"
"github.com/runatlantis/atlantis/server/events/mocks/matchers"
"github.com/runatlantis/atlantis/server/events/models"
"github.com/runatlantis/atlantis/server/events/runtime"
mocks2 "github.com/runatlantis/atlantis/server/events/runtime/mocks"
tmocks "github.com/runatlantis/atlantis/server/events/terraform/mocks"
"github.com/runatlantis/atlantis/server/events/yaml/valid"
Expand Down
3 changes: 2 additions & 1 deletion server/events/runtime/env_step_runner.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package runtime

import (
"github.com/runatlantis/atlantis/server/events/models"
"strings"

"github.com/runatlantis/atlantis/server/events/models"
)

// EnvStepRunner set environment variables.
Expand Down
2 changes: 1 addition & 1 deletion server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) {
return nil, errors.Wrap(err, "initializing webhooks")
}
vcsClient := vcs.NewClientProxy(githubClient, gitlabClient, bitbucketCloudClient, bitbucketServerClient, azuredevopsClient)
commitStatusUpdater := &events.DefaultCommitStatusUpdater{Client: vcsClient}
commitStatusUpdater := &events.DefaultCommitStatusUpdater{Client: vcsClient, StatusName: userConfig.VCSStatusName}
terraformClient, err := terraform.NewClient(
logger,
userConfig.DataDir,
Expand Down
1 change: 1 addition & 0 deletions server/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ type UserConfig struct {
TFDownloadURL string `mapstructure:"tf-download-url"`
TFEHostname string `mapstructure:"tfe-hostname"`
TFEToken string `mapstructure:"tfe-token"`
VCSStatusName string `mapstructure:"vcs-status-name"`
DefaultTFVersion string `mapstructure:"default-tf-version"`
Webhooks []WebhookConfig `mapstructure:"webhooks"`
WriteGitCreds bool `mapstructure:"write-git-creds"`
Expand Down

0 comments on commit 8eb5bb8

Please sign in to comment.