Status Check Configuration Patterns¶
Required vs Optional Checks¶
Quick Start
This guide is part of a modular documentation set. Refer to related guides in the navigation for complete context.
Required Checks¶
Block merge if they fail:
- Unit tests
- Integration tests
- Security scans (HIGH/CRITICAL)
- Linting
Configure in branch protection.
Optional Checks¶
Provide information but don't block:
- Performance benchmarks
- Code coverage reports
- Dependency updates
Run in workflow but don't add to required_status_checks.
Handling Flaky Tests¶
Flaky tests that fail randomly undermine trust.
Pattern 1: Retry Failed Tests¶
- name: Run tests
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
command: go test ./...
Genuine failures fail three times. Flakes eventually pass.
Pattern 2: Quarantine Flaky Tests¶
func TestFlakyBehavior(t *testing.T) {
if testing.Short() {
t.Skip("Flaky test - quarantined")
}
// Test code
}
Run with go test -short to skip quarantined tests.
Schedule separate job for quarantined tests:
quarantine-tests:
if: github.event_name == 'schedule' # Nightly
runs-on: ubuntu-latest
steps:
- name: Run quarantined tests
run: go test ./... -run TestFlaky
Don't let flakes block development. Isolate and fix separately.
Check Timing Strategies¶
Parallel Execution¶
jobs:
tests:
# Runs in parallel with security-scan and lint
security-scan:
# Runs in parallel
lint:
# Runs in parallel
Default: All jobs run concurrently. Fastest feedback.
Sequential Execution¶
jobs:
lint:
runs-on: ubuntu-latest
# Runs first
tests:
needs: lint # Waits for lint
runs-on: ubuntu-latest
security:
needs: tests # Waits for tests
runs-on: ubuntu-latest
Use when later checks depend on earlier results.
Fast-Fail Strategy¶
jobs:
quick-checks:
# Lint and format (30 seconds)
tests:
needs: quick-checks # Only runs if quick checks pass
# Tests (5 minutes)
security:
needs: tests # Only runs if tests pass
# Security scan (10 minutes)
Fails fast on cheap checks. Saves expensive check time.
Status Check Names¶
GitHub matches check names exactly. Be consistent:
# Bad - name mismatch
name: CI
jobs:
test-suite:
name: test-suite # Branch protection expects "tests" - FAILS
Verify with:
Dynamic Required Checks¶
Different branches may need different checks:
# Require basic checks on all branches
required_status_checks:
contexts:
- "tests"
- "lint"
# Production branches get additional checks
production_required_checks:
contexts:
- "tests"
- "lint"
- "security-scan"
- "load-test"
Use GitHub API or Terraform to configure per-branch rules.
Exempting Bot PRs¶
Dependabot or Renovate PRs may not need all checks:
Better approach: Let checks run but don't require manual review:
# Branch protection
required_pull_request_reviews:
required_approving_review_count: 1
bypass_pull_request_allowances:
apps: ["dependabot"]
Checks still run. Bot PRs auto-merge if checks pass.
Related Patterns¶
- Core Concepts - Status check fundamentals
- Operations Guide - Debugging and evidence collection
- Matrix Filtering - Optimize check execution
Flaky test quarantined. Fast-fail strategy saved 8 minutes. Check names aligned. Configuration enforced.