# Merge Freeze Documentation

Welcome! Hopefully you find what you're looking for. If you're confused about something, or just have feedback about the product please feel free to reach out via email to <hello@mergefreeze.com>.

{% content-ref url="/pages/-Lq5m87kT3pjY6MPkQeK" %}
[Connecting to GitHub](/connecting-to-github)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq5PQLrSc8O\_cqLDooH" %}
[Implementing a merge freeze](/implementing-a-merge-freeze)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq5cfoUE3VquJ5BTmrc" %}
[Recurring freezes](/recurring-freezes)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq5ZIFDsqnZOUfmWqcL" %}
[Slack integration](/slack-integration)
{% endcontent-ref %}

{% content-ref url="/pages/hbchylWu3x6oGziu9l6o" %}
[Mac Menu bar plugin](/mac-menu-bar-plugin)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq5\_BKemzFJJa0IcBVq" %}
[Web API](/web-api)
{% endcontent-ref %}

{% content-ref url="/pages/W9jMZ1SJn7YapyI4Ly75" %}
[GitHub Merge Queue](/github-merge-queue)
{% endcontent-ref %}

{% content-ref url="/pages/-Lq5ba6Y\_djS505F0Kk6" %}
[Uninstalling Merge Freeze](/uninstalling-merge-freeze)
{% endcontent-ref %}

{% content-ref url="/pages/-MlJi8Ug8YiopwCvZj7a" %}
[Frequently asked questions](/frequently-asked-questions)
{% endcontent-ref %}


# Connecting to GitHub

Three steps are involved with connecting Merge Freeze to a protected branch in GitHub: **Authorize Merge Freeze** to access some of your details, **Install the Merge Freeze App** on your GitHub organization or personal account, and **Add a protected branch** so Merge Freeze knows which pull requests to monitor.

[Info about required permissions](/frequently-asked-questions#what-github-permissions-does-the-app-require)

## Authorize Merge Freeze

We use GitHub as the only method for authenticating who you are. We don’t use email/password combinations or any other method to sign you in. This is because we need to ask GitHub what repositories you belong to that also have the Merge Freeze App installed on them.

## Install the Merge Freeze App

Merge Freeze is a [GitHub App](https://developer.github.com/apps/). GitHub Apps offer much more granular permissions than GitHub OAuth Apps and do not belong to any one user. They can be installed either on a whole organisation or only on specific repositories by anyone who is an owner or has admin rights.

## IP Allowlist Management

If your organization uses an IP allowlist for GitHub access (enterprise plans), you'll need to be on a Proactive subscription to use MergeFreeze. Then you have two options for set up. You can&#x20;

1\. allow all GitHub apps access or&#x20;

2\. add IP addresses individually (see [docs](https://docs.github.com/en/enterprise-cloud@latest/organizations/keeping-your-organization-secure/managing-security-settings-for-your-organization/managing-allowed-ip-addresses-for-your-organization#adding-an-allowed-ip-address)).&#x20;

If you'd like to use individual IP addresses, send us an email at <hello@mergefreeze.com> to get set up.

## Create a new project

Merge Freeze works by adding a status check to any pull request that wants to merge into a protected branch of your choosing, usually `main`. Once you have chosen a repository and a protected branch Merge Freeze will automatically send status updates to all pull requests wanting to merge into it (SUCCESS by default until you toggle your first merge freeze).

## Who can implement a merge freeze?

After adding a project to your Merge Freeze dashboard, navigate to the Access Control tab.

<figure><img src="/files/U7LNnOdn4NFZzUgZ1uQl" alt=""><figcaption></figcaption></figure>

From here, repository admins (as defined by GitHub Repository > Permissions > Admin) may select 1 of the following:&#x20;

1. Only repository admins can freeze/unfreeze
2. Repository admins and members with "write" access can freeze/unfreeze
3. All users with repository access

If "Repository admins only" is selected, then only users with GitHub admin privileges on the project's repository can:

* implement a freeze or unfreeze via the web UI
* unfreeze or re-freeze a single pull requests
* unfreeze deployments (if the web API is being used in a deployments script)

If "Repository admins and write access members only" is checked, then only users with GitHub "write" privileges on the project's repository (including admins) can perform the above operations.

To implement the equivalent of "readonly" access, such that Github contributors with only "pull" permissions may access the Merge Freeze dashboard and read project statuses (but not API keys), simply check "Repository admins and write access members only."

**By default, anyone who has access to a repository that has Merge Freeze installed on it will have the option to implement a merge freeze through the web UI**. Here’s how GitHub defines access to a repository:

> The authenticated user has explicit permission to access repositories they own, repositories where they are a collaborator, and repositories that they can access through an organization membership.

Further, **if a project has been connected to Slack, then anyone in that Slack team can also implement a merge freeze** using the `/mergefreeze` Slack command. **This may be restricted** separately inside Merge Freeze > Integrations > Slack. [Learn more](https://docs.mergefreeze.com/slack-integration#restricting-slack-commands-usage).

In addition to the Access Control settings inside your Merge Freeze dashboard, users must have GitHub admin privileges to the repository in order to add, update and delete recurring freezes; connect, disconnect and change the channel of a protected branch’s Slack notifications; and update a protected branch’s web API auth token.


# Implementing a merge freeze

There are two main types of merge freeze: a **manual freeze** and a **scheduled freeze**.

## Manual freeze

To implement a manual freeze all you need to do is click the “Freeze” button inside your protected branch in the Merge Freeze control panel or select "Freeze" from the drop-down menu in the projects list. This will update the Merge Freeze status in GitHub to a FAILED state. Depending on how you’ve set up your protected branch in GitHub this will either block merging completely or be a visual indicator that merging should be avoided.

[How do I set up GitHub to block merging completely rather than just show a warning?](https://docs.mergefreeze.com/frequently-asked-questions#how-come-people-can-still-merge-even-though-i-have-frozen-my-project)

### Unfreeze 1 pull request

Sometimes you may want to get one pull request merged and deployed while still blocking other pull requests from being merged.&#x20;

You can achieve this by clicking “Unfreeze 1 pull request” inside the web UI, or from the `/mergefreeze` Slack command.

<figure><img src="/files/VkPHQ1HyVO6Cfz7T3dEm" alt=""><figcaption></figcaption></figure>

A prompt will appear asking you to provide the name or  number of the pull request that you would like to unblock. The latter is the ID found in GitHub that sits alongside the title of a pull request. It also appears in the URL of the pull request like so: <https://github.com/My-Company/My-App/pull/**5>\*\*.

After clicking a recent PR by name, or inputting a PR by ID, click to Save and Merge Freeze will update the status of that PR so you can merge it into your protected branch.

**Unfreezing single pull requests are only available if your project's "freeze method" is "Push a status update to all PRs."**


# Recurring freezes

It can be useful for a team to establish specific times when merging is allowed/disallowed, such as during the weekends or holidays.

&#x20;Merge Freeze allows you to add weekly recurring freezes by opening up the “Schedules” panel of a protected branch (or [via the API](https://docs.mergefreeze.com/web-api#create-scheduled-freezes)) and selecting the days and times for your recurring freezes.

If you add a recurring freeze and the current time is in the middle of it, then your branch will automatically freeze itself until the end of the recurring freeze.

Recurring freezes can be manually overridden at any time to push out urgent fixes etc.

### What happens if I manually override a recurring freeze?

If a recurring freeze is currently in place and you manually unfreeze it to push out an urgent fix and then refreeze it again, it will automatically unfreeze itself when the recurring freeze period ends.

### Will one-off freezes/unfreezes override a recurring freeze/unfreeze?

The scheduler will skip an additional freeze/unfreeze if there already is a freeze/unfreeze in in place. The scheduler does not prioritize a one-off vs recurring schedule.

*Example 1: You set a one-off freeze at 4:55pm and then a scheduled recurring freeze at 5p.*

The scheduler will see at 5p that the branch is already frozen, and skip the second duplicative scheduled freeze.&#x20;

In this case, the one-off freeze won't override a recurring freeze and you'd only see the branch log associated with the one-off freeze.

*Example 2: You set a recurring daily unfreeze at 8am and refreeze at 4pm. Then, you add a one-time freeze for 5 days from Monday @ 4:01pm through Friday @ 8:01am.*

The scheduler will see the branch is already frozen at 4:01pm on Monday and skip its process. The scheduler will run the daily unfreeze at 8am on Friday and skip the one-time unfreeze because it sees the branch is already unfrozen.


# Slack integration

Merge Freeze offers a Slack app so that your team can easily implement a merge freeze right from Slack and get notified when someone implements a merge freeze.

The Slack app can be added to a project under the “Integrations” panel. Many projects can be linked to one Slack app installation.

## How to link your project with Slack

To integrate with Slack, you will need to have the appropriate permissions to install apps in your Slack workspace.

Login to Merge Freeze, navigate to the project and then click the "Integrations" tab and simply click the “Add to Slack” button (see below). This will take you to Slack to grant the permissions required for the Merge Freeze Slack app to be installed in your workspace.

<figure><img src="/files/Z3Xa5U1cSSNP0Qb6u3w6" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/ysK8hB0Fjocavxpl6jxS" alt=""><figcaption></figcaption></figure>

Once the Merge Freeze Slack app has been installed to your workspace you will be taken back to Merge Freeze and prompted to choose a public or private channel where Merge Freeze notifications will be sent.

<figure><img src="/files/lCYbxTaumB9wkIHHPiYI" alt=""><figcaption></figcaption></figure>

Notifications are sent every time someone freezes/unfreezes a branch, unfreezes/re-freezes a single pull request, or unfreezes / refreezes deployments.

You can change the channel that these notifications go to at any time by clicking “Change” (see above). You can also completely disconnect the Slack app from your project by clicking “Unlink”.

## Using the Slack `/mergefreeze` command to implement a merge freeze/unfreeze

Once the Slack app is connected to a protected branch you can type the `/mergefreeze` command from anywhere in your Slack workspace and you will be shown all the projects associated with this Slack workspace with the option to freeze or unfreeze each one.

Slack users are not associated with Github users so the first time a Slack user types the `/mergefreeze` command they will be asked to accept the Merge Freeze privacy policy and terms and conditions.

<figure><img src="/files/YTumq67CqGaw7mDwgTNt" alt=""><figcaption><p>Merge Freeze's Slack integration showing the unfreeze options</p></figcaption></figure>

## Restricting Slack commands usage

By default, the Slack integration will allow anyone in your Slack organization (*who has access to your connected channel*) to trigger a freeze/unfreeze of one of your Github repositories.

If you'd like to limit Merge Freeze commands to only developers with access to a Merge Freeze.com account, simply check "Restrict access" on the Project > Integrations > Slack settings panel.&#x20;

Slack command attempts by non-developers will be shown instructions to get whitelisted:

![](/files/suRwXDGqeVh1Ol5wiGdT)

Users may sync their MergeFreeze.com and Slack accounts together from inside Merge Freeze > Project > Integrations > Slack, in just a few seconds.

<figure><img src="/files/rUM4mPjhZWIA1VvCDpNJ" alt=""><figcaption></figcaption></figure>

Click "Add User Id" and enter your Slack member id in the modal.

<figure><img src="/files/yjA4nIsUyIKEcbI6wQQN" alt=""><figcaption></figcaption></figure>

## Finding your Slack member ID

When "Restrict Access" is enabled for a project's Slack integration, you're required to whitelist your personal Slack account with your MergeFreeze.com account. We use your Slack Member ID to accomplish this sync.

Inside Slack, click your profile photo in the bottom left corner and select Profile

<figure><img src="/files/bQYe9imUo1s24zlI9t61" alt="" width="187"><figcaption></figcaption></figure>

In the following view, click "the vertical dots and choose "Copy member ID".

<figure><img src="/files/fIG1K7rIz4QshBg4OVcn" alt="" width="375"><figcaption></figcaption></figure>

Go back to MergeFreeze.com and paste this value to link your account. Going forward you'll be able to use `/mergefreeze` commands inside Slack.

## Receiving merge freeze notifications in Slack

When you install the Slack app on a project you will receive a Slack notification every time a team member manually freezes or unfreezes the branch. A notification will not be sent when a scheduled freeze/unfreeze occurs. If you would like to enable the scheduler notifications, check "Scheduler notifications" on the Slack settings panel. As explained above, you can decide which Slack channel receives these notifications for your protected branch.


# Mac Menu bar plugin

Manage projects without logging into your dashboard or visiting a GitHub pull request.

![](/files/wyv4stMGVEXYrhmzrXtS)

View the docs to get up and running in seconds on the open source GitHub repository:

<https://github.com/Merge-Freeze/mac-menu-plugin>


# Web API

### Availability

The Web API can be used on any public repository that has been set up in Merge Freeze, or private repositories if your account subscribes to the Proactive plan.

### Access tokens

Before using the API you must first generate an access token. These access tokens do not expire. If you feel that your access token has been compromised and you’d like to generate another one you can simply click “Regenerate” to create a new one. Please note, however, that your old access token will cease to work from that point onwards.

There are two types of access tokens:

### Project specific access tokens

Project specific access tokens only let you get information or freeze / unfreeze the project that relates to that specific access token. They can be generated in the Web API panel of each project.

### Organization access tokens (organizations only)

Organization access tokens can get information or freeze / unfreeze any project that has been set up in Merge Freeze and belongs to your organization. To generate these access tokens your GitHub account must be an organization (not an individual) and you must be an administrator of the organization.

Assuming you meet the above criteria you'll find the organization access token in your organization settings of the Merge Freeze UI. Simply select Settings in the account dropdown.

## GET freeze status

To implement a complete code freeze, it may not be enough to simply prevent merging into your protected branch on GitHub. You may also want to block *deployments* from happening in whatever software you use to push code to production.

To achieve this we offer an endpoint for each project that provides JSON formatted data about whether there is currently a merge freeze in place or not. By querying this endpoint you can add a condition in your deployment script to only continue if your protected branch is not frozen.

The HTTP method and url to get your protected branch’s Merge Freeze data is as follows: `GET https://www.mergefreeze.com/api/branches/[GitHub account name]/[GitHub repository name]/[protected branch name]/?access_token=[Access token]`&#x20;

The exact url for your project can be found in the "Web API" panel of your project.

The endpoint will return the following fields:

| **Field name**      | **Data type**  | **Description**                                                                                                                                                                                                                                                                                                            |
| ------------------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `branch`            | String         | The name of the protected branch                                                                                                                                                                                                                                                                                           |
| `repository`        | String         | The full name (account + repository name)  of the protected branch’s GitHub repository                                                                                                                                                                                                                                     |
| `note`              | String         | A custom message provided by the team member who last froze the branch (if applicable).                                                                                                                                                                                                                                    |
| `allow_deployments` | Boolean        | Whether or not deployments are blocked; useful for "allow deployments" feature in Slack integration.                                                                                                                                                                                                                       |
| `frozen`            | Boolean        | Whether or not there is currently a merge freeze in place                                                                                                                                                                                                                                                                  |
| `frozen_by`         | String or Null | <p>The name of the person who implemented the merge freeze (may be “scheduled freeze” if a recurring freeze is responsible for the frozen state, or “slack user” if a Slack user has implemented a merge freeze but we don’t have their name).<br><br>Will return null if there is no merge freeze currently in place.</p> |
| `unblocked_prs`     | Array          | List of IDs of unblocked PRs (exceptions to an active freeze, that may be merged into the protected branch).                                                                                                                                                                                                               |
| `timezone`          | String         | The timezone of this branch, set by the user who added this project to Merge Freeze (editable inside the UI).                                                                                                                                                                                                              |
| `next_freeze_at`    | Integer        | Epoch timestamp of the next scheduled freeze (if applicable).                                                                                                                                                                                                                                                              |
| `next_unfreeze_at`  | Integer        | Epoch timestamp of the next scheduled freeze (if applicable).                                                                                                                                                                                                                                                              |

For example:

```
{
  "branch": "master",
  "repository": "Team-FooBar/My-App",
  "note": "CI is down, freezing until it's sorted",
  "allow_deployments": false,
  "frozen": true,
  "frozen_by": "John Wick",
  "unblocked_prs": [325, 411],
  "timezone": "Eastern Time (US & Canada)",
  "next_freeze_at": 1666341060,
  "next_unfreeze_at": 1666357200  
}
```

### GET freeze status errors/warnings

If you make a GET request to a branch or repository that does not exist, but your GitHub Account Name parameter + access token is valid, Merge Freeze will return an empty ( `{}` ) response. Note that **this requires using an** [**Organization-level access token**](#organization-access-tokens-organizations-only), as branch-level access tokens for non-existing branches will not be recognized.

We added this functionality for customers needing to check if projects exist in their Merge Freeze account prior to [creating them via API](#create-branches-projects).

## POST freeze status

In certain situations you may also want to programmatically freeze or unfreeze a branch. This can be done via the following endpoint:`POST https://www.mergefreeze.com/api/branches/[GitHub account name]/[GitHub repository name]/[protected branch name]/?access_token=[Access token]`

You must also send the following parameters either by including them as json in the body of the request or as form data:

| **Field name** | **Data type** | **Description**                                                                                                                   |
| -------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `frozen`       | Boolean       | <p><code>true</code> if you want the project to be frozen.</p><p><code>false</code> if you'd like the project to be unfrozen.</p> |
| `user_name`    | String        | The name of the person implementing the change.                                                                                   |
| `note`         | String        | A reason for the freeze request. Does not work on "unfreezes." **Note**: GitHub interface only shows around 50 characters.        |

The exact url for your project and an example using curl can be found in the "Web API" panel of your project.

This endpoint will return the same fields as the "GET freeze status" endpoint above.

### POST freeze status errors/warnings

If a required parameter is missing or invalid you will receive an HTTP 400 status with a json payload containing an `error` field describing the error.

If you attempt to freeze a project that is already frozen (or unfreeze an unfrozen project) the change will not take place but you will still receive an HTTP 200 status, although you will receive a `warning` field in the response describing the warning in addition to the normal fields returned in a successful response.&#x20;

## Create branches (projects)

If your dev cycle involves switching between branch names on a per week or sprint basis, it can be cumbersome to recreate projects in the Merge Freeze UI.

With a simple API request you may instead set up ([+ destroy](/web-api#delete-branches)) new projects remotely to save some time.

```
curl -d "account=merge-freeze&access_token=xxx&repository=core&branch=master&frozen=true" \
-X POST https://www.mergefreeze.com/api/branches
```

*NOTE: as of Dec2023 this feature is in private beta.* [*Email us*](mailto:hello@mergefreeze.com) *your GitHub organization slug (e.g. /AcmeCo) to gain access.*

**Required** body parameters:

| Field name     | Data type | Description                                                                                                                                    |
| -------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `account`      | String    | GitHub organization slug.                                                                                                                      |
| `access_token` | String    | "Organization-wide" token; generate this on your Installation view (*different from Branch API token -  only account admins can see this UI).* |
| `repository`   | String    | Repository slug on GitHub.                                                                                                                     |
| `branch`       | String    | Name of the branch. This can be changed later in the UI.                                                                                       |

**Optional** body parameters:

<table><thead><tr><th>Field name</th><th width="150">Data type</th><th>Description</th></tr></thead><tbody><tr><td><code>frozen</code></td><td>Boolean</td><td>Sets branch to frozen when true. Default false.</td></tr><tr><td><code>tz</code></td><td>String</td><td>E.g. UTC. Defaults to your most recently created branch's timezone.</td></tr><tr><td><code>generate_access_token</code></td><td>Boolean</td><td>Creates an API token for freezing/unfreezing this branch when true. Default false.</td></tr><tr><td><code>freeze_method</code></td><td>String</td><td>Can be "update_all_pull_requests" or "update_branch_protection_rule", defaults to update all pull requests.</td></tr><tr><td><code>admins_only</code></td><td>Boolean</td><td>Only admins can modify this branch when set to true. Default false.</td></tr></tbody></table>

Branch details (API token if requested, frozen status, etc) will be available in the response object.

## Delete branches

Similar to [creating branches](#create-branches) via the API, this endpoint requires an organization level access token.

```
curl -d "account=merge-freeze&access_token=xxx&repository=core&branch=master" \
-X DELETE https://www.mergefreeze.com/api/branches
```

**Required** body parameters:

| Field name     | Data type | Description                                                                                                                                    |
| -------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `account`      | String    | GitHub organization slug.                                                                                                                      |
| `access_token` | String    | "Organization-wide" token; generate this on your Installation view (*different from Branch API token -  only account admins can see this UI).* |
| `repository`   | String    | Repository slug on GitHub.                                                                                                                     |
| `branch`       | String    | Name of the branch.                                                                                                                            |

## Create scheduled freezes

You may schedule one-off freezes/unfreezes for your projects via the API, as well as the scheduler user interface.

```
curl -d "access_token=xxx&account=merge-freeze&repository=core&branch=master\
&one_off_freeze_at=1662665219&one_off_unfreeze_at=1662924446" \
-X POST https://www.mergefreeze.com/api/scheduled_freezes
```

Required body parameters:

| Field name            | Data type | Description                                            |
| --------------------- | --------- | ------------------------------------------------------ |
| `account`             | String    | GitHub organization slug.                              |
| `access_token`        | String    | "Organization-wide" token or Branch API token.         |
| `repository`          | String    | Repository slug on GitHub.                             |
| `branch`              | String    | Name of the branch.                                    |
| `one_off_freeze_at`   | Integer   | Epoch timestamp denoting when the freeze should begin. |
| `one_off_unfreeze_at` | Integer   | Epoch timestamp denoting when the freeze should end.   |

**Optional** body parameters:

<table><thead><tr><th>Field name</th><th width="150">Data type</th><th>Description</th></tr></thead><tbody><tr><td><code>description</code></td><td>String</td><td>description of freeze</td></tr></tbody></table>

Scheduling one-off freezes via the API across many projects at once may be useful for planning upcoming holidays and other events where deployment schedules will be impacted organization-wide.

## Unfreeze single pull requests

To unfreeze a single pull request, replace the access\_token, pull request numbers and user\_name with your access\_token, the number of the pull requests you'd like to unblock and your name.&#x20;

```
curl -X POST "https://www.mergefreeze.com/api/branches/your-org/your-repo/main/?access_token=YOUR_TOKEN" \
    -d "unblocked_prs=[123, 456]" \
    -d "user_name=Your Name"
```

| Field name      | Data type | Description                                    |
| --------------- | --------- | ---------------------------------------------- |
| `your-org`      | String    | GitHub organization slug.                      |
| `your-repo`     | String    | Repository slug on GitHub.                     |
| `access_token`  | String    | "Organization-wide" token or Branch API token. |
| `unblocked_prs` | Array     | Array of pull request numbers  to unfreeze     |
| `user_name`     | String    | Your name                                      |

## List freeze logs

You may wish to programmatically analyze the freeze/unfreeze logs for an entire organization (installation's) repositories, or just 1 repository.

```
curl https://www.mergefreeze.com/api/freeze_logs?access_token=xxx&account=merge-freeze&repository=core
```

Required body parameters:

| Field name     | Data type | Description                |
| -------------- | --------- | -------------------------- |
| `account`      | String    | GitHub organization slug.  |
| `access_token` | String    | "Organization-wide" token. |

**Optional** body parameters:

<table><thead><tr><th>Field name</th><th width="150">Data type</th><th>Description</th></tr></thead><tbody><tr><td><code>repository</code></td><td>String</td><td>Repository slug on GitHub.</td></tr></tbody></table>

Example reponse:

```
[
  {
    "id": 40257,
    "created_at": "2022-09-19 20:37:51 UTC",
    "action": "unfreeze",
    "branch_tz": "Eastern Time (US & Canada)",
    "context": "web",
    "branch": "master",
    "repository": "core",
    "note": null
  },
  {
    "id": 40256,
    "created_at": "2022-09-25 12:04:32 UTC",
    "action": "freeze",
    "branch_tz": "Eastern Time (US & Canada)",
    "context": "slack",
    "branch": "master",
    "repository": "mac-menu-plugin",
    "note": "awaiting approval by Xbar marketplace"
  }
]
```

## Allow deployments but block merging

If you’d like to perform a deployment while still keeping a merge freeze in place you can click the “Allow deployments” button. This button only shows up if your branch is currently frozen and you have created an access token for the Web API (an indication that you may be using it).

Clicking this button will change the Web API response’s `frozen` field to **false** but the merge freeze will stay on in all other places, so your team members will not be able to merge into the protected branch.

This can be undone by clicking the “Undo” link.

## Rate limits

To prevent abuse, requests to Merge Freeze are restricted to 100 per minute. Any requests exceeding this threshold will return a 429 error code and a `RateLimit-Reset` header with a time stamp indicating when the rate limit time period will be reset.

**Note** that this limit is much higher than [GitHub's rate limit](https://docs.mergefreeze.com/frequently-asked-questions#i-want-to-freeze-unfreeze-all-of-my-repositories-at-the-same-time), thus requests made with the intent to modify projects on GitHub should follow [those limits](https://docs.mergefreeze.com/frequently-asked-questions#i-want-to-freeze-unfreeze-all-of-my-repositories-at-the-same-time) instead of ours.


# GitHub Merge Queue

Automatically merge pull requests with real-time status checks by Merge Freeze.

Merge Freeze supports [GitHub's Merge Queue](https://github.blog/changelog/2023-02-08-pull-request-merge-queue-public-beta/), a branch protection rule add-on that automates status checks when pull requests are 1) enqueued and 2) ready to merge.

If you installed Merge Freeze prior to May 17, 2023, see [Troubleshooting](#troubleshooting) first to ensure your Organization shares sufficient API scopes with our GitHub Application.

### Get Started

Connect your desired GitHub repository to Merge Freeze from the Merge Freeze dashboard > "+ New Project" interface.

Then visit the repository on GitHub and navigate to Settings > Branches > Edit/Create a Branch Rule.

<figure><img src="/files/2rpUW2njvYhxbN1twZWE" alt=""><figcaption></figcaption></figure>

Ensure "Require status checks to pass before merging" is selected, then type "mergefreeze" (no spaces) into the search box and select the Merge Freeze application.

Next, scroll down and check "Require merge queue," followed by saving these settings.

<figure><img src="/files/FU5JXWvcYMFxU6Y7e1Sr" alt=""><figcaption></figcaption></figure>

You're done! Merge Freeze will now send status checks to your GitHub merge queue.

### How it Works

Here's what happens when Merge Freeze is included as a "status check" for a branch protection rule with Merge Queue enabled. See [Demonstration](#demonstration) below for a screenshot-driven explanation.

1. Click "merge when ready" from a pull request on GitHub.
2. GitHub sends a "[pull\_request.enqueued](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request)" webhook event to Merge Freeze.
3. Merge Freeze sends back the status of your project's main branch (configured inside the Merge Freeze dashboard). This status is either "success" or "failure" pending whether the branch is unfrozen or frozen, respectively.
4. Onc&#x65;**\*** the branch is unfrozen, Merge Freeze will send a status back to GitHub letting it know the PR is OK to be enqueued to the Merge Queue. Note: all of your branch rule "status checks" send a ping like this, thus all status checks must send a "success" state for the PR to enter your Merge Queue.
5. Your pull request enters the Merge Queue. When it reaches the head (to&#x70;**\*\***) of the queue, a "[merge\_group.checks\_requested](https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payloads?actionType=checks_requested#merge_group)" webhook event is sent to Merge Freeze for a final check.
6. Just like Step 3, Merge Freeze again sends back the status of your project's branch.
7. If this status is "success" (along with other branch rule checks), your pull request will be merged automatically. If not, the pull request will be kicked from the Merge Group and return to "merge when ready" state.

**\***&#x49;f your branch is already unfrozen when the payload from Step 2 is received, Merge Freeze will immediately send a "success" status check. If your branch is frozen, Merge Freeze will send a "failure" status check. Later, when you unfreeze the branch via Merge Freeze, we'll send a new "success" ping to restart the enqueue process.\
\
**\*\***&#x47;itHub allows Merge Queue users to run parallel builds. Thus "head/top" does not necesarily mean the #1 slot of a queue, but rather "within the range of parallel builds."&#x20;

<figure><img src="/files/kRa9TMAOw8RJ1cBt86Dv" alt=""><figcaption></figcaption></figure>

In other words, Merge Freeze may send a 2nd and final status update *several minutes before* the automatic merge is to occur, which can lead to false positives (see [Edge Cases](#edge-cases) below).

### Demonstration

Opening a pull request that already has Merge Queue enabled, with Merge Freeze as one of the required status checks.

<figure><img src="/files/J3kpi3dGnAfOOb8cpL5t" alt=""><figcaption></figcaption></figure>

Opening a pull request that is already failing the Merge Freeze status check.

<figure><img src="/files/K37VWAzunjINCU2f2Yql" alt=""><figcaption></figcaption></figure>

Pull request that passed the Merge Freeze (+ other, if applicable) status checks, waiting to be merged from the Merge Queue.

<figure><img src="/files/6oZb6TGZ90NGPPdHLcRC" alt=""><figcaption></figcaption></figure>

Pull request in the merge queue, awaiting final status check.

<figure><img src="/files/1xGKbU3itaKnCr3M5GUL" alt=""><figcaption></figcaption></figure>

Pull request in the merge queue, after failing the Merge Freeze status check. (This will soon after be kicked out of the queue).

<figure><img src="/files/aG5GaJE9w6n5Z0MbqzBX" alt=""><figcaption></figcaption></figure>

&#x20;Pull request in the merge queue, after passing the Merge Freeze status check.

<figure><img src="/files/lt9uyvaXD6Gl6Xh457LI" alt=""><figcaption></figcaption></figure>

### Troubleshooting

If you installed Merge Freeze prior to May 17, 2023, your integration with us does not support the Merge Queue scope by default.

To add support for Merge Queue, visit your Organization on GitHub and navigate to Settings > GitHub Apps. You should see a request for additional permissions by Merge Freeze.

<figure><img src="/files/ETtre2qRyRmoTCfVBNkH" alt=""><figcaption></figcaption></figure>

Click "review request" and accept our new API scope -- Merge queues read/write.

<figure><img src="/files/T7Rtl3Jib9vGWACBrjMR" alt=""><figcaption></figcaption></figure>

After accepting the new permissions, check out the top of this guide to get started with Merge Queue. Note that an Organization administrator may be required to complete these steps.

### Edge Cases

Suppose you have a CI build that takes several minutes to run. When your pull request is enqueued, Merge Freeze will reply immediately with a "success" status if the branch is unfrozen. However your build may run for another 10 minutes. Thus it's possible your branch's status could change from unfrozen to frozen during this build period, yet GitHub's Merge Queue wouldn't be aware because the Merge Freeze status check already passed.&#x20;

To avoid this type of false positive (CI build passes, branch is frozen), it may be a good idea for teams with long CI build times to implement a GET hook that double checks a branch's unfrozen status at the end of a build, then returns a "failure" status to GitHub even if tests and other workflows were successful.

<figure><img src="/files/c1zAUeMQxLYfEsppI2xc" alt=""><figcaption></figcaption></figure>

Ideally, GitHub will someday [allow developers to sequence their branch rule status checks](https://github.com/orgs/community/discussions/46757#discussioncomment-5950067). With this functionality, developers can simply make Merge Freeze the final check, guaranteeing real-time status updates for imminent merges.


# Uninstalling Merge Freeze

Before uninstalling Merge Freeze be sure to unfreeze any projects so that any outstanding Merge Freeze status checks will not inhibit you from merging.

If you’d like to stop using Merge Freeze all you need to do is uninstall the Github App from your organization / personal account. You can do this in Github by going to **Settings -> Applications**.

If you'd like to cancel your subscription, please email us at ***<hello@mergefreeze.com>*** to let us know.


# Frequently asked questions

## What GitHub permissions does the app require?

### **Repository permissions**

**Administration: Read and write.** This is so we can add and remove protected branch rules on a repository when the "Toggle a protected branch" freeze method is being used.

**Metadata: Read-only.** So we can see which repositories a user has access to.

**Pull requests: Read-only.** So we know which pull requests to send commit statuses to when using the "Update all pull requests" freeze method.

**Commit statuses: Read and write.** So we can update commit statuses to either success or failure when using the "Update all pull requests" freeze method.

We're not able to read or write to your repository's code base.

### Organization permissions

**Members: Read only.** So we can determine a logged in user's role within an organization (an organization administrator has access to more settings in the Merge Freeze UI).

### User authorization permissions

We don't ask for any extra permissions at the user level beyond what is required to login via GitHub.

## **Is self-hosted GitHub Enterprise supported?**

Unfortunately we don’t yet support self-hosted GitHub Enterprise instances.

GitHub marketplace apps can’t be installed on self-hosted GitHub instances. Apps for these instances require a complex setup involving creating a new app on the self-hosted instance with all the same permissions and webhook configuration as the app found in the GitHub Marketplace.

The app’s code needs to be told the url of the self-hosted GitHub instance and is then run in either a container on the privately hosted machine, or it runs in the cloud (like the marketplace app) and is allowed to connect to the private server.

Both options involve complexity that we have decided not to undertake yet. We apologize to anyone who’s affected by this and hope to have a solution some time in the future.

## **When I try and subscribe to a paid plan all I see is “Unfortunately, invoiced customers cannot purchase paid plans on the GitHub Marketplace.”** <a href="#github-invoiced-customer" id="github-invoiced-customer"></a>

When an invoiced GitHub account tries to sign up for a subscription to Merge Freeze via the GitHub marketplace they are sadly met with the following message: “Unfortunately, invoiced customers cannot purchase paid plans on the GitHub Marketplace.”

We offer payment via Stripe for these customers. To do this you’ll need to **first sign up to the Open source plan** (which is free). Then visit your Installation's settings page by choosing Settings from the organizations menu.

<figure><img src="/files/dNzu8XPo91qNcFU5WqSp" alt="" width="180"><figcaption></figcaption></figure>

On this page you'll see the option to start a free trial via credit card or ACH in the bottom left of the Plans section:

<figure><img src="/files/FX6lK86KbDmiOkOAA5TO" alt=""><figcaption></figcaption></figure>

After choosing a plan (Reactive or Proactive) you'll be able to add a payment method and begin a 14 day free trial.

If you prefer to pay annually for a discount, simply start a free trial on a monthly plan, then modify your plan when the Installation view refreshes. From this portal you may upgrade, downgrade, switch to annual billing, and download previous invoices.

<figure><img src="/files/w60eX4DoCP8eLlOvZ1MT" alt=""><figcaption></figcaption></figure>

## How do I fix a pull request that has a Merge Freeze status check that’s stuck on pending?

If a pull request is created or updated in GitHub it will send Merge Freeze a webhook. Merge Freeze then tries to find the current status of the relevant project (frozen or unfrozen) and sends the pull request a status update via the GitHub API.

If a network error occurs so that the webhook never reaches Merge Freeze, or some other error occurs so that the status update doesn’t make it to GitHub then the Merge Freeze status can be left in a “pending” state with a message that says something like “Expected - Waiting for status to be received”.

To fix this you can either send an update to your pull request so that it triggers another webhook, or you can force Merge Freeze to send another status update to all open pull requests by toggling a freeze off and on again.

New commits can be made to a repository without having to make code changes using the `--allow-empty` flag e.g.

```
git commit --allow-empty -m "Trigger update"
```

## Merge Freeze no longer updates the status of my pull request

It turns out that no single commit id can be given more than 1000 status updates from the same context (you can consider Merge Freeze to be a context). So if you have an old pull request that has been sitting there without any new commits it’s possible with many freezes and unfreezes that this limit is hit.

To fix this you’ll need to send a new commit to the pull request. New commits can be made to a repository without having to make code changes using the `--allow-empty` flag e.g.

```
git commit --allow-empty -m "Trigger update"
```

## Why does it take so long for all PRs to get updated when freezing / unfreezing?

If you’re using the default “Push a status update to all PRs” method of freezing then every time a project is frozen or unfrozen we need to make an API call to every open pull request.

These updates must be done serially, according to GitHub [app rules](https://docs.github.com/en/rest/guides/best-practices-for-integrators#dealing-with-secondary-rate-limits). If you have many open pull requests it may take some time to update them all (roughly one second per pull request).

If you have many pull requests that need updating you may wish to switch to the “Toggle a branch protection rule” method of freezing. This can be done in a project’s settings under “Freeze method.”

## How come people can still merge even though I have frozen my project?

By default GitHub will still let you merge even when status checks fail:

![](https://gblobscdn.gitbook.com/assets%2F-Lq5EXtrdrxFiGoaLv7h%2F-Lzmv6k3Awb1EPejxZik%2F-Lzmvc53SzXK3oyvZ1G_%2Fgithub-mergefreeze-canmerge.png?alt=media\&token=c4c2adb4-065c-4419-ab4a-8789ad9f7e57)

To block merging completely: In your GitHub repository head to **Settings** -> **Branches** -> **Protected branches** and choose the branch that you'd like to be able to freeze (e.g. master).

![](https://gblobscdn.gitbook.com/assets%2F-Lq5EXtrdrxFiGoaLv7h%2F-Lzmv6k3Awb1EPejxZik%2F-LzmvlIaydjfMnD3svob%2Fgithub-mergefreeze-step1.png?alt=media\&token=de9835e5-3c8f-4ef7-b299-a96eebbdc00c)

* Check **Protect this branch**.
* Check **Require status checks to pass before merging**.
* Under **Status checks found in the last week for this repository** check **mergefreeze**.
* Optionally check **Include administrators** if you want admins to obey the rules too.
* Click **Save changes**

![](https://gblobscdn.gitbook.com/assets%2F-Lq5EXtrdrxFiGoaLv7h%2F-Lzmv6k3Awb1EPejxZik%2F-Lzmvt568QskU2rqEhR3%2Fgithub-mergefreeze-step2.png?alt=media\&token=d7991f8f-d50b-45f6-b70f-5fa7155883b5)

Now when the branch is frozen users will not be able to merge:

![](https://gblobscdn.gitbook.com/assets%2F-Lq5EXtrdrxFiGoaLv7h%2F-Lzmv6k3Awb1EPejxZik%2F-Lzmw1PiB19KBE3OH4Wn%2Fgithub-mergefreeze-cannot-merge.png?alt=media\&token=9617b081-27ff-4fa2-b246-5ed0840f9d20)

## Do I need to invite other users to my Merge Freeze project?

You don’t need to specifically invite users to your Merge Freeze project to allow them to freeze / unfreeze projects.

Merge Freeze uses GitHub permissions system to decide which projects a user should have access to. It does this by using the GitHub API to fetch all repositories that have the Merge Freeze app installed and that the user is a member of. These will automatically show in the user’s Merge Freeze control panel when they login.

## I want to freeze / unfreeze all of my repositories at the same time

You can batch freeze or unfreeze by selecting multiple projects on the Dashboard. GitHub only allows one update per second for each open pull request, however, so using this may lead to long update times if you update all PRs in every repository of your organization.

For reasons stated above, please be careful with this feature. Alternatively, consider using the Merge Freeze [API](https://docs.mergefreeze.com/web-api#post-freeze-status) with an [organization level access token](https://docs.mergefreeze.com/web-api#organization-access-tokens-organizations-only) to loop through each of your repos and freeze them 1 at a time programmatically, keeping in mind that a 1 req/sec [rate-limit](https://docs.mergefreeze.com/web-api#rate-limits) applies.


