queue๐Ÿ”—

The queue action moves the pull request into one of the merge queue defined in Queue Rules.

Merge queues prevent merging broken pull requests by serializing their merge. Merging broken pull requests can happen when outdated pull requests are being merged in their base branch.

Mergify always respects the branch protection settings. When the conditions match and the queue action runs, Mergify waits for the branch protection to be validated before embarking and merging the pull request.

Mergify also waits for dependent pull requests to get merged first (see โ›“๏ธ Defining Pull Request Dependencies).

Why Queues?๐Ÿ”—

To understand the problem queues resolve, imagine the following situation:

  • The base branch (e.g., main) has its continuous integration testing passing correctly.

  • A pull request is created, which also passes the CI.

The state of the repository can be represented like this:

Pull request is open

While the pull request is open, another commit is pushed to main โ€” let's call it new commit. That new commit can be pushed directly to main or merged from another pull request; it doesn't matter.

The tests are run against the main branch by the CI, and they pass. The state of the repository and its continuous integration system can be now described like this:

Base branch adds a new commit

The pull request is still marked as valid by the continuous integration system since it did not change. As there is no code conflict, the pull request is considered as mergeable by GitHub: the merge button is green.

If you click that merge button, this is what might happen:

Base branch is broken

As a new merge commit is created to merge the pull request, it is possible that the continuous integration testing fails. Indeed, the continuous integration did not test the pull request with the new commit added to the base branch. This new commit might have introduced some new tests in the base branch while the pull request was open. That pull request may not have the correct code to pass this new test.

Using Queues๐Ÿ”—

Using a merge queue solves that issue by updating any pull request that is not up-to-date with its base branch before being merged. That forces the continuous integration system to retest the pull request with the new code from its base branch.

If a merge queue were being used in the previous example, Mergify would automatically merge the main in the base branch. The continuous integration system would have rerun and marked the pull request as failing the test, removing it from the merge queue altogether.

Rebase make CI fails

When multiple pull requests are mergeable, they are scheduled to be merged sequentially, and are updated on top of each other. The pull request branch update is only done when the pull request is ready to be merged by the engine, e.g., when all the conditions are validated.

That means that when a first pull request has been merged, and the second one is outdated like this:

strict merge with PR2 open

Mergify will make sure the pull request #2 is updated with the latest tip of the base branch before merging:

strict merge

That way, there's no way to merge a broken pull request into the base branch.

Configuring the Merge Queues๐Ÿ”—

The merge queues rely on two configuration items: the queues_rules and the queue action.

The queue action places the pull request inside the merge queue: the set of conditions described in the pull_request_rules allows the pull request to enter the queue when all conditions match.

If the queue action conditions do not match anymore, the pull request is removed from the merge queue.

When a pull request is at the top of the queue, Mergify looks at the second set of conditions defined this time in queue_rules and wait that they all match to merge the pull request.

When multiple queues are defined, they are processed one after the other in the order they are defined in the queue_rules list. Queue processing is blocked until all preceding queues are empty.

Viewing the Merge Queue๐Ÿ”—

The merge queue can be visualized from your dashboard:

The merge queue from the dashboard

Speculative Checks๐Ÿ”—

Merging pull requests one by one serially can take a lot of time, depending on the continuous integration run time. To merge pull requests faster, Mergify queues support speculative checks.

With speculative checks, the first pull requests from the queue are embarked in a merge train and tested together in parallel so they can be merged faster. A merge train consists of two or more pull requests embarked together to be tested speculatively. To test them, Mergify creates temporary pull requests where multiple queued pull requests are merged together.

The upside of creating multiple temporary pull requests is that continuous integration pipelines can run on all of them in parallel. Currently, Mergify embarks up from 1 to 20 pull requests into the merge train (you can set the value with the speculative_checks settings in queue_rules).

Merge train

A merge queue with 5 pull requests and speculative_checks set to 3๐Ÿ”—

In the above example, three pull requests are tested at the same time by the continuous integration system: PR #1, PR #1 + PR #2 and PR #1 + PR #2 + PR#3. By creating temporary pull requests that combine multiple pull requests, Mergify is able to schedule in advance the testing of the combined results of every pull request in the queue.

Those temporary pull requests check if the resulting branch can be merged according to the queue_rules conditions. If any of the merge car fails to match the queue_rules conditions, the culprit pull request is removed from the queue.

When the pull request PR #1 + PR #2 matches the queue_rules conditions, the pull requests PR #1 and PR #2 are merged and the temporary pull request PR #1 + PR #2 is deleted. The same goes for the pull request PR #1 + PR #2 + PR #3 and PR #3.

In the case where a new commit is pushed on the base branch, Mergify resets the merge train and starts over the process.

If an embarked pull request doesn't match the queue_rules anymore, it is removed from the merge train. All pull requests embarked after it are disembarked and re-embarked.

Warning

With speculative checks, pull requests are tested against the base branch within another temporary pull request. This requires the branch protection settings Require branches to be up to date before merging to be disabled. If you require a linear history, just set the queue option merge: rebase.

Batch Size๐Ÿ”—

Mergify allows checking the mergeability of multiple pull requests at once using the batch_size option. If set to 3, Mergify will create a draft pull request with the latest version of the base branch and merge the commits of the 3 next queued pull requests.

If the CI validates the draft pull request, Mergify will merge the 3 queued pull requests and close the draft one. If the CI reports a failure, Mergify uses a binary search to build a smaller batch of pull requests to check in order to find the culprit. Once the failing pull request is found, Mergify removes it from the queue. The rest of the queue is processed as usual.

batch_size and speculative_checks can be combined to increase the merge queue throughput.

For example, if your queue is 15 pull requests long and you have speculative_checks set to 3 and batch_size to 5, you'll have 3 draft pull requests of 5 pull requests each being tested at the same time. If your CI time is 10 min, you can merge those 15 pull requests in only 10 minutes.

Options๐Ÿ”—

Queue Action๐Ÿ”—

These are the options of the queue action:

Key Name

Value Type

Default

Value Description

name

string

The name of the merge queue where to move the pull request.

method

string

merge

Merge method to use. Possible values are merge, squash or rebase.

rebase_fallback

string

merge

If method is set to rebase, but the pull request cannot be rebased, the method defined in rebase_fallback will be used instead. Possible values are merge, squash, none. none will report an error if rebase is not possible.

merge_bot_account

Template

Mergify can impersonate a GitHub user to merge pull request. If no merge_bot_account is set, Mergify will merge the pull request itself. The user account must have already been logged in Mergify dashboard once and have write or maintain permission.

update_method

string

merge

Method to use to update the pull request with its base branch when the speculative check is done in-place. Possible values:

  • merge to merge the base branch into the pull request.

  • rebase to rebase the pull request against its base branch.

Note that the rebase method has some drawbacks, see Using Rebase to Update.

update_bot_account

Template

For certain actions, such as rebasing branches, Mergify has to impersonate a GitHub user. You can specify the account to use with this option. If no update_bot_account is set, Mergify picks randomly one of the organization users instead. The user account must have already been logged in Mergify dashboard once.

priority

1 <= integer <= 10000 or low or medium or high

medium

This sets the priority of the pull request in the queue. The pull request with the highest priority is merged first. low, medium, high are aliases for 1000, 2000, 3000.

commit_message

string

default

Deprecated ๐Ÿ˜ต
Defines what commit message to use when merging using the squash or merge method. Possible values are:

  • default to use the default commit message provided by GitHub or defined in commit_message_template or defined in the pull request body (see Defining the Commit Message).

  • title+body means to use the title and body from the pull request itself as the commit message. The pull request number will be added to end of the title.

commit_message_template

Template

Template to use as the commit message when using the merge or squash merge method and commit_message is set to default.

require_branch_protection

bool

true

Whether branch protections are required for queueing pull requests. This option is ignored if the target queue has speculative_checks > 1.

Queue Rules๐Ÿ”—

A queue_rules takes the following parameter:

Key Name

Value Type

Default

Value Description

name

string

The name of the merge queue.

conditions

list of ๐ŸŽฏ Conditions

The list of conditions to match to get the queued pull request merged, In case of speculative merge pull request, the conditions starting by check- are evaluated against the temporary pull request instead of the original one.

speculative_checks

int

1

The maximum number of checks to run in parallel in the queue. Must be between 1 and 20. See Speculative Checks.

allow_inplace_speculative_checks

bool

True

Allow to update/rebase the original pull request if possible to check its mergeability. If False, a draft pull request is always created.

batch_size

int

1

The maximum number of pull requests per speculative check in the queue. Must be between 1 and 20. See Speculative Checks.

Note

Defining multiple queue rules is only available for Premium subscribers.

Examples๐Ÿ”—

๐Ÿ› Single Queue๐Ÿ”—

A simple usage of the queue is to merge pull requests serially, ensuring they all pass the CI one after the other. The following example defines a queue named default which allows any pull request to be merged once it enters it.

To enter the queue, pull requests need to be based on the main branch, have 2 approving reviews and pass the CI. Once a pull request is in first position in the queue, it will be updated with the latest commit of its base branch.

queue_rules:
  - name: default
    conditions:
      - check-success=Travis CI - Pull Request

pull_request_rules:
  - name: merge using the merge queue
    conditions:
      - base=main
      - "#approved-reviews-by>=2"
      - check-success=Travis CI - Pull Request
    actions:
      queue:
        name: default

๐Ÿšฅ Multiple Queues๐Ÿ”—

By using multiple queues, it's possible to put some pull requests in a higher priority queue. As queues are processed one after the other, the following example allow to add a label urgent to a pull request so it gets put in the higher priority queue.

queue_rules:
  - name: urgent
    conditions:
      - check-success=Travis CI - Pull Request

  - name: default
    conditions:
      - check-success=Travis CI - Pull Request

pull_request_rules:
  - name: move to urgent queue when 2 reviews and label urgent
    conditions:
      - base=main
      - "#approved-reviews-by>=2"
      - label=urgent
    actions:
      queue:
        name: urgent

  - name: merge using the merge queue
    conditions:
      - base=main
      - "#approved-reviews-by>=2"
      - check-success=Travis CI - Pull Request
      - label!=urgent
    actions:
      queue:
        name: default

With such a configuration, a pull request with the label urgent will get into the queue as soon as it's approved by 2 developers but before the CI has even run on it. It will be in front of the default queue. Mergify will update the pull request with its base branch if necessary, wait for the CI to pass and then merge the pull request.

๐ŸŽฒ Speculative Checks๐Ÿ”—

If your continuous integration system takes a long time to validate the enqueued pull requests, it might be interesting to enable speculative checks. This will allow Mergify to trigger multiple runs of the CI in parallel.

In the following example, by setting the speculative_checks option to 2, Mergify will create up to 2 new pull requests to check if the first three enqueued pull requests are mergeable.

queue_rules:
  - name: default
    speculative_checks: 2
    conditions:
      - check-success=Travis CI - Pull Request

pull_request_rules:
  - name: merge using the merge queue and speculative checks
    conditions:
      - base=main
      - "#approved-reviews-by>=2"
      - check-success=Travis CI - Pull Request
    actions:
      queue:
        name: default

Multiple pull requests can be checked within one speculative check by settings batch_size.

For example, by settings speculative_checks: 2 and batch_size: 3, Mergify will create two pull requests: a first one to check if the first three enqueued pull requests are mergeable, and a second one to check the three next enqueued pull requests.

queue_rules:
  - name: default
    speculative_checks: 2
    batch_size: 2
    conditions:
      - check-success=Travis CI - Pull Request

pull_request_rules:
  - name: merge using the merge queue and speculative checks
    conditions:
      - base=main
      - "#approved-reviews-by>=2"
      - check-success=Travis CI - Pull Request
    actions:
      queue:
        name: default

โ›“๏ธ Defining Pull Request Dependencies๐Ÿ”—

Open Source
Feature ๐Ÿ’–

You can specify dependencies between pull requests from the same repository. Mergify waits for the linked pull requests to be merged before merging any pull request with a Depends-On: header.

To use this feature, adds the Depends-On: header to the body of your pull request:

New awesome feature ๐ŸŽ‰

To get the full picture, you may need to look at these pull requests:

Depends-On: #42
Depends-On: https://github.com/organization/repository/pull/123

Warning

This feature does not work for cross-repository dependencies.

Using Rebase to Update๐Ÿ”—

Using the rebase method to update a pull request with its base branch has some drawbacks:

  • It doesn't work for private forked repositories.

  • Every commits SHA-1 of the pull request will change. The pull request author will need to force-push its own branch if they add new commits.

  • GitHub branch protections of your repository may dismiss approved reviews.

  • GitHub branch protection of the contributor repository may deny Mergify force-pushing the rebased pull request.

  • GPG signed commits will lose their signatures.

  • Mergify will impersonate one of the repository members to force-push the branch as GitHub Applications are not authorized to do that by themselves. If you need to control which user is impersonated, you can use the update_bot_account option. Be aware that the GitHub UI will show the collaborator as the author of the push, while it was actually executed by Mergify.