Repository: runatlantis/atlantis (language: go)

Issue:
Feature request: allow apply on merge
<!--- Please keep this note for the community --->

### Community Note

* Please vote on this issue by adding a 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to the original issue to help the community and maintainers prioritize this request. Searching for pre-existing feature requests helps us consolidate datapoints for identical requirements into a single place, thank you!
* Please do not leave "+1" or other comments that do not add relevant new information or questions, they generate extra noise for issue followers and do not help prioritize the request.
* If you are interested in working on this issue or have submitted a pull request, please leave a comment.

<!--- Thank you for keeping this note for the community --->

---

<!--- When filing a bug, please include the following headings if possible. Any example text in this template can be deleted. --->

### Overview of the Issue

<!--- Please describe the issue you are having and how you encountered the problem. --->

Currently when a PR is merged without `atlantis apply` we end up in a situation where reality doesn't match desired state described with terraform. There is also no way to apply changes post-merge without raising a dummy PR.

At the same time, in GitHub, it's sometimes not possible to prevent people form merging PRs. For example anyone with repo admin access will get implicit push access and thus will be able to merge approved PRs without having to apply first.

In practice this means that there is currently no way to prevent human errors (people merging approved PRs without running `atlantis apply` first).

I'd like to propose optional functionality to allow atlantis to be configured to apply changes on PR merges. This would allow organizations who cannot remove push or admin access from repos to ensure changes are applied on merges without relying on humans to remember to `atlantis apply`

I realize that there is a possibility that apply fails and we'll end up being out of sync but this is a trade off that some organizations might be willing to accept.

### Reproduction Steps

<!--- 

In order to effectively and quickly resolve the issue, please provide exact steps that allow us the reproduce the problem. If no steps are provided, then it will likely take longer to get the issue resolved.
  
--->

Open a PR and then merge it without running `atlantis apply` first. This will result in code being out of sync with reality and there is no way to retroactively apply changes.
The only workaround I found is to open 2nd dummy PR and ensure it's applied before merging.

### Logs

<!---

Provide log files from Atlantis server

<details>
  <summary>Logs</summary>

```
log output
```

</details>

--->

### Environment details

I'm on atlantis v 0.18.2 but I believe older/newer versions will also be affected by this.
<!---

If not already included, please provide the following:
- Atlantis version:
- If not running the latest Atlantis version have you tried to reproduce this issue on the latest version: 
- Atlantis flags:

Atlantis server-side config file:
```
# config file
```

Repo `atlantis.yaml` file:
```
# config file
```

Any other information you can provide about the environment/deployment.
--->


### Additional Context

<!---
Additional context on the problem. Docs, links to blogs, or other material that lead you to discover this issue or were helpful in troubleshooting the issue. 
--->

This feature was requested in 2017 but wasn't implemented back then: https://github.com/runatlantis/atlantis/issues/36

There is also discussion about the mergable limitations here: https://github.com/runatlantis/atlantis/issues/1316

Apply on merge would allow us to create workflow similar to that hashicorp describe in a [docs](https://learn.hashicorp.com/tutorials/terraform/github-actions#review-and-merge-pull-request). This makes me think that the functionality is non-controversial as hashicorp themselves describe it.


Discussion / hints:
will setting `atlantis/apply` as a required check in branch protection rules help in that case? 
note: might be only available on latest version
![image](https://user-images.githubusercontent.com/16245796/161944738-09ecd57c-0824-484d-82a2-b79a1719d773.png)



> will setting `atlantis/apply` as a required check in branch protection rules help in that case? note: might be only available on latest version ![image](https://user-images.githubusercontent.com/16245796/161944738-09ecd57c-0824-484d-82a2-b79a1719d773.png)

No it won't work. For atlantis to respect GitHub branch protection rules we need to use `mergable` apply requirement. If we set up branch protection rule to require successful `atlantis/apply` then the PR will not become `mergable` until we apply and we can't apply until it's mergable...


Hey all,
To add this feature can we do something like this (Please correct me if I am wrong)? :
- Add a support for a flag `apply-on-merge` in the atlantis server with which users can specify if they want to enable apply post merge. Add `pull_request_event` type as merged to `PullRequestEventType` in `server/events/models/models.go`. Refer go-github API [code](https://github.com/google/go-github/blob/master/github/event_types.go#L758-L765)
- Add condition to allow atlantis to apply when there's flag `apply-on-merge` is set to `true` and PR is merged.
- If flag `apply-on-merge` is set to true, bypass the rule for checking the PR state `ctx.Pull.State != models.OpenPullState ` in the `server/events/command_runner.go`.
- Make sure that post run hooks (`server/events/post_workflow_hooks_command_runner.go`) uses flag `apply-on-merge`  to decide not to merge the PR (since its already merged) and continue with removing the atlantis locks.
- If state of the PR is open and if `atlantis apply`  comment event occurs, check the flag `apply-on-merge` and then reject the apply since flag `apply-on-merge` flag is set.
- If user comments `atlantis apply`  on the closed PR, return as usual.

There can  be an alternate atlantis requirement for `apply-on-merge` flag. So that users can specify that via config file.
Does this make sense? What else can we improve in this to achieve `apply` post merge? 

Thanks.
Would one of the maintainers be able to access above plan form @satyamz ? We're considering contributing to the project by adding this functionality but would like to know if the plan looks sound and whether a PR would be accepted.
I'm interested in this due to the [GitLab API bug](https://gitlab.com/gitlab-org/gitlab/-/issues/187440) mentioned in #1174 that is preventing Atlantis' `mergeable` apply requirement from functioning. Having apply-on-merge would let us make sure all the MR approvals are adhered to before the plan can be applied.
I'd like to take this issue one step further:

automatically plan on any change to the PR - failing on other parallel PRs is okay - but maybe make that optional for obvious reasons:

do NOT respond to `atlantis apply` manual commands on *unmerged* files

and finally, apply on merge 

this relies on the plan being okay and the git provider approvals/results on the PR being acceptable and merge possible - so no smarts needed there, just dump plan output on every push and do apply and dump output on merge. 

This tool is *almost* perfect on the face of it but the above work flow is the only one  that makes sense to me for any serious use. 
> I'd like to take this issue one step further:
> 
> automatically plan on any change to the PR - failing on other parallel PRs is okay - but maybe make that optional for obvious reasons:

I believe plans are regenerated on PR changes already, there is no need to `atlantis plan` when new commits are added.

> do NOT respond to `atlantis apply` manual commands on _unmerged_ files

Yes absolutely, it's a good point that in this scenario `atlantis apply` should not do anything.

> and finally, apply on merge
> 
> this relies on the plan being okay and the git provider approvals/results on the PR being acceptable and merge possible - so no smarts needed there, just dump plan output on every push and do apply and dump output on merge.

Yes exactly, this is exactly the workflow I'd like to use as well!

> This tool is _almost_ perfect on the face of it but the above work flow is the only one that makes sense to me for any serious use.

It's good to see that there are more people who have the same requirements!
We would love something along these lines as  feature, as this is something that happens on a regular basis with engineers new to our team, or for engineers from outside our organisation. 

The ability to require the `atlantis/apply` check to pass for users to merge, and for atlantis to consider a PR mergeable if all required checks _except for that check_ pass, would likely be enough for us.
we would love to see this feature implemented for our team as well, many people forgot to comment `atlantis apply` and straight merged the PR. And we can't set the `atlantis/apply` status check due to the conflict with `mergeable`
Speaking as an interested observer, I'm curious if there's something about Atlantis' design that requires it to only run during the PR phase. I ask because I recently came across a [notice](https://www.runatlantis.io/docs/locking.html#why) that said a failure occurring post-merge "would need" to be fixed by a subsequent PR. Is this really mandatory?

If I have a GitHub Action that fails post-merge, I have the option to just re-run it. Granted, if the fault is something within the repository that should never have been merged I'll most likely fix it in a new PR. But if the issue lies outside the repo, if it's something like an expired token or an intermittent network outage, I just need a button.

Is there something fundamental to Atlantis that prevents this sort of capability?
is this still an issue with `v0.19.8`?
> is this still an issue with `v0.19.8`?

As far as I can tell yes this is still a problem.
The tricky part about "apply on merge" functionality is that it's mostly GitHub limitation that we are dealing with. It is currently not possible to confirm whether GitHub merge requirements were met without actually allowing people to merge. And once people merge we have a drift between code and actual state.

Fix patch:
diff --git a/runatlantis.io/docs/apply-requirements.md b/runatlantis.io/docs/apply-requirements.md
index 27628fd5e9..d4dcddaf6b 100644
--- a/runatlantis.io/docs/apply-requirements.md
+++ b/runatlantis.io/docs/apply-requirements.md
@@ -115,7 +115,7 @@ a pull request mergeable.
 :::
 
 ::: warning
-If you set `atlantis/apply` to the mergeable requirement, use the `--gh-allow-mergeable-bypass-apply` flag or set the `ATLANTIS_GH_MERGEABLE_BYPASS_APPLY=true` environment variable. This flag and environment variable allow the mergeable check before executing `atlantis apply` to skip checking the status of `atlantis/apply`.
+If you set `atlantis/apply` to the mergeable requirement, use the `--gh-allow-mergeable-bypass-apply` flag or set the `ATLANTIS_GH_ALLOW_MERGEABLE_BYPASS_APPLY=true` environment variable. This flag and environment variable allow the mergeable check before executing `atlantis apply` to skip checking the status of `atlantis/apply`.
 :::
 
 #### GitLab


Test patch: