Write your .cihub.yaml
Change the behavior of a queue or add queues with the .cihub.yaml file of the repository; write it by hand with the JSON Schema, or with an assistant.
A queue works without a file: the first /cihub merge on the default branch creates its queue with the default
settings. .cihub.yaml, at the root of the repository, changes the behavior of a queue, adds queues on other
branches, and sets who goes first.
CIHub reads the file on the head of the target branch, never on a pull request: a pull request cannot loosen its own
gate. A change of the file applies once it merges. The file can also be .cihub.yml, .cihub/config.yaml or
.cihub/config.yml, but only one of them: with two, the configuration is in error.
Start the file
The first line declares the JSON Schema: your editor then completes each key and shows an error before you commit.
# yaml-language-server: $schema=https://cihub.io/schema/config/v1.json
version: 1Editors with a YAML language server, such as VS Code with its YAML extension, read this line.
A complete example
# yaml-language-server: $schema=https://cihub.io/schema/config/v1.json
version: 1
# Settings and conditions of every queue, unless a queue sets its own.
defaults:
queue_conditions:
draft: false
labels:
none:
- do-not-merge
queues:
- branch: main
strategy: batched
batching:
size: 3
max_wait_minutes: 1
# The checks that the test of the queue must pass, in addition to those of the rules of the branch.
merge_conditions:
checks:
success:
- Build Success
# A kind of pull request with its own settings, in the same queue.
profiles:
- name: dependencies
conditions:
author: renovate[bot]
batching:
size: 10
# Each release branch gets its own queue.
- branch: release/*
strategy: sequential
# The first rule that a pull request meets gives its priority; /cihub merge --priority wins.
priority_rules:
- name: hotfixes
conditions:
labels:
- hotfix
priority: urgent
- name: dependencies
conditions:
author: renovate[bot]
priority: low| Key | What it does |
|---|---|
queues | One entry per branch, or per glob of branches (release/*): each branch that it matches has its own queue |
strategy | How the queue tests the pull requests: Choose a strategy |
queue_conditions | What a pull request must meet to enter the line, in addition to the rules of the branch |
merge_conditions | The checks that the test commit must pass, in addition to the required checks |
profiles | The settings of a kind of pull request in the same queue, such as the updates of dependencies |
priority_rules | Who goes first: urgent, high, medium, low, or 0 to 255 |
defaults | The settings and the conditions of every queue that does not set its own |
Write conditions
A condition is a YAML map: the key is an attribute of the pull request, and every key must hold.
queue_conditions:
draft: false # a boolean
base: main # a value, or a list of values (one of them)
labels:
none: # a list: all, any, none, or count
- do-not-merge
files:
none_match: # globs
- "migrations/**"
approved_reviews_by:
count:
min: 2
checks:
success:
- buildany:, all: and none: take a list of maps. The attributes cover the state of the pull request (draft,
conflict, from_fork, behind_base), its reviews, its checks, its labels, its author, its files and its size, its
base and its head, and its position and age in the queue. The JSON schema
describes every attribute, and
specs/CONFIGURATION.md gives their
rules.
When a submitted pull request does not meet a condition, its comment names it: "the queue conditions labels: ready
are not met".
Check the file
- The schema line makes your editor check each key and each value.
- An unknown key, a value out of range or two queues on one branch is an error, with its line.
- The page of the queue in the dashboard shows the error of the file on the target branch. Until you fix it, the queue keeps the last valid file; a test that needs the file fails with "the configuration file is not valid".
Write it with an assistant
An assistant writes a valid file if it knows the rules of the file. Copy this prompt into it: it asks you the right questions first, then writes the file and explains each choice.
Help me write the .cihub.yaml file of CIHub, a merge queue for GitHub. Ask me
questions first, one at a time: which branches need a queue, how long my CI
takes and how often it fails, which checks are required, which labels or
reviews must block a merge, and which pull requests must go first.
Then write the file, with only the keys below, and explain each choice.
Rules of the file (version 1):
- Its first line declares the schema, for the editor:
`# yaml-language-server: $schema=https://cihub.io/schema/config/v1.json`.
- It starts with `version: 1`. Top-level keys: `queues` (a list),
`priority_rules` (a list) and `defaults` (any queue setting and the
conditions, without `branch` or `profiles`). An unknown key is an error.
- Each queue has a `branch`, unique in the file: a branch has one queue, and
a pull request goes to the queue of its base branch. A `branch` can be a
glob (`release/*`): each branch that it matches gets its own queue, and an
entry that names a branch wins over a glob. For an urgent pull request,
use `priority_rules`, not a second queue.
- If the file has no queue for the default branch, that branch still has
one. Other branches have a queue only with an entry.
- YAML anchors (`&name`, `*name`) and merge keys (`<<: *name`) work, to
write a map of conditions or a set of settings once.
- `strategy`: `sequential` (one test at a time), `pipelined` (default: tests
in parallel, each on top of the ones ahead) or `batched` (`pipelined` with
several pull requests per test; a failed batch is split to find the
cause). Do not use `parallel`: it is not ready yet.
- `batching: { enabled, size: 2-20, max_wait_minutes: 1-60 }`: on with
`batched` (size 4, wait 5 by default), off otherwise.
- `merge_method`: `squash` (default), `merge_commit`, `rebase`, or
`fast_forward` (only with `strategy: sequential`).
- `trigger`: `draft_pr` (default: a draft pull request runs the CI of each
test) or `push` (the push of the test branch runs it).
- `window: { floor: 1-100, ceiling: 1-100 }`, floor <= ceiling (default 2 /
20, 1 / 1 with `sequential`), or `testing_concurrency: 1-100` instead.
- `failure_budget: { retries: 0-10 }` (default 1): retries before a pull
request fails.
- `testing_timeout_minutes` (10-1440, default 300), `not_ready_timeout_hours`
(1-720, default 168), `keep_test_branches_minutes` (0-1440, default 0).
- `merge_commit_title`: `pr_title` (default) or `pr_title_and_number`.
- Booleans: `comments_enabled`, `commands_enabled`, `status_check_enabled`
(default true), `state_labels_enabled`, `resubmit_on_push` (default false).
- `label_commands: { enabled: true, enqueue_label: <label> }`: a label that
submits the pull request (default `cihub-merge-queue-submit`).
- `direct_merge_mode`: `always` (default: when no test runs, merge the first
pull request without a test branch if it contains the head of the target
branch and its checks are green) or `off`.
- `branch_protection_injection`: `both` (default), `merge` or `none`: whether
the checks required by the branch rules also count before admission and on
the test commit.
- `required_statuses`: a list of check names for the test commit; without
the key, they come from the branch rules. With no required check at all,
every test fails.
- `queue_conditions`: what a pull request must meet to enter the queue.
`merge_conditions`: only `checks`, then `success`, then a list of check
names, which adds required checks on the test commit. Those of `defaults` come first, and
each queue adds its own.
- `profiles` (in a queue): a list of `{ name, conditions, merge_method,
merge_commit_title, batching, failure_budget }` for a kind of pull request
in the same queue, such as dependency updates. The first profile whose
`conditions` match, read once at the submission, gives these settings;
`/cihub merge --profile=<name>` names one. A batch holds one profile.
A profile cannot set `fast_forward`, nor the settings of the whole queue.
- `priority_rules`: a list of `{ name, conditions, priority }`, where priority
is `urgent` (0), `high` (10), `medium` (100, default), `low` (200) or 0-255;
a lower number goes first; the first rule that matches wins.
Conditions are a YAML map, in the block style: the key is an attribute, the
value is typed, and every key must hold. A boolean takes `true` or `false`
(`draft: false`). A string takes a value or a list (one of them), or `not`
(none of them), `matches` (globs) or `regex`. A list takes a list of values
(all of them), or `all`, `any`, `none`, `any_match`, `all_match`,
`none_match` (globs) or `count` (a number, or `min` and `max`). A number or
a duration takes a value (equal), or `min` and `max` (inclusive). The checks
are under one `checks` map: `success`, `neutral`, `skipped`, `failure`,
`pending`. `all:`, `any:` and `none:` take a list of maps. Attributes:
draft, conflict, from_fork, behind_base, number, title, body,
review_decision (approved, changes_requested, review_required, none),
approved_reviews_by, changes_requested_reviews_by, review_requested,
review_threads_unresolved, checks, labels, author, sender, sender_permission
(none < read < write < admin; takes `min`, `max`), files, additions,
deletions, base, head, queue_position, queue_age, pr_age. Durations are
`<n>m`, `<n>h` or `<n>d`. Only `true` and `false` are booleans. Quote a value
that starts with `*`. For example:
queue_conditions:
draft: false
labels:
none:
- do-not-merge
checks:
success:
- buildA coding agent reads the same rules from the schema and from this site in Markdown: Use CIHub with a coding agent.
Submit, cancel and restart a pull request
Submit a pull request to the queue from a comment, a label, the checkbox of CIHub, the command line or the dashboard; give it a priority; cancel it or restart its tests; pause a queue.
Choose a strategy
Sequential, pipelined or batched, how the queue tests the pull requests, and which strategy fits the length of your CI and the number of pull requests a day.