The declarative Jenkinsfile
pipeline, agent, stages, steps.
Jenkins has two pipeline syntaxes. Scripted pipeline is full Groovy — powerful but easy to turn into unmaintainable code. Declarative pipeline is a structured, opinionated format with a fixed skeleton, and it is what you should write: it is readable, validates before it runs, and covers almost everything a normal project needs. Every declarative Jenkinsfile has the same top-level shape.
pipeline {agent { label 'linux' } // where the whole pipeline runsoptions { timeout(time: 20, unit: 'MINUTES') }stages {stage('Build') {steps { sh 'make build' }}stage('Test') {steps { sh 'make test' }}}post {always { junit 'reports/*.xml' } // run whatever the resultfailure { echo 'build failed' }}}
The required pieces
Three blocks are the backbone. agent declares where the pipeline runs — a labelled agent, a Docker image, or any. stages contains one or more stage blocks, each a named phase that shows as a box in the UI. Inside each stage, steps lists the actual commands (sh to run a shell command is the workhorse). Everything else — options, environment, post — is optional structure around that core.
The agent can also be a container, which is the clean way to get a reproducible build environment: Jenkins pulls the image, runs your steps inside it, and throws it away. No "install Node on the agent" drift — the toolchain is pinned in the pipeline.
pipeline {agent { docker { image 'node:22-alpine' } } // build inside a pinned containerstages {stage('Install') { steps { sh 'npm ci' } }stage('Test') { steps { sh 'npm test' } }}}