Skip to main content
Jenkins Pipeline
CHAPTER 06

Writing Jenkinsfile Pipelines

Updated: May 15, 2026
25 min read

# CHAPTER 6

Writing Jenkinsfile Pipelines

1. Introduction

In Chapter 5, we created a basic "Hello World" pipeline. But real-world CI/CD requires much more than simply echoing text to the screen. You need to define variables (like which server to deploy to), execute complex shell scripts, and tell Jenkins what to do if a step fails. In this chapter, we will dive deeper into the Declarative Pipeline syntax, mastering Environment Variables, the sh step, and the post block for handling build resolutions.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define and use Global Environment Variables in a Jenkinsfile.
  • Execute Linux shell commands (sh) and Windows batch commands (bat).
  • Use the post block to handle Success, Failure, and Always conditions.
  • Understand how to structure a professional, multi-stage pipeline.

3. Beginner-Friendly Explanation

Imagine building a Lego car.
  • Environment Variables: Before you start, you agree on some rules. CARCOLOR = Red, WHEELSIZE = Large. You write this on a whiteboard. Every builder can look at the whiteboard instead of asking.
  • The sh Step: This is the actual physical action. "Snap the red brick onto the base." In Jenkins, this is where you type actual Linux terminal commands.
  • The post Block (Cleanup): When the car is finished, regardless of whether it looks good or if you broke a piece, you *always* sweep the floor and put the extra pieces away. In Jenkins, the post block ensures cleanup and notifications happen, no matter what went wrong.

4. Executing Commands (sh and bat)

The steps block is where the work happens. The most common step is sh (execute a Linux Shell script). If Jenkins runs on a Windows server without WSL, you must use bat instead of sh.
groovy
12345678910
steps {
    // Run a single Linux command
    sh 'npm install'
    
    // Run multiple Linux commands
    sh '''
        echo "Building the application"
        zip -r app.zip ./src
    '''
}

5. Environment Variables

Pipelines often need data that changes depending on the context (e.g., "Are we deploying to Staging or Production?"). We define these in the environment block.
groovy
1234567891011121314151617
pipeline {
    agent any
    environment {
        // Define a variable
        APP_VERSION = '1.0.4'
        DEPLOY_SERVER = 'staging.example.com'
    }
    stages {
        stage('Deploy') {
            steps {
                // Use the variable using ${} syntax
                echo "Deploying version ${APP_VERSION} to ${DEPLOY_SERVER}"
                sh "scp app.zip user@${DEPLOY_SERVER}:/var/www/html"
            }
        }
    }
}

6. Mini Project: Build a Resilient Multi-Stage Pipeline

Let's build a professional pipeline that compiles code and cleans up after itself.

Step-by-Step Walkthrough: Update your Jenkinsfile with the following code. Note the new post section at the very end.

groovy
1234567891011121314151617181920212223242526272829303132333435
pipeline {
    agent any
    environment {
        PROJECT_NAME = 'MyAwesomePHPApp'
    }
    stages {
        stage('Build') {
            steps {
                echo "Starting build for ${PROJECT_NAME}..."
                sh 'mkdir -p build_output'
                sh 'echo "Simulated compiled code" > build_output/app.bin'
            }
        }
        stage('Test') {
            steps {
                echo 'Running tests...'
                // If this command fails, the pipeline stops here!
                sh 'ls -la build_output/app.bin' 
            }
        }
    }
    // The Post block runs after all stages finish
    post {
        always {
            echo 'Sweeping the floor. Deleting temporary build files.'
            sh 'rm -rf build_output'
        }
        success {
            echo 'Build succeeded! Sending Slack notification...'
        }
        failure {
            echo 'Build failed! Sending angry email to developers...'
        }
    }
}

7. Real-World Scenarios

A junior developer wrote a pipeline that created heavy, 2GB temporary database files during the "Test" stage. They didn't include a post { always { ... } } cleanup block. When the tests passed, the pipeline ended, leaving the 2GB file on the server. Because they deployed 10 times a day, the Jenkins server hard drive filled up entirely by Friday afternoon, crashing the server and halting all company deployments. A simple post { always { sh 'rm -rf tempdb' } } would have prevented the outage.

8. Best Practices

  • Use Single Quotes vs Double Quotes: In Groovy/Jenkins syntax, use single quotes ('text') for static text. You MUST use double quotes ("text") if you want to inject an environment variable (e.g., "Deploying ${APPVERSION}"). If you use single quotes, it will print the literal dollar sign.

9. Security Recommendations

  • Do not define passwords in the Environment block: Never write DBPASSWORD = 'password123' in the environment block of a Jenkinsfile. This file is saved in Git in plaintext for anyone to read. We will learn how to handle secure credentials in Chapter 14.

10. Troubleshooting Tips

  • The "No Such File" Error: If your sh step fails saying a file doesn't exist, remember that Jenkins runs these commands inside a temporary "Workspace" directory. Use sh 'pwd' and sh 'ls -la' as your first debugging steps to figure out exactly where Jenkins is "standing" on the server.

11. Exercises

  1. 1. What is the difference between single quotes (') and double quotes (") when writing a sh step in a Jenkinsfile?
  1. 2. Why is the always condition inside a post block critical for server maintenance?

12. FAQs

Q: Can I run Python scripts instead of bash scripts? A: Yes! As long as Python is installed on the Jenkins server (or inside the Docker container acting as the agent), you can simply write sh 'python3 script.py'.

13. Interview Questions

  • Q: Explain the purpose and standard use cases of the post block in a Declarative Pipeline. Contrast the always, success, and failure conditions.
  • Q: A developer complains that their environment variable $APIKEY is evaluating literally as the string "$API_KEY" instead of the actual key value. What Groovy syntax error is the developer making?

14. Summary

In Chapter 6, we evolved our pipelines from basic text echoing to functional scripts. We learned how to define Global Environment Variables to keep our code DRY (Don't Repeat Yourself), and how to execute powerful server commands using the sh step. Finally, we explored the critical post block, enabling our pipelines to handle failures gracefully, trigger notifications, and ensure the workspace is swept clean regardless of the build outcome.

15. Next Chapter Recommendation

We know how to write the Jenkinsfile, but currently, we have to manually click "Build" to make it run. We need Jenkins to detect when we write code and trigger itself automatically. Proceed to Chapter 7: Git and GitHub Integration.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·