A Jenkinsfile is a Groovy-like, text-based script that defines and automates the stages of your CI/CD pipeline. In this guide, we’ll explore the core declarative directives and components you need to build robust, maintainable pipelines.
Typical Pipeline Structure
A declarative Jenkinsfile usually follows this pattern:
Source: Checkout code from GitHub, Bitbucket, etc.
Build: Compile, build, and package your application.
Test: Execute unit tests, integration tests, and other suites.
Deploy: Push artifacts to staging or production environments.
Here’s a minimal example illustrating these concepts:
pipeline {
agent any
stages {
stage( 'Build' ) {
agent { docker { image 'maven:3.6.3-jdk-8' } }
steps {
sh 'mvn clean package'
}
}
stage( 'Unit Testing' ) {
steps {
junit 'target/surefire-reports/*.xml'
}
}
stage( 'Deploy' ) {
when { branch 'main' }
steps {
sh './deploy.sh'
}
}
}
}
Key Declarative Directives
Directive Purpose Example pipelineRoot block to define a declarative pipeline pipeline { … }agentSelects where to execute (node, Docker, label) agent anyagent { docker { image … }}environmentDefines global or per-stage environment variables environment { VAR = 'value' }stagesGroups one or more stage blocks stages { stage('Build') { … } }stageA named phase in the pipeline stage('Test') { … }stepsSequence of commands or plugin invocations steps { sh 'echo Hello' }postPost-build actions based on build result post { success { … } failure { … } }whenConditional execution of a stage when { branch 'main' }scriptEmbed arbitrary Groovy code steps { script { … } }
environment Directive
Set environment variables globally or override them per-stage:
pipeline {
agent any
environment {
GLOBAL_VAR = 'foo'
}
stages {
stage( 'Show Global' ) {
steps {
sh 'echo $GLOBAL_VAR' // prints foo
}
}
stage( 'Override Var' ) {
environment { GLOBAL_VAR = 'bar' }
steps {
sh 'echo $GLOBAL_VAR' // prints bar
}
}
}
}
post Directive
Define actions to run after the entire pipeline finishes, based on the outcome:
pipeline {
agent any
stages { /* … */ }
post {
success { echo 'Pipeline succeeded!' }
failure { echo 'Pipeline failed!' }
always { cleanWs() }
}
}
script Directive
Use script blocks to include complex Groovy logic:
pipeline {
agent any
stages {
stage( 'Process Files' ) {
steps {
script {
def files = [ 'file1.txt' , 'file2.txt' ]
files . each { file ->
sh "echo Processing ${ file } "
}
}
}
}
}
}
Use script sparingly. Most tasks can be handled with declarative steps or existing plugins.
when Directive
Control stage execution based on conditions (branches, environment, tags):
pipeline {
agent any
stages {
stage( 'Deploy to Production' ) {
when { branch 'main' }
steps {
sh './deploy.sh'
}
}
}
}
credentials Directive
Inject Jenkins-managed credentials securely:
pipeline {
agent any
stages {
stage( 'Use Credentials' ) {
steps {
withCredentials([usernamePassword(
credentialsId : 'myCredentials' ,
usernameVariable : 'USER' ,
passwordVariable : 'PASS'
)]) {
sh 'echo "Deploying as $USER"'
}
}
}
}
}
Never print credentials or secrets to the console. Always use the Jenkins credentials store and the appropriate binding methods.
Pause the pipeline for manual approval:
pipeline {
agent any
stages {
stage( 'Approval' ) {
steps {
input message : 'Proceed with deployment?' , ok : 'Deploy'
}
}
}
}
parameters Directive
Allow customization of pipeline runs:
pipeline {
agent any
parameters {
string( name : 'ENV' , defaultValue : 'dev' , description : 'Deployment environment' )
booleanParam( name : 'RUN_TESTS' , defaultValue : true , description : 'Execute unit tests?' )
}
stages {
stage( 'Show Params' ) {
steps {
echo "Environment: ${ params.ENV } "
echo "Run tests: ${ params.RUN_TESTS } "
}
}
}
}
stash / unstash Directives
Share files between stages or nodes:
pipeline {
agent any
stages {
stage( 'Build' ) {
steps {
sh 'mvn package'
stash name : 'app' , includes : 'target/*.jar'
}
}
stage( 'Archive' ) {
steps {
unstash 'app'
archiveArtifacts artifacts : 'target/*.jar'
}
}
}
}
parallel Directive
Run multiple branches in parallel to speed up the pipeline:
pipeline {
agent any
stages {
stage( 'Parallel Tasks' ) {
parallel {
stage( 'Unit Tests' ) {
steps { sh 'mvn test' }
}
stage( 'Security Scan' ) {
steps { sh './scan.sh' }
}
}
}
stage( 'Finalize' ) {
steps { echo 'All parallel tasks complete' }
}
}
}
Further Reading and References