CI/CD governance
Required status checks and branch protection
A green check only helps a protected branch when it matches the required check name, its expected source app, and the revision GitHub is evaluating. Inspect the pull request status box before merging: an older head result, a different app, or a missing context is not equivalent to a passing required check. Merge queue adds a separate group revision that also needs its required results.
Match the check GitHub is actually requiring
GitHub branch protection turns a check into a merge condition. The useful question is not whether a page somewhere shows green; it is whether the configured required context has an acceptable result on the revision GitHub is currently evaluating. Record the context name, the source app when the rule pins one, and the evaluated commit together. A result that matches only two of those three coordinates cannot establish that the branch rule is satisfied. This is especially easy to miss when several CI tools use similar labels or when a pull request receives a fresh push after an earlier successful run.
A required check can be a check run or a commit status. GitHub lets a branch rule select a particular GitHub App as the expected source of a required check. That source setting matters: a successful result with the same display name from another writer does not satisfy a rule expecting the selected app. If a check run and a commit status share the required name, GitHub requires both to pass. Give jobs distinct, stable names across workflows so the required context is unambiguous, and review the actual rule rather than inferring its settings from a green icon.
The revision coordinate needs just as much attention. GitHub requires the latest applicable commit to pass. When the pull request has a test merge commit with status, GitHub evaluates that merge commit; otherwise it uses the latest head commit. The pull request checks box indicates when it is showing checks for the merge commit. An earlier head result cannot be carried forward just because the code change looks small. Strict branch protection also requires the branch to be up to date with its base before merging, while a loose rule does not impose that freshness condition. Neither mode makes an old check result evidence for a newer revision.
For a team review, write down one sentence: context verify, expected source CI App, evaluated revision H2, accepted conclusion only after the matching result appears. Those labels are illustrative; H2 is not a real SHA and CI App is not a claimed integration. The sentence forces reviewers to compare the configured rule with the run being inspected. It also prevents a common category error: a green workflow on a nearby branch does not answer the pull request gate. GitHub Actions job checks from workflow_dispatch are ineligible for pull request branch-ruleset required checks, even when run on the same head commit; this event rule does not describe checks from external GitHub Apps.
Sources: About protected branches — GitHub Docs · Troubleshooting required status checks — GitHub Docs
Understand green, skipped, and pending
GitHub accepts successful, skipped, and neutral conclusions for required checks. That is a statement about how the branch gate evaluates a reported check, not proof that every intended test ran. A job skipped by a condition can report an acceptable conclusion; the repository should decide separately whether that skip is legitimate for the change. If a required verification job can skip the very paths it is supposed to protect, the branch rule may be formally satisfied while the policy has a coverage gap. Review the job condition and the reason for its conclusion before treating green as tested.
Skipping an entire workflow is different. If branch, path, or commit-message filters prevent the workflow from starting, GitHub can leave its associated required check Pending, which blocks the merge. The fix is to make the required check appear reliably for changes governed by the rule, then let its real job logic decide what to test. Do not remove the requirement merely to clear a pending badge. A missing required check should trigger an investigation of event eligibility, workflow filters, and context spelling; it should not be converted into an unrecorded exemption.
A job can also be skipped because an upstream job failed. GitHub documents that this dependency behavior can produce a surprising successful or skipped required result; workflows that must run after a dependency failure can use an appropriate condition such as always(). Apply that only after reviewing the job's purpose and failure handling. A terminal status tells you how GitHub will treat the gate. It does not substitute for the policy question of which checks must execute and what result should stop a merge.
The safest debugging order is to compare the configured rule with the pull request status box, then open the exact check run. Confirm the context text, its app, the displayed commit, and the conclusion. If the workflow never started, inspect its event and filters. If it started but the expected job did not report, inspect job names and dependencies. This narrows the repair to the producer of the missing evidence without weakening branch protection for every future pull request.
Sources: About protected branches — GitHub Docs · Troubleshooting required status checks — GitHub Docs
A green result on the wrong coordinate
Consider an illustrative rule requiring a context called verify from a selected CI App. A pull request first points at head revision H1, where verify succeeds. A developer pushes H2. The old H1 run still shows green in the run history, but H2 is now the head; if GitHub has a test merge commit with a status, that merge revision may be the evaluated target instead. Neither the visible H1 success nor a local test command supplies the required result for the target revision. The next operation is to run or repair the eligible check for the revision shown in the pull request box, then inspect that result.
Now suppose verify on H2 is green, but a second automation installed in the repository reported it. The selected CI App remains the expected source, so the matching text does not establish the branch condition. The repair is to restore the correct app's reporting path or correct a mistaken source setting through the normal rule review. Simply creating another success with the same name from a different token does not prove the intended CI ran. Likewise, a successful job named build on H2 cannot satisfy a rule still requiring verify; the context is missing even though the overall workflow may look healthy.
| Observed evidence | Why the required result is unresolved | Next operation and proof |
|---|---|---|
| verify is green on H1; current target is H2 | Result is attached to an older revision | Run the eligible check on the evaluated H2 or test merge commit; inspect the matching result |
| verify is green on H2 from Other App | Rule expects CI App as the source | Restore the expected app reporter; confirm source in the check and rule |
| build is green on H2; verify is required | Required context verify is absent | Inspect names and event filters; require verify to report on the target revision |
| PR verify is green on H2; queue targets M1 | Queue needs evidence for its merge group revision | Trigger merge_group verification and inspect verify on M1 |
These examples are diagnostic, not instructions to manufacture a passing badge. Preserve the branch rule while you repair the check producer. If an app was deliberately replaced, review the new source, its permissions, and the rule change as one migration. If a job was renamed, update the workflow and protection setting deliberately, and confirm the new context appears on a fresh pull request. Do not treat an administrator bypass, a missing source restriction, or a manual merge as equivalent to a completed verification run.
Sources: About protected branches — GitHub Docs · Troubleshooting required status checks — GitHub Docs
Check the revision created by merge queue
Merge queue changes the revision being tested. GitHub creates a merge group that combines the pull request with the latest target branch and, where applicable, other queued changes. A successful pull request check on H2 remains useful history, but the queue needs required results for its merge group revision M1. This is why a pull request can look ready before entering the queue and then fail to merge: the required context may never be reported on the new group. The queue is testing a different integration candidate, not replaying the old head result.
For GitHub Actions, required workflows need the merge_group event when the repository uses merge queue. GitHub exposes the group ref and SHA to that event. A workflow limited to pull_request and push can miss the queue candidate entirely, leaving the expected check absent on M1. Add the event to the appropriate workflow, ensure the same required job reports on the group revision, and verify the result in a real queue attempt. External CI has the same evidence obligation: it must report the required context for the group revision through its supported integration rather than assuming the pull request head result transfers.
# Partial workflow trigger; review the actual jobs and permissions.
on:
pull_request:
merge_group:
types: [checks_requested]The fragment only shows event coverage. It does not specify a runner, check name, build command, or deployment behavior. Keep the required job's identity stable across pull request and merge group events, and examine which revision the resulting check actually names. If the group fails, first distinguish a missing result from a test failure. A missing result points to triggering or reporting; a genuine failing result points to code or integration. Both should block until the stated policy has evidence on the queue candidate.
Sources: About protected branches — GitHub Docs · Troubleshooting required status checks — GitHub Docs · Events that trigger workflows — GitHub Docs
Make the rule auditable before relying on it
An effective branch protection review begins with the repository's actual rule: required context names, expected GitHub App sources, and whether merge queue is enabled. Compare that inventory with the names and sources emitted by workflows on a fresh pull request. Run one update to the pull request so the team sees how the evaluated revision changes, and if merge queue is enabled, run one candidate through it. The proof is the status box and check records for each target revision, not a screenshot of a previous green workflow.
Keep a short incident ledger when the gate stalls: pull request head, any displayed test merge commit, queue group SHA if present, required context, configured source, observed source, observed conclusion, and the event that should have created the check. A missing field is an unresolved question, not a reason to mark the candidate safe. This record lets a team distinguish stale evidence from an absent job, an app mismatch, a workflow filter, and a real test failure without changing protection rules speculatively.
When a required check is truly broken, repair the reporting path and rerun on the target revision. If the policy itself is wrong, change it through the repository's normal review with a clear explanation of the new required evidence. A bypass can move code past an unresolved gate, but it cannot create the missing proof. Keeping the context, source, and revision together makes the merge decision explainable to the next person who reads it and makes later failures much faster to diagnose.
Sources: About protected branches — GitHub Docs · Troubleshooting required status checks — GitHub Docs · Events that trigger workflows — GitHub Docs
Sources and verification
- About protected branches — GitHub Docs
GitHub documents required check conclusions, expected GitHub App sources, strict versus loose checks, merge queue behavior, and ambiguous duplicate job names. Verified .
- Troubleshooting required status checks — GitHub Docs
GitHub explains latest-head and test-merge-commit evaluation, skipped workflow pending states, check and status name collisions, source mismatches, and merge queue event requirements. Verified .
- Events that trigger workflows — GitHub Docs
GitHub documents the merge_group checks_requested event and its group ref and SHA for workflow execution. Verified .