Quality Gates in Jenkins
Learn how to make your pipeline say no to weak code before it reaches customers: what a gate is, which checks belong in it, how to set fair thresholds, and how to keep gates fast, trusted and hard to game.
Every team wants good software, but wanting is not the same as enforcing. Left to habit, quality slips quietly. A few tests are skipped to meet a deadline, a warning is ignored because it looks harmless, a risky library sneaks in during a busy week. None of these choices looks serious on its own. Together they turn a healthy project into one that nobody dares to touch.
A quality gate is the automatic answer to this problem. It is a checkpoint in your pipeline with clear rules, written down in advance. If the code meets the rules, the pipeline moves on. If not, the pipeline stops or raises a warning, and the team hears about it while the change is still fresh in everyone’s mind.
This guide starts from zero. Every new word is explained when it first appears, everyday pictures make ideas stick, and later chapters cover what experienced engineers care about: which checks to include, how to choose thresholds that people accept, how to wait for a scanning service without wasting machines, how to handle exceptions, and how to stop people from gaming the numbers.
1What Is a Quality Gate?
A plain-language first look before any details.
Jenkins is a free, open-source automation server that builds, tests and delivers software. Its work is written as a pipeline, a recipe stored in a text file called the Jenkinsfile. A pipeline is split into stages, such as Build, Test and Deploy, and each stage contains steps, the single actions Jenkins performs.
A quality gate is a set of pass-or-fail rules checked at a chosen point in the pipeline. The rules are about the health of the code and the build: do the tests pass, is enough of the new code covered by tests, are there serious security problems, is the code becoming messier? The gate collects the answers and gives one verdict: open or closed.
Think of the inspection before a car leaves the factory. Brakes are tested, lights are checked, paint is examined. Each check has a standard. If any important check fails, the car does not roll out to the showroom; it goes back to be fixed. Nobody argues about it on the day, because the standards were agreed long before. A quality gate is that inspection line for software.
What a gate is not
A gate is not a single tool. Jenkins does not have one button called “quality gate.” It is an idea that you build from several pieces: test reports, coverage numbers, code analysis results, security scans and sometimes a human sign-off. Some tools, such as SonarQube, offer their own gate feature that Jenkins can wait for. Others, such as the Jenkins plugins for warnings and coverage, let you set thresholds directly inside the pipeline.
A gate is only as good as its rules and its speed. Weak rules give false comfort. Slow gates make people look for ways around them. This guide is mostly about getting those two things right.
Teams in banking, retail, healthcare and open-source projects all use gates. The exact checks differ, but the shape is always the same: measure, compare with an agreed standard, decide, and tell people clearly why.
2Why Quality Gates Exist
The problem they solve and how the idea grew.
The problem: quality decays quietly
Without gates, quality depends on memory and goodwill. Reviewers are busy. Deadlines press. A reviewer may not notice that a change removed a test or added a risky dependency. Each small compromise is reasonable in the moment, yet the total effect is a slow decline that nobody chose and nobody can point to.
There is also a cost of timing. A defect found while writing the code costs minutes to fix. The same defect found in testing costs hours. Found by customers, it can cost days of work, lost trust and sometimes real money. Gates move the discovery earlier, to the moment when fixing is cheapest.
Quality at the end
A separate test phase ran weeks after coding. Problems came back late and expensive.
Continuous integration
Servers such as Jenkins built and tested every change automatically, giving fast feedback on the basics.
Code analysis tools
Tools measured code health, coverage and security, but their reports were often only read, not enforced.
Gates
Teams began turning those measurements into rules that decide whether the pipeline may continue.
Gates at merge time
Code hosts learned to require passing checks before a change could be merged, making gates impossible to skip by accident.
3Core Concepts You Need First
A handful of small ideas that make everything else easy.
Metric
A metric is a number that describes something about the code or the build, such as the percentage of lines covered by tests or the count of serious security issues.
Threshold
A threshold is the line a metric must not cross, such as “coverage must be at least 80 percent.” A gate is a group of thresholds.
Condition
A condition is one rule inside a gate, pairing a metric with a threshold. A gate usually contains several conditions and closes if any important one fails.
Build result
Every run finishes with a result: success, unstable, failure or aborted. Gates use these results to signal their verdict. Failure is a hard stop. Unstable is a yellow warning that lets the build continue but draws attention.
Static analysis and coverage
Static analysis examines code without running it, looking for bugs, risky patterns and messy structure. Code coverage measures how much of the code is executed by the tests. Both produce metrics that gates like to use.
New code and overall code
New code means the lines changed recently, such as in the current pull request. Overall code means everything. This difference is the secret to gates that people accept, and Chapter 13 gives it a whole section.
| Term | Simple meaning | Example |
|---|---|---|
| Metric | A number about the code | Coverage of 84 percent |
| Threshold | The line the number must respect | At least 80 percent |
| Condition | One metric plus one threshold | Coverage on new code at least 80 percent |
| Gate | A group of conditions with one verdict | Pass or fail |
| Hard gate | Failure stops the pipeline | Security issues block release |
| Soft gate | Warning only | Small drop in coverage turns the build yellow |
4Architecture and Components
Which parts of a Jenkins setup work together to make a gate.
A quality gate is not one component. It is a small system. Jenkins runs the checks and collects the numbers. Tools produce the measurements. A decision point compares them with the rules. The result flows back to the people and to the code host.
flowchart LR
DEV["Developer pushes code"] --> SCM["Source Control Server"]
SCM -->|"webhook"| CTRL["Jenkins Controller"]
CTRL --> AGT["Build Agent"]
AGT --> T["Test runner"]
AGT --> COV["Coverage tool"]
AGT --> SA["Static analysis and security scanners"]
T --> RES["Reports"]
COV --> RES
SA --> SQ["Analysis server such as SonarQube"]
RES --> GATE{"Quality gate"}
SQ --> GATE
GATE -->|"Pass"| NEXT["Next stage or deploy"]
GATE -->|"Fail"| STOP["Stop and report"]
GATE -->|"Warn"| YEL["Continue as unstable"]
GATE --> STAT["Status back to pull request"]
Read the diagram from left to right. A push starts a build on an agent. The agent runs tests, measures coverage and runs scanners. Some results stay in Jenkins as reports. Others go to an analysis server, which stores history and computes its own verdict. The gate collects everything, and the verdict controls the pipeline and is reported back to the pull request, so reviewers see a green tick or a red cross without opening Jenkins.
Jenkins controller
Schedules the build, stores the reports and applies gate rules that live inside the pipeline.
Agents
Run the tests and scanners where the code is built.
Reporting plugins
Read test, coverage and warning reports and can enforce thresholds directly.
Analysis server
A service such as SonarQube that keeps history, defines a gate and tells Jenkins the result.
Security scanners
Look for vulnerable libraries, exposed secrets and risky container images.
Status reporting
Sends the verdict to the pull request so it can block merging.
5Kinds of Quality Gates
A gate can check many different things. Here are the common families.
Tests pass
The most basic gate: no failing tests, and no unexpectedly skipped ones.
Coverage
Enough of the code, especially new code, is exercised by tests.
Code quality
Limits on bugs, code smells, duplication and complexity found by static analysis.
Security
No serious vulnerabilities in your code, in libraries you use, or in container images.
Licenses
No libraries with licenses your company cannot accept.
Performance
Response times or resource use must stay within agreed limits.
Manual approval
A named person confirms before a risky step, such as releasing to production.
Post-deploy health
After deployment, health checks and error rates decide whether to continue or roll back.
Automatic and human gates
Most gates are automatic, because machines are consistent and fast. Some decisions need human judgment, such as approving a release to customers. Good pipelines use both: machines check everything that has a rule, and humans decide the few things that need judgment.
Start small. A gate with three well-chosen conditions that everyone respects is worth far more than a gate with thirty conditions that everyone overrides.
Example: a modest first gate
A team’s first gate has only three conditions: all tests pass, coverage on new code is at least 70 percent, and no new serious security issues. Within two months the team trusts it, and only then do they add duplication and complexity limits.
6Hard Gates and Soft Gates
Failure stops the run. Unstable warns but continues. Choosing between them is a policy decision.
When a condition is not met, Jenkins can react in two ways. It can mark the build as failed, which stops later stages, or as unstable, shown in yellow, which lets the pipeline continue but signals a problem. The choice expresses how serious you consider the condition.
| Type | Result on breach | Effect | Best used for |
|---|---|---|---|
| Hard gate | Failure | Later stages are skipped and merging can be blocked | Failing tests, serious security issues, must-have coverage on new code |
| Soft gate | Unstable | Pipeline continues, team is warned | Minor code smells, small drops in a trend, new checks still being introduced |
| Advisory only | Success with a message | Nothing stops; information is recorded | Experimental checks before deciding on a threshold |
flowchart TD
M["Metric measured"] --> C{"Threshold met?"}
C -->|"Yes"| P["Pass: continue"]
C -->|"No"| S{"How serious?"}
S -->|"Critical"| H["Hard gate: mark failure and stop"]
S -->|"Moderate"| W["Soft gate: mark unstable and continue"]
S -->|"Experimental"| A["Advisory: record and continue"]
H --> N["Notify team with reason"]
W --> N
A common growth path
When you introduce a new check, begin as advisory, so people see the numbers without being blocked. After a few weeks, make it soft, so breaches are visible in yellow. When the team has cleared the backlog and trusts the rule, make it hard. This gentle path avoids the anger that comes when a brand-new gate suddenly blocks everyone.
Yellow builds that nobody looks at are the same as no gate at all. If you use soft gates, make sure someone owns the yellow, for example with a chat alert and a rule that unstable builds cannot be released.
7Where Gates Sit: Shift Left
The earlier a problem is caught, the cheaper it is to fix.
The phrase shift left means moving checks earlier in the pipeline, toward the developer’s first push. Imagine the pipeline as a line from left to right, ending at production. Cheap, fast checks belong on the left. Slow, expensive checks belong on the right, where fewer changes reach them.
flowchart LR
G1["Gate 1: build, lint, unit tests"] --> G2["Gate 2: coverage and static analysis"]
G2 --> G3["Gate 3: dependency and security scan"]
G3 --> G4["Gate 4: integration and performance tests"]
G4 --> G5["Gate 5: manual approval"]
G5 --> G6["Gate 6: post-deploy health checks"]
G1 -. "seconds" .-> T1["Fast feedback"]
G4 -. "minutes" .-> T2["Slower feedback"]
G6 -. "after release" .-> T3["Slowest, safest"]
Gate on the developer’s first push
Build, format checks and unit tests run within a few minutes. Failures here are the cheapest to fix.
Gate on the pull request
Coverage and static analysis on the new code, plus dependency scans. Reviewers see results before reading the code.
Gate on the main branch
Slower tests run: integration, end-to-end and performance checks on the merged result.
Gate before production
Security sign-off, approvals and change records for the most sensitive step.
Gate after release
Health checks and error rates confirm the release is working, with automatic rollback if not.
Placing a check too far right wastes effort: a slow test that fails after twenty minutes could have been replaced by a quick check that fails after two. Placing a slow check too far left wastes everyone’s time: a fifteen-minute scan on every push makes developers wait. Balance speed against value.
8Test Result Gates
The foundation: do the tests pass?
The simplest gate is that every test must pass. Jenkins helps through the junit step, which reads standard test result files and publishes pass and fail counts, trends and details. When tests fail, the step marks the run unstable by default, which is the yellow state, and the test command itself may mark it failed if it returns an error.
Making the gate strict
- Treat failed tests as a hard stop for anything beyond experimental branches. Yellow builds can slip into releases unless you check the result.
- Watch skipped tests. A gate that counts only failures can be satisfied by skipping everything. Report the number skipped and set a limit on it.
- Watch missing results. If the test step produced no result files at all, that is a failure, not a pass. Many pipelines silently pass because “no failures” was recorded when nothing ran.
- Watch test count. A sudden drop in the number of tests is a warning sign even if all pass.
| Check | What it catches | Suggested reaction |
|---|---|---|
| Any failed test | Broken behavior | Hard gate |
| Too many skipped tests | Tests quietly turned off | Soft gate, then hard |
| No test results found | Test stage never ran or reports missing | Hard gate |
| Big drop in test count | Deleted or disabled tests | Soft gate with alert |
| Test duration jump | Performance problem or hanging test | Soft gate with alert |
Illustration: the silent pass
A team moves their test folder. The test command finds nothing to run, prints “0 tests,” and exits successfully. For three weeks the pipeline is green while no tests run at all. A single extra condition, “at least one test result must exist,” would have caught it on day one.
9Coverage Gates
How much of the code do the tests actually exercise?
Code coverage measures the share of code that runs while tests execute. The common flavors are line coverage, the percentage of lines executed, and branch coverage, the percentage of decision paths, such as both sides of an if, taken. Coverage tools produce a report, and Jenkins coverage plugins read it and can enforce thresholds directly in the pipeline.
What coverage tells you, and what it does not
It tells you
- Which code is never touched by any test.
- Whether new code arrives with tests.
- Whether coverage is rising or falling over time.
It does not tell you
- Whether the tests check anything meaningful.
- Whether important behavior is covered rather than easy code.
- Whether the tests would catch a real bug.
Setting a useful coverage gate
- Gate the coverage of new code, not the whole project, so legacy code does not block every change.
- Use a level people can reach, commonly somewhere between 70 and 85 percent for new code, and adjust for the kind of software.
- Consider both line and branch coverage. Branch coverage is harder to fake.
- Add a “no drop” rule, so overall coverage cannot fall below the current level, which protects against slow decay.
A hundred percent coverage target is rarely wise. The last few percent often cover trivial or hard-to-test code, and chasing them leads to shallow tests written only to raise the number.
10Static Analysis Gates
Letting tools read the code and report problems.
Static analysis tools examine code without running it. They find likely bugs, unsafe patterns, style violations and needless complexity. The Jenkins Warnings plugin family collects reports from many such tools and shows them together, with trends and details. Its recording step can also apply quality gates: you say, for example, “fail the build if there are any new high-severity issues,” or “mark it unstable if the total exceeds fifty.”
Two ways to count
| Counting method | What it counts | Effect on teams |
|---|---|---|
| Total | All issues in the whole code base | Legacy problems block everyone; frustrating for old projects |
| New | Only issues introduced compared with a reference build | Fair; people fix what they touch, and the debt stops growing |
| Delta | Change in the count | Good for preventing regression |
Severity and reaction
Not all issues are equal. Most gates weigh them by severity. A common arrangement is to fail on any new high-severity issue, mark unstable on many new medium ones, and merely record low-severity findings. This keeps the gate focused on what matters.
Serious problems
Likely bugs and security risks. Hard gate, no exceptions without approval.
Notable problems
Risky patterns and maintainability concerns. Soft gate above a limit.
Style and minor issues
Record and trend. Usually not worth blocking anyone.
Illustration: the ratchet by counting only new issues
A ten-year-old project has 4,200 existing warnings. Failing on the total would block every change forever. The team gates on new issues only. Over a year the total drifts down to 3,100 because developers clean up areas they touch, and nothing new is added. Nobody had to schedule a cleanup project.
11SonarQube Quality Gates in Jenkins
The most widely used gate service and how Jenkins works with it.
SonarQube is a code quality server. It stores the results of code analysis over time and lets administrators define a quality gate: a set of conditions on metrics such as coverage, duplication, bugs, vulnerabilities and code smells. Each time code is analyzed, SonarQube compares the results with the gate and produces a status, typically passed or failed.
A typical default gate
The default gate that many installations start with checks the new code only. Commonly it requires that coverage on new code is at least 80 percent, duplicated lines on new code are 3 percent or fewer, the reliability, security and maintainability ratings for new code are the best grade, and security hotspots on new code have all been reviewed. Exact defaults vary by version and edition, so check your own server.
How Jenkins and SonarQube cooperate
flowchart TD
A["Pipeline stage: analysis step runs scanner"] --> B["Scanner sends results to SonarQube server"]
B --> C["SonarQube processes results in the background"]
C --> D["SonarQube evaluates quality gate"]
D --> E["SonarQube sends webhook to Jenkins"]
E --> F["Pipeline wait step receives status"]
F --> G{"Status"}
G -->|"Passed"| H["Pipeline continues"]
G -->|"Failed"| I["Pipeline stops"]
Connect the servers
Install the SonarQube scanner plugin in Jenkins and register the SonarQube server with a token stored as a credential.
Run the analysis
A stage wraps the scanner in the withSonarQubeEnv step, which supplies the server address and token to the scanner.
Processing
SonarQube receives the results and processes them in the background. This takes seconds to minutes.
Webhook
When processing finishes, SonarQube calls a web address on Jenkins with the gate result. This webhook must be configured on the SonarQube side.
Wait and decide
The waitForQualityGate step in the pipeline receives the result and either continues or aborts the pipeline.
The gate lives in SonarQube, not in the Jenkinsfile. That means a quality team can adjust thresholds centrally, and every project that uses the gate follows the change without editing any pipeline.
12Waiting for the Gate Properly
The wait step is simple, but three details make the difference between a smooth gate and a stuck pipeline.
Detail one: the webhook must exist
The waitForQualityGate step normally depends on the webhook from SonarQube. If the webhook is missing or points to the wrong address, Jenkins never hears the answer and waits, and waits. This is the most common gate problem of all. When a gate stage seems stuck, check the webhook delivery history on the SonarQube side first.
Detail two: always set a timeout
Wrap the wait in a timeout so a lost message cannot hold a build forever. A few minutes is usually enough for normal projects, longer for very large ones. When the timeout expires, the build ends as aborted, and your post section can report clearly what happened.
Detail three: do not hold an agent
Just as with the input step, waiting inside a machine block ties up an executor, a work slot on an agent, while doing nothing. Since the scanner has already sent its results, the wait can happen outside any agent, on the controller, which is nearly free. In practice this means placing the wait in its own stage with no agent, or after the agent block has ended.
flowchart LR
subgraph BAD["Wasteful"]
B1["Agent allocated"] --> B2["Scan"]
B2 --> B3["Wait for gate while agent held"]
B3 --> B4["Next steps"]
end
subgraph GOOD["Efficient"]
G1["Agent allocated"] --> G2["Scan"]
G2 --> G3["Agent released"]
G3 --> G4["Wait for gate with timeout, no agent"]
G4 --> G5["Agent allocated again for next steps"]
end
| Symptom | Likely cause | Fix |
|---|---|---|
| Wait never finishes | Webhook missing or blocked | Configure the webhook and check network access |
| Wait finishes but pipeline ignores failure | Abort option not set, and result not checked | Abort the pipeline on a failed gate, or check the returned status |
| Agents idle while builds wait | Wait placed inside an agent block | Move the wait outside the agent |
| Wrong project result received | Multiple analyses in one pipeline | Wait after each analysis, in the right order |
By default, a failed gate does not automatically stop the pipeline unless the wait step is told to abort on failure. Always decide explicitly what happens on a failed gate, and test it once on purpose.
13New Code Versus Overall Code
The idea that makes gates fair, and therefore accepted.
Imagine joining a project with thousands of existing problems. If a gate demanded that all of them be fixed before anything can ship, the gate would be closed forever, and everyone would soon find a way to switch it off. A better approach is to apply strict rules only to the code that people are changing now. This is often called Clean as You Code.
Think of a shared kitchen that is already messy. Demanding that the first person to cook must clean the entire room is unfair, and they will refuse. Demanding that everyone leaves the kitchen at least as clean as they found it is fair, and over time the whole kitchen becomes clean.
What counts as new
A reference point decides what is “new”: for a pull request, the target branch; for a main branch, the previous release or a period such as the last thirty days. Every tool lets you choose the definition. Pick one that matches your release rhythm, and explain it to the team.
| Approach | Advantage | Risk |
|---|---|---|
| Gate only new code | Fair; old debt does not block progress; quality improves steadily | Old debt can stay forever if nobody schedules it |
| Gate overall code | Forces cleanup of everything | Blocks work; invites overrides and switching off |
| New code strict, overall as a trend | Fair and visible | Needs a dashboard someone actually watches |
Example: the inherited project
A team inherits an old service with 31 percent coverage. They set the gate to require 80 percent on new code, and a “no drop” rule for the overall figure. After six months, the overall coverage has climbed to 46 percent without a single cleanup project, simply because every change arrived well tested.
14Security Gates
Stopping known dangers before they ship.
Security gates check for problems that would be costly if released. They come in several flavors, each scanning a different part of what you ship.
Static security analysis
Looks for risky patterns in your own code, such as unsafe handling of user input.
Dependency scanning
Checks the third-party libraries you use against lists of known vulnerabilities. A Jenkins plugin for such a tool can fail the build above a severity threshold.
Secret detection
Looks for passwords and tokens accidentally committed to the code.
Container image scanning
Checks the packaged application image for vulnerable components.
License checks
Ensures libraries carry licenses your organization allows.
Infrastructure checks
Scans deployment and cloud settings for unsafe configurations.
Choosing thresholds for security
A sensible pattern is to block on critical and high-severity findings that have a known fix, warn on medium ones, and record the rest. Blocking on everything, including findings without any available fix, teaches people to ignore the gate. Blocking on nothing wastes the scan.
Vulnerability lists change every day. A build that passed yesterday can fail today with no code change. Run dependency scans on a schedule as well as on each build, so newly published problems in old releases are noticed.
Illustration: the surprise failure
A team’s main branch build has been green for a month. On Tuesday morning it turns red with no new commits, because a widely used library was reported to have a serious flaw overnight. The scheduled scan caught it before the next release. Without a regular scan, the flaw would have shipped on Friday.
15Performance and Reliability Gates
Checking that the software is not just correct, but fast and steady enough.
Some quality problems show up only under load: pages that become slow, memory that grows, requests that fail one time in a hundred. Performance gates run load tests against a test environment and compare results with limits, such as “ninety-fifth percentile response time under 400 milliseconds” or “error rate below 0.5 percent.” A Jenkins plugin for performance testing can read the results and mark the build accordingly.
Making performance gates trustworthy
- Compare with a baseline, the last good run, rather than a fixed number, so normal variation does not cause alarms.
- Allow a tolerance. A five percent slowdown may be noise; a thirty percent slowdown is not.
- Use a stable test environment. Results from shared, noisy machines vary wildly and destroy trust.
- Keep the test short enough to be practical, and run heavier tests on a schedule instead of on every change.
Reliability gates after release
The last gate does not sit before release, but after it. After a deployment, health checks, error rates and key business numbers are watched for a few minutes. If they cross limits, the pipeline rolls back automatically. This turns the real world into the final test.
flowchart TD
D["Deploy new version to small share of users"] --> W["Watch error rate and response time"]
W --> Q{"Within limits?"}
Q -->|"Yes"| E["Expand to all users"]
Q -->|"No"| R["Roll back automatically"]
R --> N["Notify team and open incident"]
E --> F["Mark release healthy"]
16Manual Gates
When a human decision belongs in the pipeline.
Some decisions cannot be reduced to a rule. Is this the right day to release? Has the product owner confirmed the new screen? Has the security team reviewed this unusual change? For these, Jenkins offers the input step, which pauses the pipeline and waits for an authorized person to click Proceed or Abort.
Rules for a good manual gate
- Automate first. Present the human with evidence: test results, scan summaries, the change list. Do not ask them to hunt for it.
- Restrict who may approve to a named group, and record who did.
- Set a timeout, so forgotten builds do not pile up.
- Wait outside any agent, so no work slot is held.
- Use it sparingly. Too many manual gates turn approvers into rubber stamps.
The strongest pipelines combine both kinds: automatic gates that catch everything a rule can catch, and one well-designed manual gate before the riskiest step, so human attention goes where it truly matters.
Example: the release checklist gate
Before production, the pipeline pauses with a message listing test totals, coverage on new code, the security scan summary and the change list. A release manager, and only members of that group, can approve. The approver’s name is recorded in the log, giving auditors a clear trail.
17Gates per Branch Type
Different builds deserve different gates.
In a Multibranch Pipeline, Jenkins builds pull requests, main branches, release branches and tags from the same pipeline file. One gate for everything is either too weak for releases or too slow for pull requests. The better approach is to layer the gates, using the branch, change request and tag conditions to decide which stages run.
flowchart TD
B["Build starts"] --> T{"Build type"}
T -->|"Pull request"| PR["Fast gate: unit tests, new-code coverage, static analysis"]
T -->|"Main branch"| MB["Full gate: everything above plus integration tests and security scans"]
T -->|"Release branch"| RB["Release gate: full gate plus performance tests"]
T -->|"Tag"| TG["Publish gate: approval and signing checks"]
PR --> ST["Status on pull request"]
MB --> DEP["Deploy to staging"]
RB --> APP["Manual approval"]
TG --> PUB["Publish release"]
| Build type | Goal | Gate contents | Time budget |
|---|---|---|---|
| Pull request | Fast feedback for the author and reviewers | Build, unit tests, new-code coverage and analysis, quick dependency check | Under ten minutes |
| Main branch | Confirm the merged result | Everything above, integration tests, full security scans | Under thirty minutes |
| Release branch | Prove readiness | Full gate, performance tests, license checks | As needed |
| Tag | Publish a specific version | Signing, approval, final checks | As needed |
The time budget matters. If a pull request gate takes forty minutes, developers will batch their changes into large, risky pull requests to avoid waiting, which defeats the purpose. Aim for feedback in the time it takes to get a coffee.
18Enforcing at Merge Time
A gate that can be skipped is only a suggestion.
A gate inside Jenkins stops the pipeline, but it does not by itself stop someone from merging a pull request. To make the gate binding, connect it to the code host. Jenkins reports the verdict of each build as a status check on the pull request. The code host can then be told, through branch protection rules, that the pull request cannot be merged unless specific checks have passed.
Report
The branch source plugin sends the build’s result to the pull request as a named check.
Require
An administrator marks that check as required for the protected branch, such as main.
Block
The merge button stays disabled until the check turns green.
Guard the rules
Only a small group may change branch protection or bypass it, and each bypass is logged.
Administrators can often bypass protection rules. Decide who may do so, and require a written reason. If everyone can bypass, the gate is theater.
Illustration: the green tick that means something
A team moves from “we look at the checks before merging” to “the merge button is disabled unless the gate passes.” In the first month, seventeen pull requests that would previously have been merged with failing checks are fixed first. The number of production incidents linked to untested changes drops sharply.
19Choosing Thresholds
Numbers that are too soft mean nothing. Numbers that are too hard get ignored.
A threshold is a promise the team makes to itself. To be believed, it must be achievable, meaningful and stable. Picking numbers out of the air, or copying another company’s numbers, usually goes badly.
Measure the present
Record the current values for several weeks. You cannot set a fair line without knowing where you stand.
Start at “do not get worse”
The first gate is a no-regression rule: the metric may not fall below its present level.
Ratchet up slowly
Raise the line a little every quarter, always after the team has comfortably met the current one.
Review regularly
Check whether each condition still catches real problems. Retire conditions that never fire or always fire.
flowchart LR
A["Measure current level"] --> B["Set gate at current level"]
B --> C["Team meets it comfortably"]
C --> D["Raise threshold a little"]
D --> E{"Team still meets it?"}
E -->|"Yes"| C
E -->|"No"| F["Hold the line and investigate"]
F --> C
Signs that a threshold is wrong
- Always red: people stop believing it and look for overrides.
- Always green with a huge margin: it is not protecting anything.
- Frequently overridden: the rule may be unfair, or the exceptions may be the real rule.
- Debated in every review: the team does not agree on why it exists. Write down the reason.
20Overrides, Waivers and Emergency Paths
Real life has exceptions. Plan for them, or people will invent their own.
Sooner or later a gate blocks something that should go out. A critical fix must be released tonight and one non-essential condition is failing. If no official exception route exists, people bypass the whole system: they disable the check, edit the pipeline, or ask an administrator to force the merge. A planned exception path is far safer than an improvised one.
flowchart TD
F["Gate fails"] --> Q{"Genuine problem?"}
Q -->|"Yes"| FIX["Fix the code and rerun"]
Q -->|"No, false positive"| MARK["Mark finding as accepted in the tool with reason"]
Q -->|"Real but urgent"| WAIV["Request waiver from named approvers"]
WAIV --> REC["Record reason, owner and expiry date"]
REC --> REL["Release with waiver"]
REL --> FU["Follow-up task created and tracked"]
Named approvers
Only a small, known group may grant a waiver. It should never be the author of the change alone.
Written reason
Every waiver states why, in plain words, and links to the ticket.
Expiry date
Waivers end. A finding accepted “for now” must come back for review on a set date.
Visible count
Track how many waivers exist and how old they are. A growing pile means the gate or the process needs a rethink.
Define in advance what a hotfix gate looks like: a shorter, faster gate that keeps the essentials, such as tests and security blockers, and skips slow extras. When an emergency comes, nobody needs to invent rules under pressure.
21Flaky Tests, False Positives and Gaming
Three forces that quietly destroy trust in a gate.
Flaky tests
A flaky test sometimes passes and sometimes fails on identical code. It might depend on timing, on shared data, or on an outside service. Flaky tests are poison for gates: a red build that means nothing teaches everyone to rerun until green. Track flaky tests, fix or quarantine them quickly, and keep the count visible. A retry step can hide the problem for a while, but retries should be reported, never silent.
False positives
Analysis tools sometimes report a problem that is not real. If there is no easy, recorded way to mark a finding as accepted, developers will grow resentful, and rightly so. Give them a route, keep it accountable, and periodically review accepted findings.
Gaming the numbers
When a number becomes a target, people learn to hit the number instead of the goal. Coverage is the classic case: tests that run code but assert nothing raise coverage without catching bugs. Code smells are “fixed” by moving them around. This is often called Goodhart’s law: a measure that becomes a target stops being a good measure.
| Gaming behavior | What it looks like | Counter-measure |
|---|---|---|
| Empty tests | Coverage rises, bug detection does not | Code review of tests; mutation testing on critical code |
| Excluding files | Difficult code moved to excluded folders | Review changes to exclusion settings |
| Splitting changes | Big change cut into pieces to dodge limits | Gate the overall trend as well as each change |
| Lowering the threshold | Rules loosened after a failure | Changes to gates need review and an announced reason |
| Marking everything accepted | Findings closed without thought | Sample accepted findings regularly |
Culture matters more than tooling. Explain why each rule exists, celebrate real quality improvements, and treat gate breaches as information, not as personal failures.
22Protecting the Gates Themselves
A gate that anyone can quietly edit is not a gate.
Gate rules live in several places: the Jenkinsfile, the settings of the analysis server, plugin configuration and the code host’s branch protection. Each is a place where someone could weaken the standard, on purpose or by accident.
Protect the Jenkinsfile
Anyone who can change the pipeline can remove a gate. Require review for changes and protect important branches.
Central gate definitions
Keep shared gates in the analysis server or in a shared pipeline library controlled by a small group, so individual projects cannot quietly weaken them.
Control administrators
Limit who can change gate definitions, tokens and branch protection, and log every change.
Untrusted code
For pull requests from forks, run the trusted Jenkinsfile from the target branch, so an outsider cannot edit the gate inside their own request.
Guard the tokens
The token that lets Jenkins talk to the analysis server is a credential. Keep it in the credentials store, scoped narrowly.
Illustration: the quietly commented-out stage
A developer under deadline pressure comments out the quality stage in a branch’s pipeline file, planning to restore it later. The pull request is large and reviewers focus on the code. The stage stays disabled for two months. A branch rule that requires the standard gate stage to exist, checked automatically in the shared library, would have prevented it.
23Monitoring, Logging, Metrics and Speed
How to know that your gates are healthy, fair and fast.
Make every verdict explain itself
A gate that says only “failed” wastes everyone’s time. Each failure should say which condition broke, what the value was, what the limit was, and where to click to see details. Send this summary to the pull request and to chat, with a link to the report. A good message answers the developer’s first three questions before they ask.
Metrics worth watching
| Metric | Why it matters | Warning sign |
|---|---|---|
| Gate pass rate on first try | Shows how often developers meet the standard unaided | Very low means rules are unfair; near 100 percent may mean the rules are too weak |
| Time to gate verdict | Slow gates change behavior | Pull request gates over ten minutes |
| Override and waiver count | Measures how often rules are bypassed | Rising numbers or old waivers |
| Flaky test rate | Predicts distrust | Builds routinely rerun to get green |
| Escaped defects | Bugs found after release show what the gate misses | Defects clustered in areas with weak conditions |
| Trend of overall coverage and issues | Shows long-term health | Flat or falling despite passing gates |
| Queue wait time for gate stages | Shows whether agents are enough | Long waits before scans |
Keeping gates fast
- Run independent checks in parallel. Tests, static analysis and dependency scans rarely depend on each other.
- Cache dependencies between builds so scans do not download the world each time.
- Analyze incrementally where the tool supports it, looking only at changed files for pull requests.
- Fail fast. Put the cheapest, most likely-to-fail checks first, so a broken build stops in seconds.
- Move slow checks off the pull request, to main or to a schedule.
Those numbers are only an illustration, but the effect is real. With 30 pushes a day across a team, saving twenty-eight minutes each gives back well over thirteen hours of waiting every single day.
24Useful Design Patterns
Proven ways of arranging quality gates.
Pattern 1: Fast gate for pull requests, full gate for main
Keep pull requests quick with unit tests and new-code checks. Run the slower integration, security and performance checks after merge, or on a schedule.
Pattern 2: New code strict, overall code trending
Apply hard rules to what changed, and display overall health on a dashboard. Old debt shrinks steadily without blocking anyone.
Pattern 3: Advisory, soft, hard
Introduce each new check in three phases. Advisory first to gather data, soft to build awareness, hard when the team is ready.
Pattern 4: Central gate in a shared library
Package the standard quality stage as a function in a shared library. Projects call it with a few settings, and a small owning team keeps the rules consistent everywhere.
Pattern 5: Ratchet
The gate never allows a metric to fall below its current level, and the level is raised on a schedule. Quality can only go up.
Pattern 6: Gate result as a status check
Report the verdict to the code host and mark it as required, so the merge button itself enforces the standard.
Pattern 7: Scheduled re-scan
Re-run dependency and image scans nightly against released versions, so new vulnerabilities in old code are found quickly.
25Anti-patterns to Avoid
Habits that look fine at first and hurt later.
What people do
They gate the total of all issues in an old code base.
Why it hurts
The gate is red from the first day. People find ways to switch it off, and quality gets worse, not better.
Better approach
Gate new code strictly, and track overall health as a trend.
What people do
They add thirty conditions at once and turn them all to hard.
Why it hurts
Everything fails, the team revolts, and the gate is weakened or removed.
Better approach
Start with a few conditions, introduce others as advisory then soft then hard.
What people do
They run a forty-minute gate on every push.
Why it hurts
Developers stop pushing small changes, wait in idle time, and produce larger, riskier pull requests.
Better approach
Keep the pull request gate under ten minutes, and move slow checks later.
What people do
They wait for the analysis server without a timeout, inside an agent, with no webhook check.
Why it hurts
Builds hang, executors sit idle and nobody knows why.
Better approach
Confirm the webhook, wrap the wait in a timeout and release the agent first.
What people do
They let unstable builds through as if they were green.
Why it hurts
Yellow is ignored, and the soft gate becomes a decoration.
Better approach
Alert on yellow, and block releases from unstable builds.
What people do
They allow anyone to lower thresholds or skip the quality stage.
Why it hurts
The standard erodes quietly under deadline pressure.
Better approach
Keep gate definitions central, require review for changes and log every exception.
What people do
They rerun flaky builds until green without recording it.
Why it hurts
A red build stops meaning anything, and real failures hide among the noise.
Better approach
Track flaky tests, quarantine and fix them, and report every retry.
26Best Practices and Common Mistakes
A checklist to apply to any Jenkins setup today.
Do this
- Start with a few clear conditions that everyone understands.
- Gate new code strictly and track overall code as a trend.
- Keep pull request gates under ten minutes.
- Run independent checks in parallel and cache dependencies.
- Wrap waits in timeouts and release agents first.
- Report verdicts to the pull request and require them for merging.
- Record waivers with owner, reason and expiry.
- Scan dependencies again on a schedule.
- Review each threshold regularly.
Avoid this
- Copying numbers from other companies.
- Gating the whole legacy code base at once.
- Treating a missing report as a pass.
- Chasing a hundred percent coverage.
- Letting yellow builds go to production.
- Letting anyone edit or skip the gate.
- Rerunning flaky tests silently.
- Adding manual approvals at every step.
- Blocking on findings that have no available fix.
Mistakes people make when they are new
Forgetting to test the failure path. Many teams build a gate and never see it fail. Break something on purpose on a test branch and confirm the pipeline stops and the message is clear.
Trusting an empty result. “No issues found” can mean the scanner never ran. Require evidence that the tool actually analyzed something.
Mixing up new and overall. A gate on overall coverage feels strict but blocks the wrong people. Decide deliberately which you are measuring.
Ignoring the wait step’s abort setting. Without it, a failed SonarQube verdict may not stop the pipeline.
Never revisiting the rules. A gate written three years ago for a different code base may protect nothing today.
27Advantages, Disadvantages and Trade-offs
An honest look at what quality gates do well and where they strain.
Advantages
- Consistent standards that do not depend on who is reviewing.
- Problems found early, when they are cheapest to fix.
- Objective evidence for audits and reviews.
- Steady improvement when new code must meet the bar.
- Less argument in reviews about basic matters.
- Central control of standards across many projects.
Disadvantages
- Can slow feedback if checks are heavy.
- Metrics can be gamed.
- False positives and flaky tests erode trust.
- Rules need upkeep and honest review.
- Rigid rules may block sensible exceptions.
- Setup and tuning take real effort.
Trade-offs to weigh
| Choice | Benefit | Cost |
|---|---|---|
| Strict thresholds | Higher standard | More friction and more pressure to game |
| Lenient thresholds | Smooth flow | Weaker protection |
| Many checks on every push | Thorough | Slow feedback |
| Few checks early, more later | Fast feedback and thorough release checks | Some problems found later than ideal |
| Gate in the analysis server | Central control, shared by all projects | Dependence on another service and its webhook |
| Gate in the Jenkinsfile | Self-contained and visible in code | Rules spread across many files |
| Hard failure | Clear stop | Blocks urgent work unless an exception path exists |
| Soft warning | Flexible | Easy to ignore |
There is no universally right answer. The right settings depend on the risk of your software, the maturity of your team and the speed you need. Choose on purpose and write down why.
28Real-World and Industry Examples
How the ideas look in the kinds of organizations that run Jenkins at scale.
A bank with change control
Regulated banks combine automatic gates for tests, security scans and license checks with a manual approval before production. Every result and every approver is recorded, giving auditors a clear trail for each release.
An online retailer with frequent releases
Retail teams release many times a day, so their pull request gates are fast and focused. Heavier performance tests run on the main branch, and a post-deploy gate watches checkout error rates and rolls back automatically if they rise.
An open-source project
Public projects use required status checks so that no pull request merges without passing tests and analysis. Fork pull requests run the trusted pipeline definition, and maintainers approve anything sensitive.
A healthcare software vendor
Software that affects patient care needs strong evidence of testing. Gates require high coverage on critical modules, block on any serious vulnerability, and produce a report attached to each release for compliance reviews.
A mobile app team
Mobile builds are slow and expensive. The team gates pull requests with quick unit tests and static analysis, runs device tests only on release branches, and uses a manual gate before submitting to the app stores.
A small startup
A team of six sets three conditions: all tests pass, coverage on new code at least 70 percent, no new serious security findings. They add the merge requirement, and raise the coverage line by five points each quarter.
29A Complete Story: From Push to Release
Follow one imaginary team through a change.
A team owns a booking service. Their Multibranch Pipeline uses a shared library that provides the standard quality gate. The analysis server holds the gate definition, and the code host requires the Jenkins check before any merge to main.
Push and pull request
Maya opens a pull request for a new discount feature. Jenkins starts the fast gate.
Fast checks in parallel
Unit tests, coverage measurement and the static analysis scan run side by side and finish in seven minutes.
Gate verdict
The analysis server reports that coverage on new code is 62 percent, below the 80 percent condition. The pipeline stops and a message names the condition, the value and the limit, with a link to the uncovered lines.
Fix
Maya adds tests for the missing branches and pushes again. Coverage on new code becomes 86 percent, and the gate passes.
Merge
The required check is green, so the merge button unlocks. A reviewer approves and merges.
Main branch gate
On main, the full gate adds integration tests and a dependency scan. Everything passes.
Approval and release
The pipeline pauses for a release manager, showing the evidence. After approval, the release goes to a small share of users, and the post-deploy gate watches error rates.
Nightly scan
Weeks later, a nightly scan finds a newly reported flaw in a library. The team is alerted and patches it before the next release.
At no point did anyone need to remember a rule. The gates carried the standard, gave clear feedback, and kept a record. The humans spent their attention on the parts that needed judgment.
30Troubleshooting Guide
Symptoms, likely causes and calm fixes.
| Symptom | Likely cause | What to do |
|---|---|---|
| Gate stage waits forever | SonarQube webhook missing or blocked | Configure it and check delivery history; add a timeout |
| Gate failed but pipeline continued | Wait step not set to abort, and result unchecked | Enable abort on failure or check the returned status |
| Build green but no tests ran | Test files moved or report path wrong | Require at least one test result |
| Build yellow and released anyway | Unstable treated as success | Block release on unstable, alert the team |
| Coverage shows zero | Coverage report not found or wrong format | Check the report path and tool settings |
| Random red builds | Flaky tests | Identify, quarantine and fix; report retries |
| New failure with no code change | Newly published vulnerability or updated rules | Read the finding; patch or accept with a waiver |
| Gate too slow | Serial checks, no caching | Parallelize, cache, analyze incrementally |
| Merge allowed despite red check | Check not marked required, or bypass used | Require the check and audit bypasses |
| Different results locally and in Jenkins | Different tool versions or settings | Pin versions and share configuration |
A calm debugging routine
- Read the verdict message for the failing condition, value and limit.
- Open the report behind that number, not just the summary.
- Check that the tool really ran, using the log of the stage.
- Check the reference point used for new code.
- Reproduce on a test branch and change one thing at a time.
31Plain-English Glossary
Every important word in this guide in one place.
| Word | Simple meaning |
|---|---|
| Jenkins | A free automation server that builds, tests and delivers software. |
| Pipeline | A written recipe of the steps Jenkins follows. |
| Quality gate | A set of pass-or-fail rules checked at a point in the pipeline. |
| Metric | A number describing the code or build. |
| Threshold | The line a metric must respect. |
| Condition | One metric paired with one threshold. |
| Hard gate | A gate whose failure stops the pipeline. |
| Soft gate | A gate that warns but lets the pipeline continue. |
| Unstable | A yellow result meaning the build finished with problems. |
| Code coverage | The share of code executed by tests. |
| Static analysis | Examining code without running it to find problems. |
| SonarQube | A server that stores code quality results and defines gates. |
| Webhook | An automatic message from one system to another. |
| Clean as You Code | Applying strict rules only to new and changed code. |
| Shift left | Moving checks earlier in the pipeline. |
| Flaky test | A test that sometimes passes and sometimes fails on the same code. |
| Waiver | A recorded, time-limited exception to a gate. |
| Status check | A build result shown on a pull request that can block merging. |
| Goodhart’s law | A measure that becomes a target stops being a good measure. |
32Frequently Asked Questions
Short answers to the questions that come up most often.
33Summary and Key Takeaways
The whole story in a few lines.
A quality gate turns good intentions into automatic decisions. It measures the health of a change, compares it with written rules, and lets the pipeline continue, warn or stop. In Jenkins you assemble gates from test reports, coverage and analysis plugins, an analysis server such as SonarQube, security scans and a manual approval step, then make them binding through required status checks. The gates that last are fair, because they focus on new code; fast, because feedback arrives within minutes; explained, because every failure says why; protected, because nobody can quietly weaken them; and humane, because real exceptions have a recorded path.
Key Takeaways
- A gate is rules plus a verdict. Metrics and thresholds combine into conditions, and the gate passes, warns or stops the pipeline.
- Gate new code, trend the rest. Strict rules on changed code improve quality steadily without blocking work on legacy debt.
- Start small and phase in. Introduce each check as advisory, then soft, then hard, and raise thresholds gradually with a ratchet.
- Keep feedback fast. Pull request gates under about ten minutes, with checks run in parallel, cached and layered by branch type.
- Wait properly. Confirm the webhook, wrap waits in a timeout, release the agent first, and decide explicitly what a failed gate does.
- Make it binding and accountable. Require the check at merge time, protect gate definitions, and record every waiver with a reason and an expiry date.
- Guard trust. Fix flaky tests, provide a route for false positives, watch for gaming, and review thresholds regularly.