Reference
Repository policies
Set up .mirage/config.yml, review policy changes, and test scoped previews.
Repository policies control repository-wide Mirage behavior through reviewed configuration. The active file lives in the repository, so policy changes use the same pull requests, approvals, branch protection, and audit history as the code they affect.
Set up a repository policy
The recommended setup takes place in Mirage:
- Connect the private repository to Mirage and enable its GitHub integration.
- Open Settings → Repository Policies and select the repository.
- Turn on the behavior you want. Mirage shows the active value beside the proposed value.
- Select Open draft PR. Mirage validates the policy, creates
.mirage/config.yml, and opens a draft pull request against the default branch. - Review the generated file, let the repository's normal checks run, and merge the pull request when it is ready.
- Return to Settings. The policy is active when Mirage reports that it comes from the repository's default branch.
Mirage creates the .mirage directory and the config file if they do not exist. Opening a
draft does not activate anything; the change becomes active only after it reaches the default
branch.
Understand the source of truth
The copy of .mirage/config.yml on the repository's default branch is the permanent source
of truth. The Settings page is an editor for that file, not a separate configuration store.
You can use either workflow:
- Settings: Mirage validates the form, shows a plan, and opens or updates a draft pull request.
- Code: edit
.mirage/config.ymldirectly, commit it on a branch, and open a pull request yourself.
Mirage resolves policy in this order:
| Priority | Source | When it applies |
|---|---|---|
| 1 | Scoped preview | The selected PR, target commit, proposal commit, and expiry all match |
| 2 | Default branch | .mirage/config.yml exists and passes the versioned schema |
| 3 | Safe defaults | The file is absent or invalid; all new policy behavior stays off |
Mirage stores draft-proposal and preview bookkeeping in its database, but that operational state never replaces the default-branch file. Merging a policy PR changes behavior without a Mirage deployment.
Create the file manually
From the repository root, create the policy directory:
mkdir -p .mirageThen add the complete version 1 policy:
# Repository-wide Mirage behavior. Keep this file on the default branch.
version: 1
pull_requests:
cancel_workflow_runs:
on_merge: true
on_close: falseCommit the file on a branch and merge it through the repository's normal review process. You
do not need to restart a runner or redeploy Mirage. To remove the behavior, change the values
to false or remove the file in another reviewed pull request.
YAML comments are allowed. Do not put credentials or tokens in this file; it is ordinary repository content and may be visible to everyone who can read the repository.
Configuration reference
Mirage uses a strict, versioned schema. version is required and must currently be 1.
Optional sections receive safe defaults, but misspelled and unknown keys are rejected so a
policy cannot appear enabled while doing nothing.
| Key | Type | Default | Effect |
|---|---|---|---|
version | 1 | Required | Selects the repository-policy schema |
pull_requests | Mapping | All PR behavior off | Groups behavior triggered by PR lifecycle events |
pull_requests.cancel_workflow_runs | Mapping | Both values false | Controls whole-run cancellation |
pull_requests.cancel_workflow_runs.on_merge | Boolean | false | Cancels unfinished PR workflow runs after a merge |
pull_requests.cancel_workflow_runs.on_close | Boolean | false | Cancels unfinished PR workflow runs after an unmerged close |
The smallest valid file keeps every optional behavior disabled:
version: 1Merge and unmerged-close behavior are independent. For example, this keeps CI running when a PR merges but cancels it when someone closes the PR without merging:
version: 1
pull_requests:
cancel_workflow_runs:
on_merge: false
on_close: trueUse YAML booleans (true and false), not quoted strings such as "true". Future schema
changes will use a new version instead of silently changing version 1 semantics.
Review changes from Settings
Changing a switch shows an active-versus-proposed plan. Select Open draft PR to validate the complete policy, write it to a generated branch, and open a draft pull request. Further edits update that same draft while it remains open and its branch has not been changed outside Mirage.
The generated PR is intentionally ordinary GitHub configuration:
- repository checks and required approvals still apply;
- reviewers can inspect the exact YAML before it becomes active;
- closing the draft leaves active behavior unchanged; and
- merging it makes the default-branch file authoritative.
If someone edits or force-pushes the generated branch outside Mirage, Mirage stops updating that proposal rather than overwriting their work. Close it and create a new proposal, or finish the change directly in GitHub.
Test one exact revision
After opening the policy draft, enter the number of another open pull request and select Start 2-hour preview. A preview:
- applies only to the selected pull request;
- requires that pull request to target the policy proposal's base branch;
- pins both the selected pull request head and the exact policy proposal commit;
- expires after two hours; and
- becomes invalid immediately if either revision changes or the policy proposal closes.
Preview state is operational data held by Mirage. It never rewrites the target PR and never replaces the policy on the default branch. For cancellation policies, merging or closing the selected test PR is the lifecycle event that exercises the preview.
Because cancellation changes a live GitHub Actions run, use a disposable test PR when you first evaluate the behavior.
Know what cancellation affects
The two lifecycle settings are mutually exclusive for a single PR event:
| GitHub event | Setting consulted |
|---|---|
| PR merged | on_merge |
| PR closed without merging | on_close |
When the selected setting is enabled, Mirage finds unfinished workflow runs that GitHub associated with that pull request and asks GitHub Actions to cancel each whole run. This includes workflows reported against GitHub's synthetic merge commit.
Cancellation is deliberately narrow:
- it cancels an entire workflow run, not an individual Mirage runner job;
- queued and in-progress PR runs are eligible;
- completed runs are left unchanged;
push,workflow_dispatch, and other non-PR runs are not selected; and- runs associated with another pull request are not selected, even if a commit SHA overlaps.
This policy covers jobs that have not reached a Mirage runner as well as jobs routed to other providers. GitHub remains responsible for transitioning the run to its final cancelled state.
Protect and authorize policy changes
Creating proposals requires repository-management access in Mirage and the following GitHub App repository permissions:
- Contents: write to create the config branch and file;
- Pull requests: write to open a draft PR; and
- Actions: write to cancel a matching workflow run.
If an existing installation predates one of these permissions, GitHub may ask an organization owner to approve the updated App permissions. See Connect GitHub for installation and access management.
Treat the file like other sensitive CI configuration. Require pull-request review, protect the default branch, and optionally assign a code owner:
.mirage/config.yml @your-org/ci-adminsTroubleshoot a policy
| Symptom | What to check |
|---|---|
| Settings says the policy is missing | Confirm the exact path is .mirage/config.yml on the repository's default branch |
| Settings says the policy is invalid | Check version: 1, YAML indentation, Boolean values, and unknown or misspelled keys |
| Mirage cannot open the draft PR | Approve the App's Contents, Pull requests, and Actions permissions; confirm the repository is active and not archived |
| A merged draft is not active | Confirm the PR merged into the default branch and that its final file is valid |
| A preview disappeared | Previews expire after two hours and are invalidated by a force-push or a changed/closed policy proposal |
| A run was not cancelled | Confirm the matching merge/close setting is true, the run came from pull_request, and it was still unfinished when the lifecycle event arrived |
| A push run kept running | Expected: cancellation policies select PR-associated runs only |
When the default-branch file is absent or cannot be parsed, Mirage fails safe: it does not introduce cancellation behavior. Correct or revert the file through the repository's normal review process, then reload Repository Policies in Settings.