Git, CI/CD & GitOpsLXXXIX · Repository SecurityRepoSecurity
Required status checks — what runs and what must pass
What you'll learn
- Distinguish a check that runs from a check that is required, and explain why only the second is a control
- Predict the failure caused by a renamed check context or a conditionally skipped job
- Decide when strict up-to-date merging is worth its throughput cost
- Reason about what a required check proves when the pull request comes from a fork
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
There is a large difference between a pipeline that runs on every pull request and a pipeline that must pass before the merge button unlocks. The first is information: a red X that a reviewer may or may not look at. The second is a control: the merge is refused by the server. Teams routinely believe they have the second and have only the first, because nobody checked which contexts are actually in the required list.
Required is a list of names
A status check reports a result against a commit under a name - the context. Branch protection holds a list of context names, and a merge is permitted only when every name in that list has reported success on the head commit.
The consequence is that the coupling between the pipeline
and the protection rule is a string. Rename the job that
produces terraform-validate to tf-validate, and the old
context stops reporting. The rule keeps waiting for a name
nothing will ever send.
REPO=example-org/infra-prod
BRANCH=main
gh api "repos/$REPO/branches/$BRANCH/protection/required_status_checks" \
--jq '{strict: .strict, contexts: .contexts}'
flowchart LR
A["pull request head commit"] --> B["CI runs jobs"]
B --> C["contexts reported"]
C --> D{"every required context green?"}
D -->|"yes"| E["merge unlocked"]
D -->|"missing context"| F["merge blocked, waiting forever"]
D -->|"failure"| G["merge blocked, fixable"]
H["required list in protection rule"] --> D
The two blocked outcomes feel identical to an engineer and are entirely different in kind. A failure is the control working. A missing context is the control jammed: nothing is red, nothing is running, and the pull request sits pending until someone with admin rights loses patience.
Strict mode: up to date before merging
Strict mode requires the pull request branch to be current with the base branch before merging. Without it, two pull requests can each pass their checks in isolation and produce a broken base branch when both land - the classic semantic conflict, where neither diff is wrong but their combination is.
The cost is throughput: every merge invalidates every other open pull request, which must update and re-run. On a busy repository this becomes a queue that never drains. The resolutions, in order of preference:
- Merge queue. The branch is tested with the pending merges applied, batched, and merged in order. This gives strict-mode safety without the re-run storm.
- Strict mode without a queue. Correct for a repository with low merge volume, which describes most infrastructure repositories.
- Neither. Acceptable only where the code cannot semantically conflict, which for infrastructure is rarely true - two modules can both be valid and jointly break a plan.
What to require on an infrastructure repository
The list should be short, fast, and deterministic:
- Syntax and schema validation for whatever the repo holds - Terraform, Kubernetes manifests, Ansible.
- Policy evaluation for the rules that cannot be left to human review, such as forbidding wildcard IAM statements or privileged containers.
- Secret scanning on the diff.
- A plan or dry-run that renders the change and fails on anything destructive without an explicit acknowledgement.
Everything else can run and report without being required. A required check must be one whose failure genuinely means “this must not merge”; anything flaky in the required list teaches the team to bypass.
Production discipline
- A check that is not required is not a control. Decide deliberately which are which, and write the decision down.
- Every required context must always report. Conditional jobs must exit success rather than not run.
- Bypass is an incident record. If an administrator merges past a required check, that event gets a ticket and a review, not a shrug.
Cross-course references
- Terraform for Production Sysadmins - the plan-as-a- required-check pattern is the core of safe Terraform delivery, and its failure modes are covered there in depth.
- Kubernetes for Production Engineers - admission policies are the cluster-side equivalent of a required check, applied after the merge rather than before.
- Observability for Production Engineers - the parts on pipeline signals cover alerting when a required check has stopped reporting.
Quiz
Knowledge check · 4 questions
Q1. A documentation-only pull request has been pending for two days. The required context `terraform-plan` shows as expected but never runs, because the job carries a path filter for `terraform/**`. What is the correct fix?
Q2. Strict mode - requiring the branch to be up to date with the base before merging - prevents semantic conflicts between two pull requests that each pass their own checks.
Q3. Explain why the link between a CI job and a required status check is fragile, and name one control that detects the breakage.
Q4. A required policy check has been passing for four months without ever executing. Explain how, and design the detection.
Repository `infra-modules` requires three status checks on `main`: `validate`, `policy`, and `secret-scan`. During a pipeline refactor in March, the policy job was renamed from `policy` to `opa-policy` and its results now report under the new context. In July an audit finds that no pull request since March has been blocked by policy, and that the `policy` context was removed from the required list in April by an engineer who described it as 'a stale check that hangs every PR'.
Passing score: 75%. Answers are checked in this browser.