100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
YAML

Jenkinsfile Fundamentals

Learn the core building blocks of a Jenkinsfile — agent, stages, steps, environment, parameters, and post — and how Pipeline as Code changed Jenkins pipeline management.

JenkinsBeginner9 min readJul 8, 2026
Analogies

Jenkinsfile Fundamentals

A Jenkinsfile is a text file, checked into source control alongside the application code it builds, that defines a Jenkins Pipeline using code rather than manual point-and-click job configuration in the Jenkins web UI. This 'Pipeline as Code' approach was a significant shift for Jenkins users: pipeline definitions became versioned, reviewable in pull requests, reproducible across environments, and recoverable if the Jenkins controller were ever rebuilt from scratch, none of which was true of the old free-style job configuration stored only inside Jenkins' internal XML files. Almost all modern Jenkins usage centers on the Jenkinsfile, typically using the declarative syntax covered elsewhere, so understanding its core directives is essential groundwork.

🏏

Cricket analogy: A Jenkinsfile checked into source control is like writing a team's batting order into an official, published scorecard rather than the captain scribbling it on a napkin in the dressing room -- the scorecard version is reviewable by selectors, reproducible for the next match, and recoverable even if the dressing room whiteboard gets wiped.

The core directives: agent, stages, steps

Every declarative Jenkinsfile requires an agent directive specifying where the pipeline (or, if set to none at the top level, each individual stage) runs — agent any uses any available agent, agent { label 'x' } targets agents with a specific label, and agent { docker { image 'node:20' } } runs the stage inside a freshly-started container from that image. Inside stages, each stage('Name') { steps { ... } } block groups related work and is what shows up as a distinct segment in Jenkins' pipeline visualization (including Blue Ocean and the classic stage view). steps is where the actual work happens: shell commands via sh (or bat/powershell on Windows), source checkout via checkout scm, and calls into any of the hundreds of plugin-provided pipeline steps.

🏏

Cricket analogy: The agent directive is like choosing which ground a match is played on -- agent any is playing at whichever venue is available, agent { label 'x' } is insisting on a spin-friendly pitch in Chennai, and agent { docker { image 'node:20' } } is like building a brand-new, freshly-prepared pitch just for this match; stages are the session breaks (morning, afternoon, evening) that structure the day, and steps are the actual deliveries bowled within each session.

environment, parameters, and options

The environment block defines environment variables available to all steps (or scoped to a single stage if declared inside it), and it is the idiomatic place to bind credentials via credentials('id'), which Jenkins automatically masks in console log output. The parameters block declares build parameters — string, booleanParam, choice, and others — that surface as a form when a human triggers a build manually, letting one Jenkinsfile serve many parameterized use cases (e.g. choosing a target environment). The options block configures pipeline-wide behavior such as timeout(time: 30, unit: 'MINUTES'), retry(2), disableConcurrentBuilds(), and timestamps() for log formatting.

🏏

Cricket analogy: The environment block is like a team's confidential dressing-room signals available to every player, with sensitive ones (credentials) shared only through the coach's private earpiece never shouted aloud; parameters are like a pre-match form where the captain picks conditions (pitch type, format); and options are ground rules like a rain timeout, a retry for a washed-out toss, and a rule barring two matches on the same ground at once (disableConcurrentBuilds).

groovy
pipeline {
    agent any
    options {
        timeout(time: 30, unit: 'MINUTES')
        disableConcurrentBuilds()
    }
    parameters {
        choice(name: 'ENVIRONMENT', choices: ['staging', 'production'], description: 'Deploy target')
    }
    environment {
        DEPLOY_TOKEN = credentials('deploy-token-id')
    }
    stages {
        stage('Checkout') {
            steps { checkout scm }
        }
        stage('Build') {
            steps { sh 'make build' }
        }
        stage('Deploy') {
            when { expression { params.ENVIRONMENT == 'production' } }
            steps { sh './deploy.sh --env=${ENVIRONMENT}' }
        }
    }
    post {
        always { archiveArtifacts artifacts: 'build/**', fingerprint: true }
        failure { echo 'Build failed — check console output.' }
    }
}

The when directive attached to a stage is one of declarative pipeline's most powerful features: it lets a single Jenkinsfile conditionally include or skip an entire stage based on branch name, a build parameter, an environment variable, or a custom Groovy expression { }, without needing separate Jenkinsfiles per branch or environment.

The post section defines actions that run after all stages complete, based on the final build result: always runs regardless of outcome (ideal for artifact archiving or workspace cleanup), success and failure run conditionally, changed runs only if the result differs from the previous build (useful for 'build is fixed now' or 'build just broke' notifications rather than repeating the same alert every run), and cleanup always runs last, even after other post conditions, and is the conventional place for deleteDir() workspace cleanup.

🏏

Cricket analogy: The post section is like a team's end-of-match routine: always is the mandatory kit collection done regardless of result, success and failure are the celebratory team huddle versus the somber review meeting, changed is only sending the town a special parade if the result flipped from a loss last match to a win now (not repeating the same announcement every win), and cleanup is the groundstaff always rolling the covers last, after every other post-match ritual is done.

A common beginner mistake is putting credential values directly into sh step strings via Groovy interpolation, e.g. sh "curl -H 'Authorization: ${DEPLOY_TOKEN}'". Depending on how the string is built, this can bypass Jenkins' automatic credential masking in the console log. The safer pattern is to let the shell itself read the environment variable — sh 'curl -H "Authorization: $DEPLOY_TOKEN"' — using single quotes so Groovy does not interpolate the secret into the literal step string that gets logged.

  • A Jenkinsfile turns pipeline configuration into version-controlled, reviewable code ('Pipeline as Code').
  • agent, stages, and steps are the three directives required to define where and what a pipeline runs.
  • environment binds env vars and credentials; parameters defines user-facing build inputs; options configures pipeline-wide behavior like timeouts.
  • The when directive conditionally runs a stage based on branch, parameters, or a custom expression.
  • post runs cleanup/notification logic keyed on build outcome: always, success, failure, changed, cleanup.
  • Credentials should be referenced via credentials('id') and passed to shell steps with single quotes so Jenkins' log-masking applies correctly.

Practice what you learned

Was this page helpful?

Topics covered

#YAML#CICDToolsPipelinesStudyNotes#DevOps#JenkinsfileFundamentals#Jenkinsfile#Fundamentals#Core#Directives#StudyNotes#SkillVeris