Skip to main content

Quality6 min read

Quality gates that protect releases without slowing teams down

Which automated quality gates to put in a CI/CD pipeline, in what order, and how to keep them fast, trustworthy and genuinely useful.

Verolution EngineeringPublished

A quality gate is a check that a change must pass before it moves to the next stage of delivery: merging, deploying to a test environment or releasing to production. Each good gate turns a category of failure into something the pipeline catches minutes after a change is made, rather than something a customer discovers later.

Bad gates do the opposite. When checks are slow, noisy or flaky, teams learn to rerun them until they pass or to find ways around them. The aim is a small set of checks that are fast, deterministic and trusted, ordered so that feedback arrives as early as possible.

What a gate is, and what it is not

A gate has three parts: a check, a threshold and a consequence. The check measures something, such as test results, new vulnerabilities or bundle size. The threshold defines pass or fail. The consequence is that a failing change does not proceed. A check without a consequence is a report: useful, but not a gate.

That distinction gives you a safe way to introduce new checks. Run a check in advisory mode while you learn how often it is right, and make it blocking once it is reliable. Gate definitions belong in version control, reviewed like any other change, with a named owner.

Choose gates by risk

Start from the failures that would hurt most, not from a list of tools. For a payments platform, that might be an incorrect calculation or a broken reconciliation. For a consumer web app, a slow or inaccessible sign-up flow. For an internal tool, perhaps little more than regressions in core workflows. For each risk, ask which check would catch it earliest and most cheaply.

Every gate also has a cost in pipeline time, maintenance and false positives. Add one when it addresses a real risk, and review the ones that no longer earn their cost.

Order checks for fast feedback

Put the cheapest checks first, so a typo never waits behind a long browser test suite:

  1. Locally, at commit time: formatting and fast lint rules, so trivial issues never reach CI.
  2. First CI stage: format check, lint, type check and unit tests, run in parallel and reporting within a few minutes.
  3. Second stage: build the deployable artifact once, then run integration tests against real dependencies such as databases and queues in containers, contract tests between services, and security scans.
  4. Third stage: deploy that same artifact to a staging or ephemeral environment and run a small set of end-to-end smoke tests on critical journeys, such as signing in and completing the core transaction.
  5. After release: monitor errors, latency and real-user performance, ideally behind a gradual rollout.

Keep the end-to-end suite small. Browser tests are slow and brittle; their job is to prove the pieces are wired together, and business logic is cheaper to test at lower levels. Promote the same artifact through every stage, so what you tested is what you ship. And watch total pipeline time: when the pipeline is slow, people batch changes, and bigger batches make every release riskier.

Treat flaky tests as defects with a deadline

A flaky test passes and fails on the same code. The damage is not the wasted rerun; it is that the team learns red builds are noise. The policy that works is zero tolerance:

  1. Quarantine a test as soon as it is identified as flaky: take it out of the blocking suite, but keep running it and recording results.
  2. Assign an owner and a deadline, tracked like any other defect.
  3. Fix it or delete it by that deadline. A test left in quarantine indefinitely protects nothing and still costs CI time.

Be careful with automatic retries. They turn pipelines green while hiding race conditions that can also occur in production, so if you use them, report every test that needed one. Common causes of flakiness include fixed sleeps instead of waiting for a condition, state shared between tests, dependence on test order or external services, time zones and dates, and uncontrolled randomness.

Set performance budgets that reflect real users

Performance tends to erode one small addition at a time, so it needs a budget that makes each regression visible in the change that causes it. For web applications, Google's Core Web Vitals (opens in a new tab) define "good" at the 75th percentile of page loads:

MetricWhat it measuresGood
Largest Contentful Paint (LCP)Loading of the main content2.5 s or less
Interaction to Next Paint (INP)Responsiveness to user input200 ms or less
Cumulative Layout Shift (CLS)Visual stability0.1 or less

Field data from the Chrome UX Report or your own real-user monitoring is the measure that counts. Lab tools such as Lighthouse are diagnostics: repeatable enough to catch regressions in CI, but unable to reproduce the range of devices and networks your users have. A standard Lighthouse page-load run cannot measure INP at all, because nobody interacts with the page; Total Blocking Time is the usual lab proxy. A practical setup gates on lab budgets in CI (bundle size, lab LCP, Total Blocking Time, compared with the main branch) and tracks field data on a dashboard. For APIs, the equivalent is a latency budget for key endpoints under a representative load test.

Security and accessibility gates

Two security checks belong in almost every pipeline. A dependency audit fails the build on known high or critical vulnerabilities that have a fix available and routes the rest to the backlog with target dates; it should also run on a schedule, because new advisories appear for unchanged code. Secret scanning blocks credentials from being committed, and any secret that slips through is rotated, not just deleted. Gate on what each change introduces, and track the existing backlog separately so it shrinks without blocking unrelated work.

For accessibility, automated tools such as axe can run inside component and end-to-end tests and fail the build on issues like missing form labels, images without alternative text or invalid ARIA attributes. They are cheap and worth having, but they catch only a portion of accessibility problems. Focus order, meaningful alternative text, clear error messages and a usable screen reader experience need human judgment, so make keyboard and screen reader testing part of the release checklist for significant interface changes, measured against the WCAG level you have committed to, typically AA.

Produce release evidence automatically

Every release should carry a record of how you know it is safe: commit and build identifiers, which gates ran and their results, test and scan summaries, performance and accessibility results, any overrides with their justification, and who approved the release. Generate it in the pipeline and attach it to the release rather than assembling it by hand. It answers what changed and how it was verified, for stakeholders, auditors and whoever is investigating an incident.

Keep the gates honest

There are legitimate reasons to override a gate: a confirmed false positive, an urgent fix, a vulnerability with no available patch and no exposure in how you use the component. Overrides should be possible but never silent. Each needs a recorded reason, a named approver, an expiry date and a follow-up ticket, and the list should be reviewed regularly, for example in retrospectives.

If the same gate is overridden again and again, either the gate is wrong or the team is under pressure that will surface somewhere else. Fix the cause rather than normalizing the bypass. A gate that the team routinely works around protects nothing.

Where to start

  1. List your top release risks and map each to the earliest check that would catch it.
  2. Reorder the pipeline so formatting, lint, type checks and unit tests report within minutes.
  3. Find your flakiest tests and quarantine them, each with an owner and a deadline.
  4. Make dependency auditing, secret scanning and automated accessibility checks blocking for newly introduced issues.
  5. Set performance budgets from current field data and check them on every change.

Our quality assurance practice helps teams design pipelines like this around their own risks.

More engineering notes

Start a conversation

Let’s engineer what’s next.

Tell us what you’re building, fixing or exploring. We’ll help you find a sensible first step — whether that’s a focused review, a prototype or a full engagement.