I'd like to automatically (i.e. from Jenkins) merge a GitHub pull request that has been approved by a person and has been tested successfully; in other words, when all THREE of these checkmarks are green:
Is this possible? I haven't found any documentation on an API for GitHub's new "changes approved" code review functionality.
There is a new PullRequestReviewEvent webhook that is triggered when a review is submitted in a non-pending state. The body of the webhook contains the ["review"]["state"] field, which will be approved when all reviewers have approved the changes (i.e. when you get the green "changes approved" tick in the UI).
Combine this with the StatusEvent for the head SHA of your pull request to get the status checks from CI and so on, then finally check the "merge-ability" of the pull by requesting the pull request from the API:
GET /repos/:owner/:repo/pulls/:number
Once you have all three things, you can merge the pull request with:
PUT /repos/:owner/:repo/pulls/:number/merge
and appropriate payload parameters. Note you'll need the Accept: application/vnd.github.polaris-preview+json for some of the payload parameters as they are in a preview period.
Official documentation: "Managing auto-merge for pull requests in your repository".
That is now (Dec. 2020, 4 years later) available:
Pull request auto-merge public beta
Pull request auto-merge is now rolling out as a public beta!
With auto-merge, pull requests can be automatically merged when all requirements for merging are met. No more waiting for long checks to finish just so you can press the merge button!
To use auto-merge, a repository maintainer or admin must first toggle on the repository setting to allow auto-merge (see steps).
Then any user with write permission can enable or disable auto-merge by navigating to the pull request page.
Keep in mind that auto-merge is only available for pull requests targeting a branch with required reviews or required status checks, and therefore is only available on public repositories and private repositories on Team and GitHub Enterprise Cloud plans.
Learn more about pull request auto-merge.
Update Feb. 2021:
Pull request auto-merge is now generally available
With auto-merge, pull requests can be set to merge automatically when all merge requirements are met.
No more waiting on slow CI jobs or tests to finish just so you can click the merge button!
To use auto-merge, first have an administrator allow auto-merge in the repository settings.
Then to enable auto-merge, navigate to the pull request on GitHub.com or GitHub Mobile and tap the button to enable.
Note that auto-merge can only be enabled by users with permission to merge and when there are unsatisfied merge requirements, like missing approvals or failing required status checks.
GraphQL APIs will be rolling out later this week. The pull request webhook event also now includes actions that indicate when auto-merge is enabled or disabled.
Learn more about pull request auto-merge
However, as The Godfather mentions in the comments:
The problem with this is that it doesn't do auto-update.
So as soon as your repo has "branches must be up-to-date" and some other PR got merged, this "auto-merge" doesn't work any more.
It should have been called the same way as Gitlab: "merge when pipeline succeeds", at least it's not as confusing... –
Update Aug. 2021:
Maintainers can now manage the availability of auto-merge in a repository
Maintainers can now manage the repository-level "Allow auto-merge" setting.
This setting, which is off by default, controls whether auto-merge is available on pull requests in the repository.
Previously, only admins could manage this setting.
Additionally, this setting can now by controlled using the "Create a repository" and "Update a repository" REST APIs.
I wrote an app that does this. It responds to the review, labelled, and commit status/checks events, and merges when the merge button is green.
The fact that it merges when the merge button is green means that you can configure the requirements for a mergeable PR in the GitHub settings, there's no need to write separate configuration for the app.
Mergery is:
Free, including for private repositories.
Fast. It's event-driven, it doesn't run on a schedule.
Simple. No configuration required. Just label your PRs with automerge.
You can use Mergify to do exactly this, since this is what it has been created for. Just set up a minimal .mergify.yml file in your repository:
rules:
default:
protection:
required_status_checks:
context:
- continuous-integration/travis/pr
required_pull_request_reviews:
required_approving_review_count: 1
And you'll be good to go.
(disclaimer: I'm one of the Mergify founders)
Using github actions which is one of the new ways, this can be done. I have written a blog about auto approving and auto merging PRs using github actions. However, if the intent is to just merge the PRs only, then then the second job in this work flow would be enough to do it.
https://github.com/bobvanderlinden/probot-auto-merge is a free GitHub app that does the job. It's configurable in .github/auto-merge.yml.
Related
Upon reviewing the branch protection settings for a GitHub repo, and reading the documentation for all of the settings, I still can't quite figure out the difference between enabling these two groups of settings:
According to the documentation, if I require approvals, it means an approval is required from someone else (I cannot approve my own PR):
If you enable required reviews, collaborators can only push changes to a protected branch via a pull request that is approved by the required number of reviewers with write permissions.
The next option seems self explanatory, but here is what the documentation has to say about it:
Optionally, you can choose to dismiss stale pull request approvals when commits are pushed. If anyone pushes a commit that modifies code to an approved pull request, the approval will be dismissed, and the pull request cannot be merged. This doesn't apply if the collaborator pushes commits that don't modify code, like merging the base branch into the pull request's branch.
However, when I look at the documentation for the branch protection setting to "require approval of the most recent push", it sounds like it does the same thing as if I had the first two enabled:
Optionally, you can require approvals from someone other than the last person to push to a branch before a pull request can be merged. This ensures more than one person sees pull requests in their final state before they are merged into a protected branch. If you enable this feature, the most recent user to push their changes will need an approval regardless of the required approvals branch protection. Users who have already reviewed a pull request can reapprove after the most recent push to meet this requirement.
It sounds like this option implies that an approval will be dismissed if a new commit is pushed to the branch for the open PR. If that's the case, then isn't enabling the first to the same as enabling the last one?
The "require approval of the most recent push" protection rule was recently introduced (oct 2022), with the express purpose to prevent someone responding to a code review request from sneaking in changes and approving them themselves or using the already supplied approval from another reviewer.
The security research that explores these topics has not been broadly published, but there are some great discussions with recommendations on how to secure your branches.
With this new policy enabled, when a reviewer applies some suggestions to the code, they can't approve and merge the code without finding another person to review their changes.
Excerpts from the article, red team, emphasis mine:
— Modify code after review
After the attacker submits a valid and good code change that is approved, the attacker abuses their existing approval to make further changes that include bad code while retaining the stale approval.
Another scenario is that the attacker could first be a good samaritan and approve the code of a fellow developer, let’s assume it’s a good code change, but it doesn’t matter. What matters is that once they have approved that pull request, they could abuse their own write access, add bad code and self-approve their own code change.
And the protections, blue team, emphasis mine:
Require a pull request before merging
Require approvals
Dismiss stale pull request approvals when new commits are pushed
Require review from Code Owners
Allow specified actors to bypass required pull requests (avoid unless you absolutely need to)
Require approval of the most recent push (this is a new setting, as of October 2022, and is really great mitigation for some of our attack scenarios)
Require status checks to pass before merging (it you have some form of CI with tests, linters, SAST, it would be great to enforce those)
Require signed commits (this is great for end-to-end accountability)
Enforce Branch Protection for administrator (i.e. “Do not allow bypassing the above settings”)
Recommended mitigations, emphasis mine:
— Modify code after review
Attacker submits good code, gets approval, then submits bad code
The mitigation is to set your Branch Protection to “Dismiss stale pull request approvals when new commits are pushed”.
Attacker approves someone else’s good code, then submits bad code and self-approves changes
The mitigation is to set your Branch Protection to “Require approval of the most recent push”.
I would like to ask for your help with steps to resolve a seemingly simple issue in regards with branch policies. We have the following requirement: Mandate at least 1 Pull-Request approval from a team member other than the code author. However, once the reviewer has added some comments for minor code changes to be made, and approved the PR, then for the next iteration on this PR we would like to retain the reviewer's previous approval vote so that the code author can complete the PR without waiting for any additional approvals for their latest code changes. We understand that if there are more critical code changes suggested by the reviewer, then they can simply vote to wait or reject the PR.
Could you please help provide steps to achieve this scenario to retain reviewer's approval votes over successive code iteration/s? Thanks.
Assuming you are using Github, do the following
Go to your repository
Click on the settings tab
Click on branches on the left
Edit the branch protection rules
Under "Require a pull request before merging" uncheck the box that says "Dismiss stale pull request approvals when new commits are pushed"
Edit: my bad, completely overlooked the azure devops tag. See if the following works for you
Under Branch Policies, set Require a minimum number of reviewers on, and uncheck the box that says when new changes are pushed.
Found documentation here.
I'm trying to find a way to stop users who have worked on a branch (who have committed changes on a branch) form being able to approve in a pull request on that branch. The idea that a dev can't approve their own work.
I haven't been able to find anything in the devops documentation and was hoping someone might have found a way that I've missed.
Anyone come across a solution?
Out of the box, you can prevent the creator of the pull request and the most recent pusher from approving their own changes, but you can't prevent every user who's committed to the branch from approving their changes. You likely won't want to prevent every developer who's committed to a branch from approving, because eventually, that will be nearly the entire development team.
You'll want to head to Project Settings > Repositories > Policies and update your branch policy to adjust the following settings:
Unchecked: Allow requestors to approve their own changes
Checked: Prohibit the most recent pusher from approving their own changes
Here's Microsoft's documentation on how to enable approval restrictions:
https://learn.microsoft.com/en-us/azure/devops/repos/git/branch-policies?view=azure-devops#require-a-minimum-number-of-reviewers
The feature Prohibit the most recent pusher from approving their own changes just prohibit the pull request creator from approving their own changes.
For example, user A create branch and push commit, then user B create the pull request.
The user B can vote Approve but the vote will not count toward the Minimum number of reviewers. And user A vote approve the pull request and the vote will count toward the Minimum number of reviewers
Prevent a user approving request if they have worked on the branch
You could add your request for this feature on our UserVoice site, which is our main forum for product suggestions. Thank you for helping us build a better Azure DevOps.
In addition, as a workaround, we could configure the branch policy and enable the feature Automatically included reviewers-> add admin as request reviewer and set the option Policy requirement to Required. Then after the administrator checks and approves the pull request, then developers can complete the pull request.
Also, If there are fewer developers, we can let each developer create his own branch, they can only work on their own branch and create pull request for their own branch, then enable the branch policy Prohibit the most recent pusher from approving their own changes to do this.
My organization requires approved pull requests. We currently have two active development branches that have essentially, but not literally, the same code. I'll refer to them as DevA and DevB. I built a feature (Feature) off of DevA, merged DevA into Feature, and then pushed Feature. On GitHub, I created two pull requests. The first was merging Feature into DevA, and the second was merging Feature into DevB. To my surprise, following an approval on Feature->DevA, I was able to merge Feature->DevB, despite not getting approval for that PR. I merged Feature->DevA, which removed the ability to merge Feature->DevB until I received a second approval. Why did this happen?
My theory is because Feature was the same for both PRs, the approval allowed my to execute any pull request where Feature is the branch getting merged in. After the first pull request completed, there was no longer an active approval for Feature, which required a second approval for Feature->DevB.
Generally, a Github branch goes to "Approved" state when at least one person approves the changes. But sometimes a branch may be needed to be reviewed by more than one person and it could only be merged when everybody approves.
Is there a way to override default behavior of Github to setup a branch not to go to "Approved" state until all reviewers have approved the changes? Basically I don't want the branch to show up in green until then.
GitHub has the ability to require multiple reviewers.
GitHub does not currently support this functionality.