Code Review in CI/CD: How to Build a Pipeline That Catches Defects
Code Review in CI/CD: How to Build a Pipeline That Catches Defects

Code review in a CI/CD pipeline works when each layer does the job it is best at. Fast deterministic checks run first and block the merge on failure. Deeper analysis of the change and its surrounding code runs next. Human reviewers then spend their attention on design, intent and maintainability, which no tool can judge. Wire those layers to a required status check on a protected branch and review stops being a courtesy and becomes a gate.
This guide covers how to order the layers, how to enforce them on GitHub, why pull request size matters more than any tool choice, and how to tell whether your pipeline is catching real defects or only producing noise.
TL;DR
- Run cheap checks (lint, unit tests) before expensive ones (security scans, deeper review), and make the important ones required status checks so they cannot be skipped.
- Keep pull requests small. Review speed and quality depend on PR size more than on tooling.
- Automation covers syntax, style and known vulnerability patterns. Humans keep design, readability and intent.
- Judge any automated reviewer by confirmed defects found, not by comment volume. Findings should come with evidence you can reproduce.
- End each review with a score or verdict that your merge gate can read.
Table of Contents
- What code review means inside a pipeline
- Order the stages by cost
- Enforce it: required status checks on GitHub
- Keep pull requests small
- What automation should not try to replace
- Why diff-only review misses defects
- Our perspective: a verdict you can verify
- Where an evidence-based review step fits
- Measure whether the pipeline works
- A rollout plan for the next two weeks
- FAQ
- Sources
What code review means inside a pipeline
A CI/CD pipeline is a scripted sequence of jobs that runs whenever code changes, usually on a push or a pull request. Code review inside that pipeline is the set of judgments the pipeline makes about a change before it reaches the main branch. Some of those judgments are mechanical: does it build, do tests pass, does a linter complain. Others require reading the change in the context of the code around it: who calls this function, what contract does this interface promise, what happens to a dependency when this value is null.
There are three kinds of reviewer in a mature setup:
- Deterministic checks. Linters, type checkers, unit tests, dependency audits, secret scanners. Same input, same output.
- Analytical review. Static analysis and AI-assisted review that reason about the change and the repository around it.
- Human review. A teammate who understands the product and the team’s conventions.
The common mistake is to treat these as substitutes. They are layers. The MinimumCD practice guide puts the division plainly: automated tools catch syntax errors, style violations and known vulnerability patterns, while human review exists for what automation cannot evaluate, such as cognitive load and maintainability.
Order the stages by cost
The cheapest check should answer first. A developer who pushes a typo should learn about it in seconds, not after a twenty-minute security scan has finished.
A CI/CD standards guide from Libre DevOps recommends exactly this ordering: lightweight checks such as linting and unit tests ahead of heavier SAST and SCA scans, configured as fail-closed status checks so routine violations never need a human to point them out.
A practical ordering looks like this:
| Stage | Typical duration | What it catches | Blocks merge? |
|---|---|---|---|
| Format and lint | Seconds | Style, obvious errors | Yes |
| Type check and build | Under a few minutes | Contract breaks, compile errors | Yes |
| Unit and integration tests | Minutes | Regressions in known behavior | Yes |
| Dependency and secret scan | Minutes | Known vulnerable packages, leaked credentials | Yes |
| Analytical PR review | Minutes | Defects that depend on repository context | Yes, on a threshold |
| Human review | Hours to a day | Design, intent, readability | Yes, by approval rule |
The human stage sits last on purpose. When every earlier stage is green, the reviewer opens a pull request that already compiles, passes tests and has no style debate left in it. The conversation can be about the change itself.
Enforce it: required status checks on GitHub
A check that can be ignored is a suggestion. On GitHub, the mechanism that turns a check into a gate is the required status check on a protected branch. GitHub’s status checks reference describes how teams mark builds, test suites and security scans as required so a pull request cannot merge until they pass.
One detail from the same documentation deserves attention: a skipped status check reports as success by default and does not block the merge. If a workflow uses path filters or conditions that can skip a job, the required check can pass without ever running. The fix is to design the workflow so the required job always runs, and to verify the setting by opening a deliberately failing pull request once.
If a required check never reports, merges stall instead. GitHub maintains a page on troubleshooting required status checks that covers the common causes, such as name mismatches between the workflow job and the branch rule.
A minimal protected-branch policy for most teams:
- Require pull requests before merging, with at least one human approval.
- Require the lint, test and security jobs as status checks.
- Require the analytical review check, so its verdict is part of the merge decision.
- Require branches to be up to date before merging, so checks ran against the code that will actually land.
We go through the setup step by step in our guide to GitHub CI quality gates built on PR review evidence.
Keep pull requests small
Tooling gets the attention, but size is the strongest lever. LinearB’s analysis of elite teams concludes that reducing PR size is concrete, measurable and achievable, and that elite teams keep changes under roughly 225 lines. Small pull requests are picked up faster, which lowers cycle time and improves the other DORA metrics.
The reasoning is simple. A reviewer, human or automated, has finite attention. A 40-line change gets read line by line. A 1,200-line change gets skimmed, and the defect hides in the part nobody read.
To make small PRs the default:
- Split refactors from behavior changes. A rename across forty files should not share a pull request with a logic fix.
- Ship behind feature flags so incomplete work can merge safely.
- Add a soft CI warning when a PR exceeds your size threshold, and a human conversation when it does.
Small changes also make delivery steadier. A 2025 meta-analysis of CI/CD performance through DORA metrics reports that elite teams typically hold a change failure rate of 0 to 5% and restore service in under an hour, which shows that deployment speed and stability can coexist when CI/CD practice is mature.
What automation should not try to replace
Pull request review is the industry default, but it has a cost. As InfoQ’s piece on co-creation patterns describes, the reviewer becomes available only after the author has moved on to something else, and the resulting delayed back-and-forth drags out every change. Some elite teams respond by shifting toward pairing or mob programming, which turns review into a real-time activity.
That is a legitimate option, and it does not conflict with an automated gate. Even a pair that wrote the code together benefits from a pipeline that checks the result against the rest of the repository. The pipeline is the one reviewer that never gets tired and never assumes someone else already looked.
None of this makes the human reviewer redundant. A tool can count branches and flag a missing null check. It cannot tell you whether the abstraction will confuse the next engineer, or whether the feature solves the right problem. Keep humans on those questions, and take every question a machine can answer off their plate.
The same logic applies well beyond application code. Teams that treat generated assets, such as hreflang tags regenerated on every change, as a pipeline step rather than a manual chore remove a whole category of review comments before a person ever sees the diff.

Why diff-only review misses defects
Most automated review reads the diff and nothing else. That is fast, and it catches a lot. It also has a blind spot: many serious defects are not visible in the changed lines. A function signature changes safely in isolation but breaks three callers in other files. A new code path passes user input to a sink that lives in a module the diff never touches. An interface is implemented correctly but violates an assumption a dependency relies on.
Catching those requires reading the repository context: callers, interfaces and dependencies. It also requires tracing how data moves through the change, which is the subject of our write-up on data flow analysis for faster PR scans.

Our perspective: a verdict you can verify
We build Veridical, so we have a stake in how this question is answered, and we will state it directly. The problem with most automated review is not that it finds too little. It is that it publishes too much without proof. A bot that leaves thirty comments per pull request trains a team to scroll past all of them, including the one that mattered. Then the gate gets quietly lowered, usually by the people who were most enthusiastic when it launched.
Our position is that a finding earns its place in a review only when it is tied to concrete evidence and a reproducible check. If we cannot show you the code path, the caller or the failing condition, the finding does not ship. You do not have to take that on faith: the evidence is inline, next to the line it concerns.
The second part of our position is measurement. Recall and precision are a tightrope. Push recall up and false positives bury the signal. Push precision up and real defects slip through. That is why we express review quality as a quantitative score grounded in F1 projections over real defects, not as a count of comments. Every review ends with a calibrated advisory score, and because it is a number, you can wire it into a merge gate the same way you wire in a test result. For the reasoning behind that, see why code quality metrics need verified PR reviews.
Third, we review the repository around the change, not only the diff, because the defects that cause data leaks and performance regressions tend to live in the interaction between files.
The pipeline you want is one where the final automated check says something a senior engineer would sign, and shows its work.
— Łukasz
Where an evidence-based review step fits
In the ordering above, Veridical occupies the analytical review row. It runs on the pull request after the fast deterministic checks, reads the change with repository context, and publishes a summary, inline findings with evidence, and an advisory score. Your branch protection rule can then require that check.
Plans, as listed on our pricing page: the Launch tier has no published price, Standard is 39 USD per month and Pro is 69 USD per month. Deterministic checks, review history and repair workflows are included on paid plans. Open-source maintainers do not need a budget conversation: we offer free AI code reviews for open source projects. If you handle private repositories, read how we treat your code on the security and data handling page before you install anything. To see the product itself, start with AI code review for GitHub.
Measure whether the pipeline works
A pipeline that always passes is as suspicious as one that always fails. Track a few numbers over a quarter:
- Change failure rate. The share of deployments that cause an incident or rollback. Elite teams in the DORA research sit at 0 to 5%.
- Time from PR open to first review. If it is days, your queue is the bottleneck, and PR size is the first suspect.
- Confirmed defects caught before merge. Count findings a human accepted as real, not comments posted.
- Escaped defects. Bugs found in production that the pipeline could have caught. Each one is a prompt to add a check or tune a threshold.
- Override rate. How often people merge past a failing gate. A rising rate means the gate has lost credibility.
When a check has a high override rate and a low confirmed-defect rate, it is costing you speed for nothing. Tune it or remove it. Teams that want a structured way to try process changes can follow our two-week plan for testing research-backed code review practices.
A rollout plan for the next two weeks
- Day 1. Turn on branch protection for the main branch with a required human approval.
- Days 2 to 3. Add lint, type check and unit tests as required checks. Confirm each blocks a deliberately broken PR.
- Days 4 to 5. Add dependency and secret scanning. Fail closed on high severity only, to start.
- Week 2. Add the analytical review step in advisory mode. Compare its findings with what your human reviewers caught on the same pull requests.
- End of week 2. Promote it to a required check at a score threshold your team agrees on. Review override rate monthly.
If you want the review process itself laid out, six steps to evidence-based GitHub pull request reviews covers it in detail. Language-specific teams may also find our Python PR security checks a useful starting set.
FAQ
What is code review in CI/CD?
It is the set of automated and human judgments applied to a change inside the pipeline before it merges. Deterministic checks and analytical review run on every pull request, and a human approves what remains. The result is enforced through required status checks rather than convention.
Should automated review replace human reviewers?
No. Automation handles syntax, style, known vulnerability patterns and repository-wide consistency. Humans handle design, maintainability and whether the change solves the right problem. The best use of automation is to clear everything mechanical so human time goes to those questions.
How do I make a code review check block merges on GitHub?
Add the check’s job name as a required status check in the branch protection rule for your main branch. Make sure the job always runs, because a skipped check reports as success and does not block. Then test the rule with a pull request that is meant to fail.
How long should CI code review take?
Fast checks should answer in seconds to a few minutes, with heavier scans after them. If the whole pipeline is slow, split it so cheap checks fail first and heavy ones run only when those pass. Keeping pull requests small shortens every stage.
Sources
- Code Review, MinimumCD Practice Guide
- CI/CD Standards, Libre DevOps
- Status checks reference, GitHub Docs
- Troubleshooting required status checks, GitHub Docs
- The Workflow Metrics That Make Elite Dev Teams, LinearB
- Redefining Speed and Stability: A Meta Analysis of CI/CD Performance through DORA Metrics
- From Async Code Reviews to Co-Creation Patterns, InfoQ