Pipelines declare a timeout
jenkins/job-timeout-set@v1
Every declarative pipeline declares how long it may run, either on the pipeline itself or on every stage, so a hung build is stopped instead of holding an executor.
| Id | jenkins/job-timeout-set |
| Version | v1 |
| Category | jenkins |
| Default severity | info |
| Interpreter | python3 |
| Timeout | 30 seconds |
| Violations tolerated | 0 |
| Collects | jenkins |
Collectors
This guardrail doesn't gather anything itself. It relies on the collectors below, which the CLI runs once per build before any check, and reads what they found from GUARDRAIL_FACTS. If a collector collects nothing, this guardrail is skipped, not failed.
| Collector | Gathers | Inputs it is given |
|---|---|---|
jenkins | The Jenkinsfiles the repository carries, read in Jenkins's own vocabulary: whether each is a declarative pipeline or a scripted one, the agent it asks for, the stages in the order they are declared with the steps inside them, the timeouts its options blocks declare, the shared libraries it loads and how tightly each is pinned, and the credential ids it reaches for. A Jenkinsfile is Groovy rather than a declaration, so it is read by pattern and scanned says so. Names and ids only, never a credential, an environment value or a parameter value. | jenkinsfiles |
The inputs above are this guardrail's own inputs, passed straight through to the collector. Setting one in buildnote.json changes what is collected, and two guardrails configured the same way share a single collection.
Configuration
{
"guardrails": {
"failOn": "error",
"checks": [
{
"use": "jenkins/job-timeout-set@v1",
"severity": "info",
"with": {
"jenkinsfiles": "Jenkinsfile,Jenkinsfile.*,*.Jenkinsfile",
"maxMinutes": "60"
},
"exemptions": []
}
]
}
}Inputs
| Input | Description | Default | Environment variable |
|---|---|---|---|
jenkinsfiles | Comma separated globs naming the Jenkinsfiles to read. | Jenkinsfile,Jenkinsfile.*,*.Jenkinsfile | GUARDRAIL_INPUT_JENKINSFILES |
maxMinutes | Longest timeout accepted. A stage that declares more than this is treated as having no timeout. | 60 | GUARDRAIL_INPUT_MAXMINUTES |
How to fix
Declare a timeout on the pipeline, where it covers every stage:
pipeline {
options {
timeout(time: 30, unit: 'MINUTES')
}
}Jenkins has no default timeout. A hung build holds its executor until someone notices and aborts it by hand, and on a controller with only a few executors, one stuck stage can stop the whole queue. An options block on a stage covers that stage and every stage nested inside it, so either the pipeline declares a timeout or each of its stages does.
Scripted pipelines are skipped, not reported: there, timeout is a step in ordinary Groovy, so not finding one doesn't prove it isn't there.
More in jenkins
jenkins/shared-library-pinned. Every@Libraryannotation andlibrarystep names a tag or a commit SHA instead of a branch, so the library code a build runs can't change underneath it.