Shopify is a large-scale eCommerce platform that makes heavy use of code commits and merges to keep its operation running smoothly. On a typical day, Shopify will make around 40 code changes and merge 400 commits into its master codebase. This level of activity would be unmanageable for most companies, but Shopify and most tech giants like Uber and AWS have put in place several systems and processes to help them manage and collaborate on such a large scale.
One such way is using Merge Queues. Merge Queue allows developers to manage and collaborate on code changes on a large scale.
Merge Queues are a crucial part of how most tech companies are able to manage and collaborate on code at such a large scale. Merge Queues allow developers to work together on code changes without worrying about breaking the production, merge conflicts, or to wait for PR to be merged.
Engineering teams are tasked with developing new features across multiple branches to keep many different products in step. This means that there is a lot of merging to do. When many engineers are working concurrently, there are likely to be many branches and PRs; merging these branches can lead to various conflicts and even break the application or production environment.
Most companies use CI to prevent such issues. But even with CI in place, if you don't manage your PRs correctly, you may break the prod. But how? Let me explain this with an example.
You asked your team of developers to add X features to the application. They started working on it based on what you assigned them by creating their feature branch. One of the developers completed the task and created the PR, and CI checks also ran successfully. Meanwhile, the other developer also changed one of the files affecting the first PR and created his PR (CI ran successfully again🟢).
The senior developer started looking at both the PRs and thought of merging as CI passed, and everything was good. The senior dev merged the second PR first, which changed in the file affecting the other PR. As the CI was already 🟢, he merged the other one too. You know what happened next.
The solution to this problem is Merge Queues that automate this tedious task for you by ensuring that before merging, the PRs are up-to-date with their respective base branches. And if you have a CI process, it will pick up these PRs again and rerun the jobs on the new code.
So, GitHub must be offering this. Not quite ❌. GitHub provides a built-in merge queues feature; however, as per their official documentation, it is currently in limited public beta and thus not generally available to all. On the other hand, GitLab calls this feature Merge Trains and is available only for premium users.
If you use GitHub and have been reviewing PRs even for a while now, you know that there are certain kinds of PRs that you don't even need to thoroughly review based on whatever factors like saying a PR is good to be merged if the PR:
- just adds files and does not modify or delete any of the existing files
- modifies just the README.md file
- is approved by a senior developer 🧑💻
This is where Mergify comes in 🚀. Mergify enables you to do that and a lot more. It's a SaaS integration that connects with GitHub repositories to automate and assist with prioritizing, queuing, and merging PRs.
Here are some more use cases for you that can be achieved with Mergify apart from condition-based automated merging:
- Rebase the source branch of PRs
- Label and assign to fellow team members
- Delete the head branches upon PR merge
Although there are various options in the market for merge queues like MergeQueue, Mergify stands out as not just a merge queue offering but also as a process automation solution.
Some of the benefits of using Mergify over MergeQueue and other similar alternatives include:
- Offers time-saving features such as speculative checks and batch pull requests that positively affect the merge time.
- Offers the ability to set up multiple queues in which you can sort, order, and prioritize your PRs based on condition checks and how your processes work.
- Offers not just safe code merging capability but a complete automated approach towards dealing with multiple collaborators for your codebase.
- Offers community support and dedicated customer success manager on paid plans where you also get premium features such as priority queues, random request reviews, private deployments, and much more.
Now when we have a fair understanding of what Mergify is and how it can help us, let's dive into how you can get started with Mergify.
- Have yourself signed into your GitHub account.
- Have a public repository ready to be connected with Mergify. (private repositories are supported in paid plans)
- Head to Mergify SignUp and sign in via GitHub, and you can choose to let Mergify connect to all your repositories or select a few, similar to how GitHub apps work.
Now when you're all signed up and Mergify connected to your GitHub repository, let's walk through a couple of examples to see how Mergify can solve our problems.
Mergify's configs have a pretty simple structure. It has a list of conditions that, when become true with respect to any of our PRs, the mentioned actions shall take place.
We can define multiple pull request rules that Mergify will check our PRs against but for the sake of simplicity of this article, let's stick to the simple ones that will help a larger audience get started with Mergify.
To set up a config, you need a file
.mergify.yml in the root of your directory that will tell Mergify what to do with the PRs. What we'll have in the config editor when we open it up for the first time will be a very basic initial configuration that the Mergify config editor loads up by default once a repository is connected.
What's nice about Mergify is that you can create a PR from the Mergify Dashboard itself that'll create a .mergify.yml file for you in your repo. Even if you feel it's too soon and you need to test it before committing stuff, then there's a test option available within the config editor where you can test your config against a particular PR to test out the config. It also acts as a validation of your config schema.
Let's go through the same initial config where we've added just another condition.
pull_request_rules: - name: Automatic merge on approval conditions: - "#approved-reviews-by>=1" - "author=theinfosecguy-example" actions: merge: method: merge
Given the minimal config, translating this into simpler terms means that whenever a PR has either 1 or more approvals just go ahead and merge the PR.
In a PR in our example repo, as shown below, the PR was authored by
@theinfosecguy-example and the moment the PR got approved by a collaborator, the Mergify bot went ahead and merged the PR as post the approval this PR matched all the conditions mentioned in our pull request rules in the config, as mentioned above.
You can refer to Conditions — Mergify documentation to get a hold of all the conditions Mergify can work with which you can further combine as per your teams’ needs.
Mergify will take care of your simple checks freeing a large chunk of your time to focus on the more challenging PRs where merge conflicts arise and PRs with outdated base branches require your input.
Here’s another example where we have multiple PRs that desire to update a single file meaning that the base branch of the second PR will be outdated once the first PR is merged but Mergify is here to save the day.
Firstly we have defined a queue, you can define multiple as per your requirement, and then we have to define pull request rules. Here’s the config for your reference.
queue_rules: - name: default conditions:  pull_request_rules: - name: merge using the merge queue conditions: - "#files=1" - "author=theinfosecguy-example" actions: queue: name: default
In this particular config, we have set up a queue named "default" and the conditions say that if the PR modifies one single file and is authored by a specific user, then send the PR to the "default" merge queue to be further merged.
Let's take another example to understand better the automated PR management in a team of multiple collaborators where say; you have a senior Python developer and a DevOps team to be looped in regarding security-related tasks.
queue_rules: - name: default conditions:  pull_request_rules: - name: assign PRs with Python files modified to theinfosecguy-example conditions: - files~=\.py$ - -closed actions: assign: add_users: - theinfosecguy-example - name: ask the security team to review security labeled PR conditions: - label=security actions: request_reviews: teams: - "@myorg/devops"
This above-mentioned config has two rules, the first one will look for open PRs that modify any files with
.py extension and assign the PR to
theinfosecguy-example whereas the second rule states that if a PR is labeled as “security” then request reviews from the “devops” team from your GitHub organization which you’d anyway do if even if not automated.
Having a look at their documentation, Mergify can cater to many use cases with its powerful condition-based automation configurations.
All merge queues do is avoid merging outdated PRs to prevent merging broken pull requests and extend that functionality. Mergify also automates DevOps operations, prioritization, queuing, and condition-based automatic merges. You can have multiple queues, multiple condition checks, more advanced checks with logical and grouping, and whatnot.
Although Mergify requires a paid subscription to set up multiple queues and connect to private repositories, it is free and offers basic open-source project features. They also have a 14-day free trial on their paid plans if you want to check out the premium features.
Check out Mergify!