Skip to main content
A merge freeze stops pull requests merging for a while: during a release, over a weekend, or through the holidays. You might want one so nobody ships a change while the team is away, or while a release is being cut. The freeze feature keeps a smartcloud / merge freeze check on every open pull request’s head commit. The check fails while a freeze is in effect and passes otherwise. Require that check in your branch ruleset, and nothing merges during a freeze. You can start a freeze by hand (active: true) or on a schedule (windows), and let urgent fixes through with a label.

Turn it on

1

Add a freeze section

.github/smartcloud.yml
2

Run on the right events

The check must be updated when a pull request changes, when a window opens or closes, and when the merge queue tries to merge. Add labeled and unlabeled so an exempt label takes effect at once, and a schedule at least as often as your windows need:
.github/workflows/smartcloud.yml
3

Grant the permissions

The job needs checks: write to write the check, and statuses: read and pull-requests: read to read what is already there. The permissions in Getting started include them.
4

Require the freeze check

Require smartcloud / merge freeze in the ruleset. With the settings feature:
.github/smartcloud.yml
The required aggregate leaves smartcloud’s own smartcloud / ... checks out, so the freeze check must be required on its own, beside the aggregate.

Options

A window is either dated (start and end) or recurring (from and to), never a mix.

Recurring windows

  • from and to must both name a day or both leave it out, and they must differ.
  • Days are Mon, Tue, Wed, Thu, Fri, Sat and Sun. Hours run from 00 to 23, with two digits.
  • When to comes before from, the window runs over midnight, or over the weekend.
Quote a time that YAML could read as something else, such as '22:00'.

Dated windows

The date must be real: 2026-02-30 is rejected, not rolled over to March.

Complete example

.github/smartcloud.yml

How it works

When more than one freeze is in effect, the check names the manual freeze first, then the first open window in the order the config lists them. Its summary reads, for example, Merges are frozen by the weekend window (No weekend deploys) until Mon 08:00 (Europe/London). The freeze check is brought up to date on three kinds of event:
  • Pull request events. On each event for an open pull request, the feature works out the check for the head commit and publishes it if the conclusion differs from the last one it published there. During a freeze it also leaves a warning (freeze.active) in the report, or a notice (freeze.exempt) when an exempt label lets the pull request through. It does not fail the smartcloud job: the job’s own check would stay failed after the freeze ends, while the freeze check is updated.
  • Scheduled runs. On schedule and workflow_dispatch events it updates the check on every open pull request, publishing a new one only where the conclusion changes, and records a notice (freeze.swept) with how many it updated. A freeze window starts and ends between events, so run the workflow on a schedule at least as often as the windows need, for example hourly, or at the windows’ edges. After switching active on or off, run the workflow by hand to update the open pull requests at once.
  • Merge queue. On a merge_group event a freeze is an error, which fails the smartcloud job and so the queue entry, whatever the pull request’s labels. With a merge queue, the freeze is checked at the moment of merging, so the schedule matters less.
Exempt labels are compared exactly as written, including case.

What you will see on GitHub

  • A smartcloud / merge freeze check run on every open pull request: failure titled “Merges are frozen” during a freeze, success titled “No merge freeze” otherwise, and success titled “Exempt from the merge freeze” when the pull request has an exempt label. This is the check that blocks merging.
  • A smartcloud / freeze check with the feature’s findings, like every feature. It is neutral during a freeze (a warning) and does not block.
  • During a freeze, a warning in the report comment on the pull request saying when merging can resume.
  • A failed merge queue entry, if a queued pull request reaches the front during a freeze.
  • In the job summary of a scheduled run, how many pull requests had their check updated.

Forks and restricted runs

The feature writes the check with GITHUB_TOKEN and reads the commit’s checks with the workflow token, as the required feature does. On a pull request from a fork the token is read-only: the feature cannot write the check, and records a warning (freeze.check) instead of failing the run. The next scheduled run, which acts with the repository’s own token, publishes the check on the fork’s head commit.

Troubleshooting

The check only changes when the workflow runs. Add a schedule often enough to catch the end of each window, or run the workflow by hand with workflow_dispatch.
Add labeled and unlabeled to the workflow’s pull_request types. Check that the label matches an exempt.labels entry exactly, including case. In a merge queue, labels do not help: a freeze fails every queue entry.
Require smartcloud / merge freeze in the ruleset. Requiring only the smartcloud aggregate is not enough, because it leaves smartcloud’s own checks out.
Write both times as HH:MM, or both as Day HH:MM. A window whose from equals its to would be empty, so it is rejected.
Dated windows need a full date and time with an offset, such as 2026-12-24T00:00:00Z, on a real calendar day, and end later than start.
Use an IANA name such as Europe/London or America/New_York, not an abbreviation such as BST.
The token could not write the check, usually because the pull request comes from a fork. The next scheduled run fixes it. On your own pull requests, check the job has checks: write.
Last modified on September 27, 2026