Skip to content

Commit

Permalink
Merge pull request #28 from runatlantis/master
Browse files Browse the repository at this point in the history
fetch upstream
  • Loading branch information
ghaiszaher authored Nov 26, 2021
2 parents 1108041 + 33b4d63 commit f7a9655
Show file tree
Hide file tree
Showing 28 changed files with 518 additions and 222 deletions.
5 changes: 5 additions & 0 deletions runatlantis.io/docs/repo-level-atlantis-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ workflows:
steps:
- run: echo hi
- apply
allowed_regexp_prefixes:
- dev/
- staging/
```
## Use Cases
Expand Down Expand Up @@ -194,6 +197,7 @@ automerge:
delete_source_branch_on_merge:
projects:
workflows:
allowed_regexp_prefixes:
```
| Key | Type | Default | Required | Description |
|-------------------------------|----------------------------------------------------------|---------|----------|-------------------------------------------------------------|
Expand All @@ -202,6 +206,7 @@ workflows:
| delete_source_branch_on_merge | bool | `false` | no | Automatically deletes the source branch on merge |
| projects | array[[Project](repo-level-atlantis-yaml.html#project)] | `[]` | no | Lists the projects in this repo |
| workflows<br />*(restricted)* | map[string: [Workflow](custom-workflows.html#reference)] | `{}` | no | Custom workflows |
| allowed_regexp_prefixes | array[string] | `[]` | no | Lists the allowed regexp prefixes to use when the [`--enable-regexp-cmd`](server-configuration.html#enable-regexp-cmd) flag is used

### Project
```yaml
Expand Down
3 changes: 2 additions & 1 deletion runatlantis.io/docs/terraform-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,6 @@ Atlantis will automatically download the version specified.
:::

::: tip NOTE
The Atlantis [latest docker image](https://hub.docker.com/layers/runatlantis/atlantis/latest/images/sha256-4f80472e20bd899b03a619e593f9e7b9a55d9e630850de443b988295f63f5c7a?context=explore) tends to have recent versions of Terraform, but there may be a delay as new versions are released. The highest version of Terraform allowed in your code is the version specified by `DEFAULT_TERRAFORM_VERSION` in the image your server is running.
The Atlantis [latest docker image](https://github.com/runatlantis/atlantis/pkgs/container/atlantis/9854680?tag=latest) tends to have recent versions of Terraform, but there may be a delay as new versions are released. The highest version of Terraform allowed in your code is the version specified by `DEFAULT_TERRAFORM_VERSION` in the image your server is running.
:::

7 changes: 5 additions & 2 deletions server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,7 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) {
userConfig.EnablePolicyChecksFlag = true

ctrl, vcsClient, githubGetter, atlantisWorkspace := setupE2E(t, c.RepoDir)

// Set the repo to be cloned through the testing backdoor.
repoDir, headSHA, cleanup := initializeRepo(t, c.RepoDir)
defer cleanup()
Expand Down Expand Up @@ -937,8 +938,7 @@ func setupE2E(t *testing.T, repoDir string) (events_controllers.VCSEventsControl
Webhooks: &mockWebhookSender{},
WorkingDirLocker: locker,
AggregateApplyRequirements: &events.AggregateApplyRequirements{
PullApprovedChecker: e2eVCSClient,
WorkingDir: workingDir,
WorkingDir: workingDir,
},
}

Expand Down Expand Up @@ -984,6 +984,8 @@ func setupE2E(t *testing.T, repoDir string) (events_controllers.VCSEventsControl
boltdb,
)

e2ePullReqStatusFetcher := vcs.NewPullReqStatusFetcher(e2eVCSClient)

applyCommandRunner := events.NewApplyCommandRunner(
e2eVCSClient,
false,
Expand All @@ -998,6 +1000,7 @@ func setupE2E(t *testing.T, repoDir string) (events_controllers.VCSEventsControl
parallelPoolSize,
silenceNoProjects,
false,
e2ePullReqStatusFetcher,
)

approvePoliciesCommandRunner := events.NewApprovePoliciesCommandRunner(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ FAIL - <redacted plan file> - main - WARNING: Null Resource creation is prohibit
1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions

```
* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.
* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:
* `atlantis approve_policies`
* :repeat: Or, address the policy failure by modifying the codebase and re-planning.


Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ FAIL - <redacted plan file> - main - WARNING: Null Resource creation is prohibit
1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions

```
* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.
* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:
* `atlantis approve_policies`
* :repeat: Or, address the policy failure by modifying the codebase and re-planning.


Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ FAIL - <redacted plan file> - null_resource_policy - WARNING: Null Resource crea
1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions

```
* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.
* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:
* `atlantis approve_policies`
* :repeat: Or, address the policy failure by modifying the codebase and re-planning.


Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ FAIL - <redacted plan file> - main - WARNING: Forbidden Resource creation is pro
1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions

```
* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.
* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:
* `atlantis approve_policies`
* :repeat: Or, address the policy failure by modifying the codebase and re-planning.


---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ FAIL - <redacted plan file> - main - WARNING: Null Resource creation is prohibit
1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions

```
* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.
* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:
* `atlantis approve_policies`
* :repeat: Or, address the policy failure by modifying the codebase and re-planning.


34 changes: 18 additions & 16 deletions server/events/apply_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ func NewApplyCommandRunner(
parallelPoolSize int,
SilenceNoProjects bool,
silenceVCSStatusNoProjects bool,
pullReqStatusFetcher vcs.PullReqStatusFetcher,
) *ApplyCommandRunner {
return &ApplyCommandRunner{
vcsClient: vcsClient,
Expand All @@ -36,21 +37,23 @@ func NewApplyCommandRunner(
parallelPoolSize: parallelPoolSize,
SilenceNoProjects: SilenceNoProjects,
silenceVCSStatusNoProjects: silenceVCSStatusNoProjects,
pullReqStatusFetcher: pullReqStatusFetcher,
}
}

type ApplyCommandRunner struct {
DisableApplyAll bool
DB *db.BoltDB
locker locking.ApplyLockChecker
vcsClient vcs.Client
commitStatusUpdater CommitStatusUpdater
prjCmdBuilder ProjectApplyCommandBuilder
prjCmdRunner ProjectApplyCommandRunner
autoMerger *AutoMerger
pullUpdater *PullUpdater
dbUpdater *DBUpdater
parallelPoolSize int
DisableApplyAll bool
DB *db.BoltDB
locker locking.ApplyLockChecker
vcsClient vcs.Client
commitStatusUpdater CommitStatusUpdater
prjCmdBuilder ProjectApplyCommandBuilder
prjCmdRunner ProjectApplyCommandRunner
autoMerger *AutoMerger
pullUpdater *PullUpdater
dbUpdater *DBUpdater
parallelPoolSize int
pullReqStatusFetcher vcs.PullReqStatusFetcher
// SilenceNoProjects is whether Atlantis should respond to PRs if no projects
// are found
SilenceNoProjects bool
Expand Down Expand Up @@ -98,17 +101,16 @@ func (a *ApplyCommandRunner) Run(ctx *CommandContext, cmd *CommentCommand) {
// We do this here because when we set a "Pending" status, if users have
// required the Atlantis status checks to pass, then we've now changed
// the mergeability status of the pull request.
ctx.PullMergeable, err = a.vcsClient.PullIsMergeable(baseRepo, pull)
// This sets the approved, mergeable, and sqlocked status in the context.
ctx.PullRequestStatus, err = a.pullReqStatusFetcher.FetchPullStatus(baseRepo, pull)
if err != nil {
// On error we continue the request with mergeable assumed false.
// We want to continue because not all apply's will need this status,
// only if they rely on the mergeability requirement.
ctx.PullMergeable = false
ctx.Log.Warn("unable to get mergeable status: %s. Continuing with mergeable assumed false", err)
// All PullRequestStatus fields are set to false by default when error.
ctx.Log.Warn("unable to get pull request status: %s. Continuing with mergeable and approved assumed false", err)
}

ctx.Log.Info("pull request mergeable status: %t", ctx.PullMergeable)

var projectCmds []models.ProjectCommandContext
projectCmds, err = a.prjCmdBuilder.BuildApplyCommands(ctx, cmd)

Expand Down
14 changes: 3 additions & 11 deletions server/events/apply_requirement_handler.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package events

import (
"github.com/pkg/errors"
"github.com/runatlantis/atlantis/server/core/runtime"
"github.com/runatlantis/atlantis/server/events/models"
"github.com/runatlantis/atlantis/server/events/yaml/raw"
"github.com/runatlantis/atlantis/server/events/yaml/valid"
Expand All @@ -14,20 +12,14 @@ type ApplyRequirement interface {
}

type AggregateApplyRequirements struct {
PullApprovedChecker runtime.PullApprovedChecker
WorkingDir WorkingDir
WorkingDir WorkingDir
}

func (a *AggregateApplyRequirements) ValidateProject(repoDir string, ctx models.ProjectCommandContext) (failure string, err error) {

for _, req := range ctx.ApplyRequirements {
switch req {
case raw.ApprovedApplyRequirement:
approvalStatus, err := a.PullApprovedChecker.PullIsApproved(ctx.Pull.BaseRepo, ctx.Pull) // nolint: vetshadow
if err != nil {
return "", errors.Wrap(err, "checking if pull request was approved")
}
if !approvalStatus.IsApproved {
if !ctx.PullReqStatus.ApprovalStatus.IsApproved {
return "Pull request must be approved by at least one person other than the author before running apply.", nil
}
// this should come before mergeability check since mergeability is a superset of this check.
Expand All @@ -36,7 +28,7 @@ func (a *AggregateApplyRequirements) ValidateProject(repoDir string, ctx models.
return "All policies must pass for project before running apply", nil
}
case raw.MergeableApplyRequirement:
if !ctx.PullMergeable {
if !ctx.PullReqStatus.Mergeable {
return "Pull request must be mergeable before running apply.", nil
}
case raw.UnDivergedApplyRequirement:
Expand Down
5 changes: 0 additions & 5 deletions server/events/command_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ type CommandContext struct {
// User is the user that triggered this command.
User models.User
Log logging.SimpleLogging
// PullMergeable is true if Pull is able to be merged. This is available in
// the CommandContext because we want to collect this information before we
// set our own build statuses which can affect mergeability if users have
// required the Atlantis status to be successful prior to merging.
PullMergeable bool

// Current PR state
PullRequestStatus models.PullReqStatus
Expand Down
4 changes: 4 additions & 0 deletions server/events/command_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"testing"

"github.com/runatlantis/atlantis/server/core/db"
"github.com/runatlantis/atlantis/server/events/vcs"
"github.com/runatlantis/atlantis/server/events/yaml/valid"
"github.com/runatlantis/atlantis/server/logging"

Expand Down Expand Up @@ -131,6 +132,8 @@ func setup(t *testing.T) *vcsmocks.MockClient {
defaultBoltDB,
)

pullReqStatusFetcher := vcs.NewPullReqStatusFetcher(vcsClient)

applyCommandRunner = events.NewApplyCommandRunner(
vcsClient,
false,
Expand All @@ -145,6 +148,7 @@ func setup(t *testing.T) *vcsmocks.MockClient {
parallelPoolSize,
SilenceNoProjects,
false,
pullReqStatusFetcher,
)

approvePoliciesCommandRunner = events.NewApprovePoliciesCommandRunner(
Expand Down
11 changes: 8 additions & 3 deletions server/events/comment_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,19 @@ type CommentParseResult struct {
// Valid commands contain:
// - The initial "executable" name, 'run' or 'atlantis' or '@GithubUser'
// where GithubUser is the API user Atlantis is running as.
// - Then a command, either 'plan', 'apply', 'approve_policies', or 'help'.
// - Then a command: 'plan', 'apply', 'unlock', 'version, 'approve_policies',
// or 'help'.
// - Then optional flags, then an optional separator '--' followed by optional
// extra flags to be appended to the terraform plan/apply command.
//
// Examples:
// - atlantis help
// - run plan
// - run apply
// - @GithubUser plan -w staging
// - atlantis plan -w staging -d dir --verbose
// - atlantis plan --verbose -- -key=value -key2 value2
// - atlantis unlock
// - atlantis version
// - atlantis approve_policies
//
func (e *CommentParser) Parse(comment string, vcsHost models.VCSHostType) CommentParseResult {
Expand Down Expand Up @@ -166,7 +169,7 @@ func (e *CommentParser) Parse(comment string, vcsHost models.VCSHostType) Commen
return CommentParseResult{CommentResponse: e.HelpComment(e.ApplyDisabled)}
}

// Need to have a plan, apply, approve_policy or unlock at this point.
// Need plan, apply, unlock, approve_policies, or version at this point.
if !e.stringInSlice(command, []string{models.PlanCommand.String(), models.ApplyCommand.String(), models.UnlockCommand.String(), models.ApprovePoliciesCommand.String(), models.VersionCommand.String()}) {
return CommentParseResult{CommentResponse: fmt.Sprintf("```\nError: unknown command %q.\nRun 'atlantis --help' for usage.\n```", command)}
}
Expand Down Expand Up @@ -404,6 +407,8 @@ Commands:
{{- end }}
unlock Removes all atlantis locks and discards all plans for this PR.
To unlock a specific plan you can use the Atlantis UI.
approve_policies
Approves all current policy checking failures for the PR.
version Print the output of 'terraform version'
help View help.
Expand Down
4 changes: 4 additions & 0 deletions server/events/comment_parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,8 @@ Commands:
To only apply a specific plan, use the -d, -w and -p flags.
unlock Removes all atlantis locks and discards all plans for this PR.
To unlock a specific plan you can use the Atlantis UI.
approve_policies
Approves all current policy checking failures for the PR.
version Print the output of 'terraform version'
help View help.
Expand Down Expand Up @@ -756,6 +758,8 @@ Commands:
To plan a specific project, use the -d, -w and -p flags.
unlock Removes all atlantis locks and discards all plans for this PR.
To unlock a specific plan you can use the Atlantis UI.
approve_policies
Approves all current policy checking failures for the PR.
version Print the output of 'terraform version'
help View help.
Expand Down
4 changes: 3 additions & 1 deletion server/events/markdown_renderer.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,9 @@ var unwrappedErrTmplText = "**{{.Command}} Error**\n" +
"{{.Error}}\n" +
"```" +
"{{ if eq .Command \"Policy Check\" }}" +
"\n* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.\n" +
"\n* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:\n" +
" * `atlantis approve_policies`\n" +
"* :repeat: Or, address the policy failure by modifying the codebase and re-planning.\n" +
"{{ end }}"
var wrappedErrTmplText = "**{{.Command}} Error**\n" +
"<details><summary>Show Output</summary>\n\n" +
Expand Down
8 changes: 6 additions & 2 deletions server/events/markdown_renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ func TestRenderErr(t *testing.T) {
models.PolicyCheckCommand,
err,
"**Policy Check Error**\n```\nerr\n```" +
"\n* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.\n\n",
"\n* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:\n" +
" * `atlantis approve_policies`\n" +
"* :repeat: Or, address the policy failure by modifying the codebase and re-planning.\n\n",
},
}

Expand Down Expand Up @@ -639,7 +641,9 @@ $$$
$$$
error
$$$
* :heavy_check_mark: To **approve** failing policies either request an approval from approvers or address the failure by modifying the codebase.
* :heavy_check_mark: To **approve** failing policies an authorized approver can comment:
* $atlantis approve_policies$
* :repeat: Or, address the policy failure by modifying the codebase and re-planning.
---
Expand Down
13 changes: 6 additions & 7 deletions server/events/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const (
planfileSlashReplace = "::"
)

type PullReqStatus struct {
ApprovalStatus ApprovalStatus
Mergeable bool
}

// Repo is a VCS repository.
type Repo struct {
// FullName is the owner and repo name separated
Expand Down Expand Up @@ -142,10 +147,6 @@ func NewRepo(vcsHostType VCSHostType, repoFullName string, cloneURL string, vcsU
}, nil
}

type PullReqStatus struct {
Approved ApprovalStatus
}

type ApprovalStatus struct {
IsApproved bool
ApprovedBy string
Expand Down Expand Up @@ -374,9 +375,7 @@ type ProjectCommandContext struct {
HeadRepo Repo
// Log is a logger that's been set up for this context.
Log logging.SimpleLogging
// PullMergeable is true if the pull request for this project is able to be merged.
PullMergeable bool
// CurrentProjectPlanStatus is the status of the current project prior to this command.
// PullReqStatus holds state about the PR that requires additional computation outside models.PullRequest
PullReqStatus PullReqStatus
// CurrentProjectPlanStatus is the status of the current project prior to this command.
ProjectPlanStatus ProjectPlanStatus
Expand Down
Loading

0 comments on commit f7a9655

Please sign in to comment.