What Merge Preflight does

Merge Preflight turns repository and operational state into one deterministic merge decision.

For each ready pull request, it resolves the effective repository policy, queries any required Jira, Linear, or Sentry state, evaluates rules in order, and publishes the verdict to GitHub. Summary comments explain blockers and remediation. Every evaluation and emergency bypass is persisted for audit.

Merge gate & bypass

A failing rule blocks merge (or warns if you configure it to). In emergency situations, it can be bypassed: comment @mergepreflight bypass <reason>. Bypass log is auditable.

Explainable output

Each rule returns a stable status, reason, remediation, and safe external references. Warnings remain visible without blocking.

Operational context

Policies can incorporate issue workflow (Jira/Linear), incident state (Sentry), deployment freezes, release windows, changed files, commits, labels, and naming conventions.

Policy examples

Keep release changes traceable and reviewable

Require issue-shaped branch, commit, and title conventions; cap review size; and demand release notes on release or hotfix branches. Naming failures block, while the size limit starts as a warning.

schema_version: 1
branch_name_policy:
  patterns:
    - '^feature/[A-Z]+-\d+-.*$'
    - '^hotfix/[A-Z]+-\d+-.*$'
commit_message_policy:
  patterns:
    - '^[A-Z]+-\d+ .+$'
  scope: all_commits
pull_request_title_policy:
  patterns:
    - '^[A-Z]+-\d+: .+$'
pull_request_size_policy:
  max_changed_lines: 1000
  max_changed_files: 25
changelog_policy:
  branches:
    - '^release/.*$'
    - '^hotfix/.*$'
  required_files:
    - CHANGELOG.md
    - docs/releases/*.md
rules:
  - id: branch_name_pattern
  - id: commit_message_pattern
  - id: pull_request_title_pattern
  - id: maximum_pull_request_size
    configuration:
      mode: warn
  - id: require_changelog

Freeze unrelated work during a production incident

Require a Jira issue to be release ready, then use Sentry's unresolved critical issue state to admit only work linked to the incident or labeled as an incident fix. Provider outages fail closed.

schema_version: 1
bypass_allowlist:
  - incident-commander
rules:
  - id: require_linked_jira_issue_status
    configuration:
      accepted_statuses: [Approved, Done]
      external_account_ref: jira-production
  - id: block_unrelated_pr_during_sentry_critical
    configuration:
      incident_fix_labels: [hotfix, incident-fix]
      external_account_ref: sentry-production
      failure_behavior: fail_closed
Schema version 1

Configuration model

The effective policy comes from one of three sources: a hosted repository policy, the repository policy file (default path .mergepreflight.yml), or an installation-level organization default with sparse repository overrides. Hosted and repository-file policies use the same schema and rule IDs.

Key Meaning
schema_version Required. The implemented schema version is 1.
rules Ordered rule definitions. Each accepts id, optional enabled (default true), and optional configuration or config.
bypass_allowlist SCM usernames authorized to use comment-command bypass in addition to repository authorization settings.
comments.enabled Retained in schema version 1 for compatibility. Runtime comment publication is controlled by the repository's comment mode.
Shortcut sections branch_name_policy, commit_message_policy, pull_request_title_policy, pull_request_size_policy, freeze_windows, and changelog_policy keep structured rule data readable.

Rule status and failure semantics

  • mode: block is the default. A failed rule produces a blocker.
  • mode: warn reports the same finding without blocking the merge.
  • enabled: false produces a skipped rule result.
  • Invalid YAML, an unsupported schema, an unknown hosted-policy parameter, or invalid rule configuration produces an explicit policy-configuration error instead of silently weakening enforcement.
  • Sentry-backed policies additionally support failure_behavior: fail_closed (default) or fail_open when the provider cannot be queried.

Policy reference

The IDs below are the complete currently registered policy set.

Pull request hygiene

Require pull request label

require_pull_request_label

Passes when the pull request has at least one configured label. Matching is case-insensitive.

labels
Required non-empty list of accepted labels. Singular label remains accepted by repository YAML.
mode
block or warn.
schema_version: 1
rules:
  - id: require_pull_request_label
    configuration:
      labels: [release-ready, production-approved]

Require issue reference

require_issue_reference

Searches the pull request title and body for any configured regular expression. This is provider-neutral and does not call Jira or Linear.

patterns
Required list of regular expressions. Singular pattern is also accepted.
mode
block or warn.
schema_version: 1
rules:
  - id: require_issue_reference
    configuration:
      patterns:
        - '[A-Z]+-\d+'
        - 'INC-\d+'

Pull request title pattern

pull_request_title_pattern

Requires the entire pull request title to match at least one configured regular expression.

patterns
Required list of title regular expressions, provided directly or through pull_request_title_policy.patterns.
mode
block or warn.
schema_version: 1
pull_request_title_policy:
  patterns:
    - '^[A-Z]+-\d+: .+$'
    - '^NOISSUE: .+$'
rules:
  - id: pull_request_title_pattern

Maximum pull request size

maximum_pull_request_size

Enforces any combination of changed-line, changed-file, and commit-count limits. At least one positive limit is required; unavailable required SCM data fails closed.

max_changed_lines
Maximum additions plus deletions.
max_changed_files
Maximum changed files.
max_commits
Maximum pull request commits.
mode
block or warn.
schema_version: 1
pull_request_size_policy:
  max_changed_lines: 1200
  max_changed_files: 30
  max_commits: 20
rules:
  - id: maximum_pull_request_size
    configuration:
      mode: warn

Source control conventions

Branch name pattern

branch_name_pattern

Requires the entire source branch name to match at least one configured regular expression.

patterns
Required list of branch regular expressions, provided directly or through branch_name_policy.patterns.
mode
block or warn.
schema_version: 1
branch_name_policy:
  patterns:
    - '^feature/[A-Z]+-\d+-.*$'
    - '^hotfix/INC-\d+-.*$'
rules:
  - id: branch_name_pattern

Commit message pattern

commit_message_pattern

Requires selected pull request commit messages to match at least one regular expression and reports the first offending commit.

patterns
Required list of commit-message regular expressions.
scope
all_commits (default) or latest_commit. Legacy merge_range_commits remains parseable for existing YAML.
mode
block or warn.
schema_version: 1
commit_message_policy:
  patterns:
    - '^[A-Z]+-\d+ .+$'
  scope: all_commits
rules:
  - id: commit_message_pattern

Release safety

Freeze windows

freeze_window

Blocks during scheduled local-time release freezes. The application clock is evaluated in the configured IANA timezone; overnight windows carry into the next day and equal start/end times mean a full-day freeze.

freeze_windows.timezone
Required IANA timezone.
freeze_windows.periods
Day-name lists with local HH:mm start and end times.
mode
block or warn.
schema_version: 1
freeze_windows:
  timezone: Europe/Berlin
  periods:
    - days: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY]
      start: '19:00'
      end: '09:00'
    - days: [SATURDAY, SUNDAY]
      start: '00:00'
      end: '00:00'
rules:
  - id: freeze_window

Require changelog

require_changelog

Runs only when the source branch matches a configured regular expression, then requires at least one changed file to match an exact path or glob. Non-matching branches pass without a changelog requirement.

branches
Required source-branch regular expressions.
required_files
Required exact paths or glob patterns.
mode
block or warn.
schema_version: 1
changelog_policy:
  branches:
    - '^release/.*$'
    - '^hotfix/.*$'
  required_files:
    - CHANGELOG.md
    - docs/releases/*.md
rules:
  - id: require_changelog

Require no active deployment freeze

require_no_active_deployment_freeze

Queries Sentry incident/error state and blocks while the selected deployment-freeze object is active. No matching object means no active freeze.

Requires an active installation-scoped Sentry connection with incident lookup capability. Sentry SaaS uses read-only OAuth; self-managed Sentry can use encrypted token credentials. If multiple Sentry accounts are connected, select one with external_account_ref.

deployment_freeze_reference
Lookup text; defaults to active deployment freeze.
external_account_ref
Optional stable Sentry connection reference.
failure_behavior
fail_closed (default) or fail_open.
mode
block or warn.
schema_version: 1
rules:
  - id: require_no_active_deployment_freeze
    configuration:
      deployment_freeze_reference: active production deployment freeze
      external_account_ref: sentry-production
      failure_behavior: fail_closed

External systems

Jira

Require Jira issue in an allowed status

require_linked_jira_issue_status

Finds Jira issue keys in the pull request title, description, and branch name, resolves them against the selected Jira site, and requires the linked issue's workflow status to allow merging.

Requires an active installation-scoped Jira connection with issue-status capability. Jira Cloud uses read-only Atlassian OAuth; Jira Data Center can use encrypted token credentials. Connection settings may restrict readable projects; accepted workflow statuses belong to this policy. The hosted editor presents connected Jira sites by name.

accepted_statuses
Required Jira workflow status names.
issue
Optional explicit Jira issue key.
external_account_ref
Optional stable Jira connection reference.
mode
block or warn.
schema_version: 1
rules:
  - id: require_linked_jira_issue_status
    configuration:
      accepted_statuses: [Approved, Ready, Done]
      external_account_ref: jira-production
Linear

Require Linear issue in an allowed state

require_linked_linear_issue_state

Finds Linear issue identifiers in the pull request title, description, and branch name, resolves them against the selected Linear workspace, and requires the linked issue's workflow state to allow merging.

Requires an active installation-scoped Linear OAuth connection with issue-status capability. The integration is installed as a read-only workspace application actor. Connection settings may restrict readable teams; accepted workflow states belong to this policy. Discovered team keys identify Linear references automatically, while linear_prefixes remains an optional YAML fine-tuning control.

accepted_states
Required Linear workflow state names.
linear_prefixes
Optional team-key allowlist used to disambiguate detected issue identifiers.
issue
Optional explicit Linear issue identifier.
external_account_ref
Optional stable Linear connection reference.
mode
block or warn.
schema_version: 1
rules:
  - id: require_linked_linear_issue_state
    configuration:
      accepted_states: [Ready, Done]
      linear_prefixes: [ENG, OPS]
      external_account_ref: linear-production
Sentry

Block unrelated PRs during Sentry incidents

block_unrelated_pr_during_sentry_critical

Looks up active critical Sentry state and blocks unrelated work. A pull request passes when it references the active incident or has one of the configured incident-fix labels. No active incident means the rule passes.

Requires an active installation-scoped Sentry connection with incident lookup capability. Sentry SaaS uses read-only OAuth; self-managed Sentry can use encrypted token credentials. Connection settings define the projects, environments, critical levels, and optional short-reference prefixes searched by the provider.

incident_reference
Optional lookup text overriding pull request-derived incident references.
incident_fix_labels
Labels treated as incident fixes; defaults to hotfix and incident-fix.
external_account_ref
Optional stable Sentry connection reference.
failure_behavior
fail_closed (default) or fail_open.
mode
block or warn.
schema_version: 1
rules:
  - id: block_unrelated_pr_during_sentry_critical
    configuration:
      incident_fix_labels: [hotfix, incident-fix]
      external_account_ref: sentry-production
      failure_behavior: fail_closed
Sentry

Allow linked hotfix during incident

allow_linked_hotfix_during_incident

Evaluates the incident exception explicitly: linked or incident-fix-labeled work passes during an active incident; unrelated work fails or warns. If no active incident exists, no exception is required and the rule passes.

This rule is registered and supported by the engine but is not exposed as a separate hosted-editor control. It uses the same Sentry connection, incident lookup, project/environment/critical-level filtering, account selection, and credential handling described above.

incident_reference
Optional lookup text overriding pull request-derived incident references.
incident_fix_labels
Labels treated as incident fixes; defaults to hotfix and incident-fix.
external_account_ref
Optional stable Sentry connection reference.
failure_behavior
fail_closed (default) or fail_open.
mode
block or warn.
schema_version: 1
rules:
  - id: allow_linked_hotfix_during_incident
    configuration:
      incident_fix_labels: [hotfix, incident-fix]
      external_account_ref: sentry-production
      failure_behavior: fail_open
Runtime behavior

Evaluation, publication, and bypass

Rules execute in document order against pull request snapshot. A rule returns PASSED, WARNING, BLOCKED, SKIPPED, or ERROR. The overall evaluation is blocked when any blocker exists, errored when rule evaluation errors exist, and passed otherwise.

Emergency bypass

On a blocked pull request, an authorized actor can comment @mergepreflight bypass <reason>. The reason is mandatory. Authorization comes from repository administrators, the policy's bypass_allowlist, or configured provider-confirmed target-branch merge authority; generic write access is not sufficient.

A bypass is bound to the current evaluation/head and records the actor, reason, repository and pull request reference, head SHA, timestamp, and blockers present at the time. It is treated as an audited exception.