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.Options
A window is either dated (
start and end) or recurring (from and to), never a mix.
Recurring windows
fromandtomust both name a day or both leave it out, and they must differ.- Days are
Mon,Tue,Wed,Thu,Fri,SatandSun. Hours run from00to23, with two digits. - When
tocomes beforefrom, the window runs over midnight, or over the weekend.
'22:00'.
Dated windows
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
scheduleandworkflow_dispatchevents 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 switchingactiveon or off, run the workflow by hand to update the open pull requests at once. - Merge queue. On a
merge_groupevent 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.
What you will see on GitHub
- A
smartcloud / merge freezecheck 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 / freezecheck 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 withGITHUB_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 freeze ended but pull requests are still blocked
The freeze ended but pull requests are still blocked
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.Adding the hotfix label did not unblock the pull request
Adding the hotfix label did not unblock the pull request
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.Merges are not blocked during a freeze
Merges are not blocked during a freeze
Require
smartcloud / merge freeze in the ruleset. Requiring only the smartcloud aggregate is not enough, because
it leaves smartcloud’s own checks out.Config warning: from and to must both name a day or both leave it out, and must differ
Config warning: from and to must both name a day or both leave it out, and must differ
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.Config warning: not a valid date and time, or end must be after start
Config warning: not a valid date and time, or end must be after start
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.Config warning: unknown time zone
Config warning: unknown time zone
Use an IANA name such as
Europe/London or America/New_York, not an abbreviation such as BST.Warning: Could not publish the smartcloud / merge freeze check
Warning: Could not publish the smartcloud / merge freeze check
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.