Skip to main content

Pre-merge Checks

Pre-merge checks are quality gates that run automatically after every PR review. They evaluate the review findings against your defined thresholds and post a commit status to GitHub, allowing you to block merges when code quality standards are not met. Checks are configured in the CodePeel dashboard and apply across all your repositories.


Overview

Pre-merge checks bridge the gap between code review findings and merge enforcement. While CodePeel's review engine identifies issues, pre-merge checks turn those findings into actionable gates that integrate with GitHub's branch protection rules.

Each check defines a condition (for example, "no security issues found") and a severity level that determines whether a failure blocks the merge or serves as a soft warning. When a PR review completes, all enabled checks are evaluated against the review metrics. The results are posted as a GitHub commit status under the codepeel/premerge context.

This feature works with GitHub's branch protection rules. When you require the codepeel/premerge status check to pass before merging, any check failure with error severity will prevent the PR from being merged until the issues are resolved.

Pre-merge checks are available on all plans including Free. They do not consume additional reviews -- they evaluate the findings that were already produced by the standard review. The only requirement is that a review must complete successfully for checks to run.


How It Works

The pre-merge check system operates as a post-review evaluation pipeline. It runs automatically after every PR review completes, requires no manual intervention, and integrates directly with GitHub's status checks API.

Step-by-step flow

  1. A PR is opened or updated. CodePeel receives the webhook and runs the standard review (secret scanning, AI analysis, SAST, architecture review).

  2. Review completes with metrics. The review produces aggregate metrics: bugs caught, security issues found, performance issues detected, and critical-severity findings count.

  3. Checks are loaded. CodePeel loads your enabled checks for evaluation.

  4. Each check is evaluated. For each enabled check, the system compares the review metrics against the check's threshold and type. A pass/fail result is determined.

  5. Events are recorded. Each check evaluation is stored with the result, details, repository, commit SHA, and timestamp. The check's pass/fail counters are updated.

  6. Results are stored on the review. The computed results for all checks are saved with the review, making them visible in the dashboard.

  7. GitHub commit status is posted. A single commit status is posted to the PR's head commit under the codepeel/premerge context. If all checks pass, the status is success. If any check with error severity fails, the status is failure.

Commit status details

The commit status posted to GitHub includes:

FieldValue
Contextcodepeel/premerge
Statesuccess or failure
Description"All pre-merge checks passed" or "Pre-merge check failed"
Target URLhttps://codepeel.app/app/premerge-checks

The description is capped at 140 characters per GitHub's API limit. The target URL links to your pre-merge checks dashboard where you can see detailed results.


Check Types

CodePeel provides four predefined check types, each evaluating a different aspect of the review findings. You can enable any combination of these checks simultaneously.

Security Blocker

Fails if any security issue is found in the review. This is a zero-tolerance check with no threshold -- even a single security finding causes failure.

PropertyValue
Check typesecurity_blocker
Default severityerror (blocks merge)
ThresholdNone (any security issue fails)
EvaluationAny security issue fails the check

Use this for repositories that handle sensitive data, authentication, or payment processing where any security vulnerability must be addressed before merging.

Bug Density

Fails if the number of bugs found exceeds your configured threshold. This allows you to tolerate a small number of minor bugs while blocking PRs with many issues.

PropertyValue
Check typebug_density
Default severitywarning
Default threshold5
EvaluationBug count at or below the threshold

Set the threshold based on your team's tolerance. A threshold of 0 means zero bugs allowed. A threshold of 5 means up to 5 bugs are acceptable before the check fails.

Max Issues

Fails if the total number of issues (bugs + security + performance) exceeds your configured threshold. This provides a single aggregate gate across all finding categories.

PropertyValue
Check typemax_issues
Default severityerror (blocks merge)
Default threshold10
EvaluationTotal bug + security + performance findings at or below the threshold

This is the most flexible check type. Set a higher threshold for large PRs or repositories with known technical debt, and a lower threshold for critical services.

Missing threshold passes by default. For bug_density and max_issues checks that are saved without a threshold value, the evaluation short-circuits to "passed". A check saved with no threshold always passes — it is effectively a no-op rather than a zero-tolerance gate. If you want zero tolerance, set the threshold to 0.

Critical Findings

Fails if any critical-severity finding is detected. Critical findings represent the most serious issues: security vulnerabilities, data loss risks, crashes, and race conditions.

PropertyValue
Check typecritical_findings
Default severityerror (blocks merge)
ThresholdNone (any critical finding fails)
EvaluationAny critical finding fails the check

This check is independent of finding category. A critical bug, critical security issue, or critical performance problem all trigger failure.

Check type comparison

Check TypeWhat it evaluatesHas thresholdDefault severity
security_blockerAny security findingsNoerror
bug_densityBug countYeswarning
max_issuesTotal issues (bugs + security + performance)Yeserror
critical_findingsCritical-severity findingsNoerror

Severity Levels

Each check has a severity level that determines its impact on the merge workflow.

Error severity

Checks with error severity block the merge. When any error-severity check fails, GitHub shows a red X on the commit status. If you have branch protection rules requiring the codepeel/premerge status to pass, the PR cannot be merged until all error-severity checks pass.

This is the recommended severity for security blockers and critical findings checks. Use it when you want hard enforcement that cannot be bypassed without fixing the underlying issues.

Warning severity

Checks with warning severity record the failure but do not block the merge. The commit status remains success even if warning-severity checks fail. The failure is visible in the CodePeel dashboard and check history, but it does not prevent merging.

Use warning severity for checks that track quality trends without enforcing hard gates. For example, a bug density check with warning severity lets you monitor how many bugs are introduced per PR without blocking the development workflow.

How severity affects the commit status

The commit status is determined by evaluating all enabled checks:

  • If all checks pass: status is success
  • If only warning-severity checks fail: status is success (warnings do not block)
  • If any error-severity check fails: status is failure

Setting Up Pre-merge Checks

Creating a check

  1. Navigate to Pre-merge Checks in the sidebar
  2. Find the check type you want to enable
  3. Toggle the check to enabled
  4. Set the severity level (error to block merges, warning for soft alerts)
  5. For threshold-based checks (bug_density, max_issues), set your threshold value
  6. The check is immediately active for all future PR reviews

Enabling branch protection

To enforce pre-merge checks as a merge requirement:

  1. Go to your GitHub repository settings
  2. Navigate to Branches > Branch protection rules
  3. Click Add rule (or edit an existing rule for your main branch)
  4. Under "Require status checks to pass before merging", search for codepeel/premerge
  5. Select it and save the rule

Once configured, GitHub will not allow merging any PR where the codepeel/premerge status is failure.

Recommended configuration

For most teams, we recommend starting with:

CheckSeverityThresholdRationale
Security Blockererror--Zero tolerance for security issues
Critical Findingserror--Critical issues must be fixed
Bug Densitywarning5Track bug introduction without blocking
Max Issueserror10Block PRs that exceed overall issue count

This configuration blocks merges only for security and critical issues while providing visibility into bug density and total issue counts.


Dashboard

The Pre-merge Checks page in the dashboard provides a complete view of your checks, their status, and recent history.

Check cards

Each check is displayed as a card showing:

  • Name and description -- what the check evaluates
  • Enabled/disabled toggle -- activate or deactivate the check
  • Severity badge -- error (red) or warning (yellow)
  • Threshold -- for threshold-based checks, the current value
  • Pass/fail ratio -- a bar showing the proportion of passes to failures
  • Last triggered -- when the check last ran (empty if never triggered)

Statistics

Each check tracks cumulative statistics:

StatDescription
Pass countTotal number of times this check has passed
Fail countTotal number of times this check has failed
Last triggeredTimestamp of the most recent failure

These statistics update after every PR review across all your repositories.

Recent History

The Recent History section shows paginated check events (both passes and failures) across all repositories. Each event includes:

  • Result -- pass or fail
  • Check name -- which check was evaluated
  • Repository -- which repo the PR belongs to
  • Commit SHA -- the specific commit that was checked
  • PR number and URL -- link to the pull request
  • Timestamp -- when the check ran
  • Details -- human-readable explanation (e.g., "Check failed: 2 security issues found")

History is paginated with configurable page sizes and supports loading additional pages.


Check Events

Every time a check is evaluated, an event is recorded. These events provide a complete audit trail of all check evaluations.

Detail messages

Each event includes a details field with a human-readable explanation of why the check passed or failed:

Check TypePass messageFail message
security_blocker"Check passed: 0 security issues found""Check failed: 3 security issues found"
bug_density"Check passed: 1 bug found (threshold: 5)""Check failed: 7 bugs found (threshold: 5)"
max_issues"Check passed: 3 total issues (threshold: 10)""Check failed: 12 total issues (threshold: 10)"
critical_findings"Check passed: 0 critical findings""Check failed: 2 critical findings"

Integration with Reviews

Pre-merge check results are saved with the review itself, making them accessible from the review detail page in the dashboard.

After checks are evaluated, the results are saved alongside the review:

[
  {
    "name": "Security Blocker",
    "checkType": "security_blocker",
    "result": true,
    "details": "Check passed: 0 security issues found"
  },
  {
    "name": "Bug Density",
    "checkType": "bug_density",
    "result": false,
    "details": "Check failed: 5 bugs found (threshold: 5)"
  }
]

This allows you to see which checks passed or failed for any specific review without needing a separate query.


API Reference

Pre-merge checks can be managed programmatically through the REST API.

List checks

GET /api/app/checks
Authorization: Bearer <token>

Returns an array of all checks for the authenticated user.

Create a check

POST /api/app/checks
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Security Blocker",
  "description": "Block merge if any security issue is found",
  "enabled": true,
  "severity": "error",
  "checkType": "security_blocker",
  "failureMessage": "Security issues must be resolved before merging"
}

Required fields: name, severity, checkType. For threshold-based checks, include threshold.

Update a check

PATCH /api/app/checks
Authorization: Bearer <token>
Content-Type: application/json

{
  "id": "check-id-here",
  "enabled": false,
  "threshold": 10
}

Delete a check

DELETE /api/app/checks?id=check-id-here
Authorization: Bearer <token>

Troubleshooting

Commit status not appearing on PR

If the codepeel/premerge status does not appear on your PR:

  1. Verify you have at least one enabled check in the dashboard
  2. Confirm the PR review completed successfully (check the review in your dashboard)
  3. Ensure the GitHub App has statuses:write permission on the repository
  4. Check if the review was skipped (WIP title, draft PR, or base branch not in auto_review.base_branches)

The commit status is only posted when at least one check is enabled. If all checks are disabled, no status is posted.

Check always passes even with issues

Verify the check type matches what you expect:

  • security_blocker only evaluates security-type findings, not bugs or performance issues
  • bug_density only counts bug-type findings
  • critical_findings only counts findings with critical severity, regardless of type
  • max_issues counts bugs + security + performance (but not architecture-only findings)

Also verify your threshold is set correctly. A threshold of 5 means the check passes if there are 5 or fewer issues (it fails at 6+).

Check fails but PR can still be merged

This means either:

  1. The check has warning severity (warnings do not block merges)
  2. Branch protection rules are not configured to require the codepeel/premerge status
  3. The repository admin has bypassed branch protection

To enforce blocking, ensure the check severity is error AND the codepeel/premerge status is required in your branch protection rules.

"Last triggered" is empty

The "Last triggered" field only updates on failures. If a check has never failed, this field remains empty even if the check has been evaluated many times (all passes). Check the pass count to confirm the check is running.

Checks not running on incremental reviews

Pre-merge checks run after every review completion, including incremental reviews triggered by new commits. If checks are not running on subsequent pushes, verify that auto_review.auto_incremental_review is true in your configuration.


Frequently Asked Questions

Do pre-merge checks require a paid plan?

Pre-merge checks are available on all plans including Free. However, the checks evaluate findings from the review, so you need available reviews in your quota for the PR to be reviewed in the first place. See Billing for plan details.

Can I have different checks for different repositories?

No. Pre-merge checks are configured at the account level and apply to all repositories where you have the GitHub App installed. All enabled checks are evaluated on every PR review regardless of which repository the PR belongs to.

Do checks run on IDE reviews from the VS Code extension?

No. Pre-merge checks only run on GitHub PR reviews. IDE reviews from the VS Code extension or MCP server do not trigger check evaluation or post commit statuses.

What happens if the check evaluation fails?

If the check evaluation itself encounters an error, the error is logged but does not affect the PR. No commit status is posted in this case, which means the PR is not blocked. This is graceful degradation — a system error should not prevent developers from merging.

Can I create custom check types beyond the four predefined ones?

Not currently. The four check types (security_blocker, bug_density, max_issues, critical_findings) cover the most common quality gate scenarios. The max_issues type with a custom threshold provides flexibility for most use cases. If you need a check type that is not supported, contact support.

How do I see why a specific check failed?

Each check event includes a details field with a human-readable explanation. View this in the Recent History section of the Pre-merge Checks dashboard page. The detail message includes the actual count and threshold (e.g., "Check failed: 5 bugs found (threshold: 5)").

Do checks evaluate architecture findings?

Architecture findings are not included in the max_issues total. The max_issues check counts bugs + security + performance issues only. Architecture findings are evaluated by the critical_findings check if they have critical severity, but they do not contribute to the aggregate issue count used by bug_density or max_issues.

Can I temporarily disable all checks?

Yes. You can toggle each check individually from the dashboard. Disabled checks are not evaluated and do not affect the commit status. If all checks are disabled, no codepeel/premerge status is posted to GitHub at all.

What is the difference between pre-merge checks and custom rules?

Custom rules are regex-based pattern matchers defined in .codepeel.yml that produce individual findings on specific lines. Pre-merge checks are aggregate quality gates that evaluate the total findings from a review and post a pass/fail commit status. Custom rules produce findings; pre-merge checks evaluate the aggregate result of all findings.


Best Practices

Start with warnings, then promote to errors

When first enabling pre-merge checks, set all checks to warning severity. Monitor the results for a few weeks to understand your baseline. Once you are confident the thresholds are appropriate for your team, promote critical checks to error severity.

This approach prevents disruption to your development workflow while you calibrate thresholds. A check that fails too often with error severity will frustrate developers and may lead to the check being disabled entirely.

Use security blocker and critical findings as hard gates

These two checks have no threshold -- they fail on any occurrence. This makes them ideal for hard enforcement because the condition is unambiguous. A single security vulnerability or critical finding is always worth blocking a merge.

For threshold-based checks like bug_density and max_issues, the appropriate threshold depends on your team size, PR size norms, and quality standards. Start with generous thresholds (5-10) and tighten them as your codebase improves.

Combine with health score monitoring

Pre-merge checks evaluate individual metrics (bug count, security count, critical count). For a holistic view of PR quality, also monitor the health score which provides a weighted aggregate across all finding types and severities.

A PR might pass all pre-merge checks (no security issues, bugs under threshold) but still have a low health score due to many medium-severity findings. Use the health score as a complementary signal alongside pre-merge checks.

Set up notifications for failures

When a pre-merge check fails, the commit status on GitHub is the primary notification mechanism. Developers see the red X on their PR and can click through to the CodePeel dashboard for details. For additional visibility, configure GitHub notifications to alert you when status checks fail on your repositories.

Review check history regularly

The Recent History section in the dashboard shows patterns over time. If a particular check fails frequently, it may indicate a systemic issue in your codebase or that the threshold needs adjustment. Conversely, a check that never fails may have too generous a threshold to be useful.


Limitations

Account-level scope

Pre-merge checks are configured at the account level, not per-repository. All enabled checks apply to every repository where you have the GitHub App installed. If you need different thresholds for different repositories, you currently need separate CodePeel accounts.

Single commit status

All checks are aggregated into a single codepeel/premerge commit status. GitHub does not show individual check results in the status -- only the aggregate pass/fail. To see which specific check failed, developers must click through to the CodePeel dashboard.

No custom evaluation logic

Check types are predefined. You cannot write custom evaluation expressions or combine multiple conditions into a single check. For complex quality gates, use multiple checks together -- for example, a security_blocker with error severity AND a max_issues check with warning severity.

Timing dependency

Pre-merge checks only run after a review completes. If the review fails (due to quota exhaustion, rate limiting, or API errors), no checks are evaluated and no commit status is posted. Ensure your account has available reviews for the checks to function.

No retroactive evaluation

Checks are only evaluated at the time a review completes. If you create a new check or change a threshold, existing PRs are not re-evaluated. The new check configuration applies to the next review that runs. To re-evaluate an existing PR, push a new commit to trigger an incremental review.


Related Documentation

  • Features -- How findings are categorized and scored
  • Configuration -- .codepeel.yml settings that affect what findings are produced
  • Billing -- Plans and quotas that determine whether reviews run
← All docsCodePeel