Jenkins pipelines are defined as code in a Jenkinsfile, checked into the repo alongside the application. The
declarative syntax below covers what you'll touch in almost every pipeline.
Minimal Pipeline
pipeline {
agent any
stages {
stage('Build') {
steps {
sh 'npm ci && npm run build'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
}
}Declarative vs. scripted
Declarative pipeline (the pipeline { } block above) is the standard, structured syntax — predictable, easier to
lint, and what most teams should default to. Scripted pipeline (node { }, raw Groovy) is more flexible but
harder to review — reach for it only when declarative syntax genuinely can't express what you need.
Agents
pipeline {
agent { label 'linux && docker' }
// or per-stage:
stages {
stage('Build') {
agent { docker { image 'node:20' } }
steps { sh 'npm ci' }
}
}
}agent none
Set agent none at the pipeline level when every stage declares its own agent — it stops Jenkins reserving an
executor for the top level that no step actually uses.
Environment Variables
pipeline {
agent any
environment {
NODE_ENV = 'production'
API_URL = "${params.API_URL ?: 'https://api.example.com'}"
}
stages {
stage('Build') {
steps { sh 'echo $NODE_ENV' }
}
}
}Credentials
stage('Deploy') {
steps {
withCredentials([usernamePassword(
credentialsId: 'registry-creds',
usernameVariable: 'REG_USER',
passwordVariable: 'REG_PASS'
)]) {
sh 'docker login -u $REG_USER -p $REG_PASS registry.example.com'
}
}
}Never echo a credential
withCredentials masks the bound variables in console output automatically — but only for exact matches. Don't
concatenate or transform a secret before printing it (e.g. echo "token=$REG_PASS" inside a larger string built
another way), since masking can't catch what it doesn't recognize verbatim.
Parallel Stages
stage('Test') {
parallel {
stage('Unit') {
steps { sh 'npm run test:unit' }
}
stage('Integration') {
steps { sh 'npm run test:integration' }
}
}
}Conditional Stages
stage('Deploy') {
when {
branch 'main'
}
steps {
sh './deploy.sh'
}
}Post Actions
pipeline {
agent any
stages { /* ... */ }
post {
always { junit 'reports/**/*.xml' }
success { slackSend(message: 'Build passed') }
failure { slackSend(message: 'Build failed') }
}
}Artifacts
archiveArtifacts artifacts: 'dist/**', fingerprint: trueSaves build output as a Jenkins artifact, downloadable from the build page and fingerprinted for traceability across later builds.
Useful CLI Commands
jenkins-cli build JOB_NAMETriggers a job build from the command line, useful for scripting outside the Jenkins UI.
jenkins-cli console JOB_NAMEStreams a running or completed build's console output.
Troubleshooting
Common pipeline failures
Stuck in queue — no executor matches the requested agent label; check node labels against the pipeline.
Credential not found — the credentialsId doesn't exist in the scope the pipeline runs in (global vs.
folder-scoped credentials). Workspace conflicts — two builds of the same job sharing a workspace path; enable
disableConcurrentBuilds() or use a per-build workspace.