Two pull requests can each pass against yesterday's main branch and still break when combined. Repository rules define the conditions for changing a branch, while a merge queue evaluates eligible changes in a candidate that includes the current target and earlier queued work. The queue needs CI that understands its event. This lesson connects policy design to a complete workflow skeleton and a small compatibility exercise. Feature availability varies by repository, visibility and plan, so verify support before adopting a queue or rule requirement.
Define requirements from concrete failure cases
Begin with the behavior you want to prevent: an unreviewed API change, a missing test result, an accidental branch deletion or a history rewrite. Map each failure case to an explicit repository requirement instead of enabling every option without understanding it. Name the target branch or tag pattern and document who can bypass the rule. A useful policy has a normal contribution path and a narrow, observable exception path for genuine emergencies.
Rulesets can coexist with other applicable rulesets and branch protection. Evaluate the effective combination rather than assuming the newest rule replaces older requirements. For example, review requirements from multiple sources can leave a stricter effective review count than one screen suggests. Read the repository's visible rules and compare them with the merge box on an actual pull request. Keep policy changes reviewable, and test a new requirement in a practice repository before applying it to a busy default branch.
Identify the check that represents project correctness
A required check needs a clear, stable identity and a job that genuinely exercises the intended behavior. Give jobs distinctive names across workflows so results are not ambiguous. Consider whether the requirement expects a specific integration as the source. A check named tests that merely prints a message would establish almost nothing, even if the platform correctly enforces it. The workflow below is explicitly a runnable structural demonstration; replace its tiny inline assertion with your repository's actual checkout and test commands before requiring it.
Avoid event and path filters that prevent an expected check from ever being created for a candidate. If a workflow skips whole runs for some changes, understand how the required-check configuration sees those missing results. Test documentation-only, code and workflow changes against the policy. The goal is to make the relevant verification happen consistently, not to create a gate that blocks harmless work because its selected workflow never ran.
Make CI handle merge-group candidates
A merge queue creates temporary candidate history containing the target branch and the queued changes under evaluation. A pull_request-only workflow does not cover that event. Add merge_group with its checks_requested activity to a workflow that supplies queue-required checks. The check should evaluate the candidate supplied for that run rather than hard-code main or the original pull request head. Otherwise it can report a passing result while ignoring the combination the queue needs to validate.
External CI integrations need their own documented support for queue candidates and status reporting. Do not assume that adding a GitHub Actions event fixes a separate provider. Observe one queued request from creation through its check result and merge or removal. Confirm the candidate identifier in logs, the check identity and the final branch update. A failed queue check is a reason to inspect the combined behavior; bypassing it simply because the original pull request was green defeats the queue's purpose.
Tune the process using observed outcomes
A queue is most useful when concurrent contributions make repeated manual updates expensive or unreliable. It can also introduce new waiting time and CI load. Measure failures, queue duration and repeated work before changing batching or concurrency settings. Keep a clear response when a candidate fails: identify the failing test, reproduce the combined state and decide which contribution needs adjustment. Contributors should be able to understand why their request left the queue.
Review bypass permissions, merge methods and CI reliability together. A queue cannot guarantee a healthy branch if the required test omits the failing behavior or privileged users routinely skip the gate. Preserve a documented emergency process and audit its use. Treat flaky tests as project defects that undermine the decision signal; do not repeatedly re-run until one green result hides a real pattern. The policy should make the branch's evidence understandable to maintainers and contributors.
Sources and prerequisites
Review pull requests, Actions and code review. Read the official ruleset model, available rules, merge queue setup and workflow events.
GitHub Repository Rulesets and Merge Queue Checks Summary
- Plan rules from concrete failure cases and inspect all applicable requirements.
- Produce stable meaningful checks for merge_group as well as pull_request.
- A queue tests combinations under your configured evidence; maintain those tests.
GitHub Repository Rulesets and Merge Queue Checks Examples
Each example shows the code, the output it produces and what each part does.
A complete Actions trigger skeleton for queue checks
Save this as .github/workflows/queue-contract.yml in a practice repository. It needs no repository checkout because its assertion is entirely inline. The expected output is from that assertion when GitHub runs either supported event. This local lesson does not create a ruleset or claim a live queue execution.
The event configuration is the important platform part of this example. The demonstration assertion does not validate your application. For real use, run the same meaningful project checks on both pull-request and merge-group candidates, check out the correct candidate and select that stable check in the applicable rule.
name: Queue contract demo
on:
pull_request:
merge_group:
types: [checks_requested]
permissions: {}
jobs:
queue-contract:
name: queue-contract
runs-on: ubuntu-latest
steps:
- name: Check the demonstration contract
run: |
node --input-type=module <<'NODE'
import assert from 'node:assert/strict';
const config = { version: 2, parserVersion: 2 };
assert.equal(config.version, config.parserVersion);
console.log('contract passed');
NODEcontract passedGitHub Repository Rulesets and Merge Queue Checks in Real Projects
Model why combined changes need merge queue testing
Run this standalone Node.js program locally. It models why two independently acceptable changes may need a combined test: one updates the produced format and the other keeps an old parser expectation. It is a compatibility exercise, not an emulator of GitHub's merge queue.
const base = { produced: 1, accepted: 1 };
const changeA = { produced: 2, accepted: 2 };
const changeB = { produced: 1, accepted: 1, newFeature: true };
const compatible = value => value.produced === value.accepted;
const combined = { ...changeA, accepted: changeB.accepted, newFeature: true };
console.log('A alone:', compatible(changeA));
console.log('B alone:', compatible(changeB));
console.log('combined:', compatible(combined));
const fixed = { ...combined, accepted: changeA.accepted };
console.log('reviewed combination:', compatible(fixed));A alone: true
B alone: true
combined: false
reviewed combination: trueThe combined object intentionally exposes the disagreement between versions. A test that runs only against each isolated change misses it. In a repository, the exact candidate tree and meaningful integration tests play the roles represented by this small model.
GitHub Repository Rulesets and Merge Queue Checks FAQ
Why is a queued pull request waiting for a check that never appears?
Inspect whether the workflow listens for merge_group and whether its filters permit the queue candidate to create the expected check. Confirm the job's identity matches the required check and that external CI supports queue candidates if it supplies the result. Compare the run's candidate identifier with the queue entry. A passing pull_request run does not automatically supply the separate candidate verification that a merge queue expects.
Does a ruleset replace every older branch protection setting?
Do not assume replacement. Applicable rulesets and branch protections can work together, and multiple rulesets can contribute effective restrictions. Inspect the full rule set targeting the branch and test the observed merge requirements. When consolidating policy, remove or change obsolete requirements deliberately rather than leaving overlapping settings unexplained. Document the resulting review count, checks and bypass permissions so contributors can predict the normal process.
Should I require the queue-contract demonstration job in production?
Only after replacing the demonstration assertion with checks that establish your actual project's contract. A green inline constant comparison proves that its own tiny expression succeeded, not that the repository builds or its integrations work. Use the skeleton to learn the event configuration, then add a correct candidate checkout, dependencies and meaningful tests. Verify the same required check is produced for both ordinary requests and queue candidates.
Can a merge queue guarantee that main will never break?
It can evaluate combined candidates under the configured checks, but the checks and process define the evidence available. Missing tests, flaky checks, uncontrolled bypasses or external changes can still lead to failures. Observe queue outcomes and improve the tests around real failure cases. Treat the queue as an integration mechanism whose assumptions you maintain, rather than a substitute for meaningful verification and a reviewed repository policy.
GitHub Repository Rulesets and Merge Queue Checks Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Which result exposes the version disagreement in the compatibility exercise?
GitHub Repository Rulesets and Merge Queue Checks Quiz
2 questions to check what you learned.
Which Actions event is needed to evaluate a merge queue candidate?
- merge_group with checks_requested
- Only issue_comment
- Only a manually named branch called queue
What should a real queue-required check evaluate?
- Only a hard-coded old main revision
- The candidate combining target and queued changes
- Only the pull request title