Skip to content

Commit

Permalink
Delete source branch on merge (#1357)
Browse files Browse the repository at this point in the history
Co-authored-by: Tapaszto, Istvan <istvan.tapaszto@msciintegration.onmicrosoft.com>
  • Loading branch information
tapaszto and Tapaszto, Istvan authored Apr 22, 2021
1 parent f290780 commit 632460b
Show file tree
Hide file tree
Showing 32 changed files with 329 additions and 195 deletions.
8 changes: 7 additions & 1 deletion runatlantis.io/docs/repo-level-atlantis-yaml.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,13 @@ need to be defined.
```yaml
version: 3
automerge: true
delete_source_branch_on_merge: true
projects:
- name: my-project-name
dir: .
workspace: default
terraform_version: v0.11.0
delete_source_branch_on_merge: true
autoplan:
when_modified: ["*.tf", "../modules/**.tf"]
enabled: true
Expand Down Expand Up @@ -189,13 +191,15 @@ See [Custom Workflow Use Cases: Custom Backend Config](custom-workflows.html#cus
```yaml
version:
automerge:
delete_source_branch_on_merge:
projects:
workflows:
```
| Key | Type | Default | Required | Description |
|-------------------------------|----------------------------------------------------------|---------|----------|-------------------------------------------------------------|
| version | int | none | **yes** | This key is required and must be set to `3` |
| automerge | bool | `false` | no | Automatically merge pull request when all plans are applied |
| automerge | bool | `false` | no | Automatically merges pull request when all plans are applied|
| 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 |

Expand All @@ -204,6 +208,7 @@ workflows:
name: myname
dir: mydir
workspace: myworkspace
delete_source_branch_on_merge:
autoplan:
terraform_version: 0.11.0
apply_requirements: ["approved"]
Expand All @@ -216,6 +221,7 @@ workflow: myworkflow
| dir | string | none | **yes** | The directory of this project relative to the repo root. For example if the project was under `./project1` then use `project1`. Use `.` to indicate the repo root. |
| workspace | string | `"default"` | no | The [Terraform workspace](https://www.terraform.io/docs/state/workspaces.html) for this project. Atlantis will switch to this workplace when planning/applying and will create it if it doesn't exist. |
| autoplan | [Autoplan](#autoplan) | none | no | A custom autoplan configuration. If not specified, will use the autoplan config. See [Autoplanning](autoplanning.html). |
| delete_source_branch_on_merge | bool | `false` | no | Automatically deletes the source branch on merge |
| terraform_version | string | none | no | A specific Terraform version to use when running commands for this project. Must be [Semver compatible](https://semver.org/), ex. `v0.11.0`, `0.12.0-beta1`. |
| apply_requirements<br />*(restricted)* | array[string] | none | no | Requirements that must be satisfied before `atlantis apply` can be run. Currently the only supported requirements are `approved` and `mergeable`. See [Apply Requirements](apply-requirements.html) for more details. |
| workflow <br />*(restricted)* | string | none | no | A custom workflow. If not specified, Atlantis will use its default workflow. |
Expand Down
23 changes: 14 additions & 9 deletions runatlantis.io/docs/server-side-repo-config.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ repos:

# allowed_overrides specifies which keys can be overridden by this repo in
# its atlantis.yaml file.
allowed_overrides: [apply_requirements, workflow]
allowed_overrides: [apply_requirements, workflow, delete_source_branch_on_merge]

# allowed_workflows specifies which workflows the repos that match
# are allowed to select.
Expand All @@ -52,6 +52,10 @@ repos:
# workflows. If false (default), the repo can only use server-side defined
# workflows.
allow_custom_workflows: true

# delete_source_branch_on_merge defines whether the source branch would be deleted on merge
# If false (default), the source branch won't be deleted on merge
delete_source_branch_on_merge: true

# pre_workflow_hooks defines arbitrary list of scripts to execute before workflow execution.
pre_workflow_hooks:
Expand Down Expand Up @@ -366,14 +370,15 @@ If you set a workflow with the key `default`, it will override this.
:::

### Repo
| Key | Type | Default | Required | Description |
|------------------------|----------|---------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| id | string | none | yes | Value can be a regular expression when specified as /&lt;regex&gt;/ or an exact string match. Repo IDs are of the form `{vcs hostname}/{org}/{name}`, ex. `github.com/owner/repo`. Hostname is specified without scheme or port. For Bitbucket Server, {org} is the **name** of the project, not the key. |
| workflow | string | none | no | A custom workflow. |
| apply_requirements | []string | none | no | Requirements that must be satisfied before `atlantis apply` can be run. Currently the only supported requirements are `approved` and `mergeable`. See [Apply Requirements](apply-requirements.html) for more details. |
| allowed_overrides | []string | none | no | A list of restricted keys that `atlantis.yaml` files can override. The only supported keys are `apply_requirements` and `workflow` |
| allowed_workflows | []string | none | no | A list of workflows that `atlantis.yaml` files can select from. |
| allow_custom_workflows | bool | false | no | Whether or not to allow [Custom Workflows](custom-workflows.html). |
| Key | Type | Default | Required | Description |
|-------------------------------|----------|---------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| id | string | none | yes | Value can be a regular expression when specified as /&lt;regex&gt;/ or an exact string match. Repo IDs are of the form `{vcs hostname}/{org}/{name}`, ex. `github.com/owner/repo`. Hostname is specified without scheme or port. For Bitbucket Server, {org} is the **name** of the project, not the key. |
| workflow | string | none | no | A custom workflow. |
| apply_requirements | []string | none | no | Requirements that must be satisfied before `atlantis apply` can be run. Currently the only supported requirements are `approved` and `mergeable`. See [Apply Requirements](apply-requirements.html) for more details. |
| allowed_overrides | []string | none | no | A list of restricted keys that `atlantis.yaml` files can override. The only supported keys are `apply_requirements`, `workflow` and `delete_source_branch_on_merge` |
| allowed_workflows | []string | none | no | A list of workflows that `atlantis.yaml` files can select from. |
| allow_custom_workflows | bool | false | no | Whether or not to allow [Custom Workflows](custom-workflows.html). |
| delete_source_branch_on_merge | bool | false | no | Whether or not to delete the source branch on merge (only AzureDevOps and GitLab support) |


:::tip Notes
Expand Down
2 changes: 1 addition & 1 deletion server/events/apply_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ func (a *ApplyCommandRunner) Run(ctx *CommandContext, cmd *CommentCommand) {
a.updateCommitStatus(ctx, pullStatus)

if a.autoMerger.automergeEnabled(projectCmds) {
a.autoMerger.automerge(ctx, pullStatus)
a.autoMerger.automerge(ctx, pullStatus, a.autoMerger.deleteSourceBranchOnMergeEnabled(projectCmds))
}
}

Expand Down
12 changes: 10 additions & 2 deletions server/events/automerger.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type AutoMerger struct {
GlobalAutomerge bool
}

func (c *AutoMerger) automerge(ctx *CommandContext, pullStatus models.PullStatus) {
func (c *AutoMerger) automerge(ctx *CommandContext, pullStatus models.PullStatus, deleteSourceBranchOnMerge bool) {
// We only automerge if all projects have been successfully applied.
for _, p := range pullStatus.Projects {
if p.Status != models.AppliedPlanStatus {
Expand All @@ -29,7 +29,9 @@ func (c *AutoMerger) automerge(ctx *CommandContext, pullStatus models.PullStatus

// Make the API call to perform the merge.
ctx.Log.Info("automerging pull request")
err := c.VCSClient.MergePull(ctx.Pull)
var pullOptions models.PullRequestOptions
pullOptions.DeleteSourceBranchOnMerge = deleteSourceBranchOnMerge
err := c.VCSClient.MergePull(ctx.Pull, pullOptions)

if err != nil {
ctx.Log.Err("automerging failed: %s", err)
Expand All @@ -48,3 +50,9 @@ func (c *AutoMerger) automergeEnabled(projectCmds []models.ProjectCommandContext
// Otherwise we check if this repo is configured for automerging.
(len(projectCmds) > 0 && projectCmds[0].AutomergeEnabled)
}

// deleteSourceBranchOnMergeEnabled returns true if we should delete the source branch on merge in this context.
func (c *AutoMerger) deleteSourceBranchOnMergeEnabled(projectCmds []models.ProjectCommandContext) bool {
//check if this repo is configured for automerging.
return (len(projectCmds) > 0 && projectCmds[0].DeleteSourceBranchOnMerge)
}
2 changes: 0 additions & 2 deletions server/events/command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,4 @@ func (c *DefaultCommandRunner) logPanics(baseRepo models.Repo, pullNum int, logg
}
}

// automergeComment is the comment that gets posted when Atlantis automatically
// merges the PR.
var automergeComment = `Automatically merging because all plans have been successfully applied.`
9 changes: 7 additions & 2 deletions server/events/command_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -649,8 +649,12 @@ func TestApplyWithAutoMerge_VSCMerge(t *testing.T) {
autoMerger.GlobalAutomerge = true
defer func() { autoMerger.GlobalAutomerge = false }()

pullOptions := models.PullRequestOptions{
DeleteSourceBranchOnMerge: false,
}

ch.RunCommentCommand(fixtures.GithubRepo, &fixtures.GithubRepo, nil, fixtures.User, fixtures.Pull.Num, &events.CommentCommand{Name: models.ApplyCommand})
vcsClient.VerifyWasCalledOnce().MergePull(modelPull)
vcsClient.VerifyWasCalledOnce().MergePull(modelPull, pullOptions)
}

func TestRunApply_DiscardedProjects(t *testing.T) {
Expand Down Expand Up @@ -688,7 +692,8 @@ func TestRunApply_DiscardedProjects(t *testing.T) {
When(workingDir.GetPullDir(matchers.AnyModelsRepo(), matchers.AnyModelsPullRequest())).
ThenReturn(tmp, nil)
ch.RunCommentCommand(fixtures.GithubRepo, &fixtures.GithubRepo, &pull, fixtures.User, fixtures.Pull.Num, &events.CommentCommand{Name: models.ApplyCommand})
vcsClient.VerifyWasCalled(Never()).MergePull(matchers.AnyModelsPullRequest())

vcsClient.VerifyWasCalled(Never()).MergePull(matchers.AnyModelsPullRequest(), matchers.AnyModelsPullRequestOptions())
}

func TestRunCommentCommand_DrainOngoing(t *testing.T) {
Expand Down
21 changes: 21 additions & 0 deletions server/events/mocks/matchers/models_pullrequestoptions.go

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

9 changes: 9 additions & 0 deletions server/events/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,13 @@ type PullRequest struct {
BaseRepo Repo
}

// PullRequestOptions is used to set optional paralmeters for PullRequest
type PullRequestOptions struct {
// When DeleteSourceBranchOnMerge flag is set to true VCS deletes the source branch after the PR is merged
// Applied by GitLab & AzureDevops
DeleteSourceBranchOnMerge bool
}

type PullRequestState int

const (
Expand Down Expand Up @@ -391,6 +398,8 @@ type ProjectCommandContext struct {
// PolicySets represent the policies that are run on the plan as part of the
// policy check stage
PolicySets valid.PolicySets
// DeleteSourceBranchOnMerge will attempt to allow a branch to be deleted when merged (AzureDevOps & GitLab Support Only)
DeleteSourceBranchOnMerge bool
}

// GetShowResultFileName returns the filename (not the path) to store the tf show result
Expand Down
13 changes: 10 additions & 3 deletions server/events/project_command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ const (
DefaultParallelApplyEnabled = false
// DefaultParallelPlanEnabled is the default for the parallel plan setting.
DefaultParallelPlanEnabled = false
// DefaultDeleteSourceBranchOnMerge being false is the default setting whether or not to remove a source branch on merge
DefaultDeleteSourceBranchOnMerge = false
)

func NewProjectCommandBuilder(
Expand Down Expand Up @@ -235,6 +237,7 @@ func (p *DefaultProjectCommandBuilder) buildPlanAllCommands(ctx *CommandContext,
commentFlags,
repoDir,
repoCfg.Automerge,
mergedCfg.DeleteSourceBranchOnMerge,
repoCfg.ParallelApply,
repoCfg.ParallelPlan,
verbose,
Expand All @@ -261,6 +264,7 @@ func (p *DefaultProjectCommandBuilder) buildPlanAllCommands(ctx *CommandContext,
commentFlags,
repoDir,
DefaultAutomergeEnabled,
pCfg.DeleteSourceBranchOnMerge,
DefaultParallelApplyEnabled,
DefaultParallelPlanEnabled,
verbose,
Expand Down Expand Up @@ -451,10 +455,12 @@ func (p *DefaultProjectCommandBuilder) buildProjectCommandCtx(ctx *CommandContex
var projCtxs []models.ProjectCommandContext
var projCfg valid.MergedProjectCfg
automerge := DefaultAutomergeEnabled
deleteBranchOnMerge := DefaultDeleteSourceBranchOnMerge
parallelApply := DefaultParallelApplyEnabled
parallelPlan := DefaultParallelPlanEnabled
if repoCfgPtr != nil {
automerge = repoCfgPtr.Automerge
deleteBranchOnMerge = projCfg.DeleteSourceBranchOnMerge
parallelApply = repoCfgPtr.ParallelApply
parallelPlan = repoCfgPtr.ParallelPlan
}
Expand All @@ -477,8 +483,9 @@ func (p *DefaultProjectCommandBuilder) buildProjectCommandCtx(ctx *CommandContex
commentFlags,
repoDir,
automerge,
parallelApply,
deleteBranchOnMerge,
parallelPlan,
parallelApply,
verbose,
)...)
}
Expand All @@ -492,8 +499,9 @@ func (p *DefaultProjectCommandBuilder) buildProjectCommandCtx(ctx *CommandContex
commentFlags,
repoDir,
automerge,
parallelApply,
deleteBranchOnMerge,
parallelPlan,
parallelApply,
verbose,
)...)
}
Expand All @@ -503,7 +511,6 @@ func (p *DefaultProjectCommandBuilder) buildProjectCommandCtx(ctx *CommandContex
}

return projCtxs, nil

}

// validateWorkspaceAllowed returns an error if repoCfg defines projects in
Expand Down
Loading

0 comments on commit 632460b

Please sign in to comment.