Skip to documentation

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:

  1. Connect the private repository to Mirage and enable its GitHub integration.
  2. Open Settings → Repository Policies and select the repository.
  3. Turn on the behavior you want. Mirage shows the active value beside the proposed value.
  4. Select Open draft PR. Mirage validates the policy, creates .mirage/config.yml, and opens a draft pull request against the default branch.
  5. Review the generated file, let the repository's normal checks run, and merge the pull request when it is ready.
  6. 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.yml directly, commit it on a branch, and open a pull request yourself.

Mirage resolves policy in this order:

PrioritySourceWhen it applies
1Scoped previewThe selected PR, target commit, proposal commit, and expiry all match
2Default branch.mirage/config.yml exists and passes the versioned schema
3Safe defaultsThe 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:

Create the policy directory
mkdir -p .mirage

Then add the complete version 1 policy:

.mirage/config.yml
# Repository-wide Mirage behavior. Keep this file on the default branch.
version: 1
pull_requests:
  cancel_workflow_runs:
    on_merge: true
    on_close: false

Commit 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.

KeyTypeDefaultEffect
version1RequiredSelects the repository-policy schema
pull_requestsMappingAll PR behavior offGroups behavior triggered by PR lifecycle events
pull_requests.cancel_workflow_runsMappingBoth values falseControls whole-run cancellation
pull_requests.cancel_workflow_runs.on_mergeBooleanfalseCancels unfinished PR workflow runs after a merge
pull_requests.cancel_workflow_runs.on_closeBooleanfalseCancels unfinished PR workflow runs after an unmerged close

The smallest valid file keeps every optional behavior disabled:

Minimal safe policy
version: 1

Merge 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:

Cancel only after an unmerged close
version: 1
pull_requests:
  cancel_workflow_runs:
    on_merge: false
    on_close: true

Use 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 eventSetting consulted
PR mergedon_merge
PR closed without mergingon_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:

CODEOWNERS
.mirage/config.yml @your-org/ci-admins

Troubleshoot a policy

SymptomWhat to check
Settings says the policy is missingConfirm the exact path is .mirage/config.yml on the repository's default branch
Settings says the policy is invalidCheck version: 1, YAML indentation, Boolean values, and unknown or misspelled keys
Mirage cannot open the draft PRApprove the App's Contents, Pull requests, and Actions permissions; confirm the repository is active and not archived
A merged draft is not activeConfirm the PR merged into the default branch and that its final file is valid
A preview disappearedPreviews expire after two hours and are invalidated by a force-push or a changed/closed policy proposal
A run was not cancelledConfirm 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 runningExpected: 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.