Introduction
A Pipeline Script is a programmatic definition of a software delivery pipeline, typically written in a domain-specific language (DSL) or supported scripting language like Groovy, YAML, or Bash. These scripts are the backbone of CI/CD automation, allowing teams to define how software should be built, tested, packaged, and deployed in a repeatable and version-controlled way.
Pipeline scripts are often used in tools like:
- Jenkins (Declarative/Scripted Groovy)
- GitHub Actions (YAML)
- GitLab CI (YAML)
- CircleCI (YAML)
- Azure Pipelines (YAML)
- Bitbucket Pipelines (YAML)
Why Use a Pipeline Script?
Traditional CI tools required point-and-click configuration via dashboards. This often led to:
- Configuration drift
- Inconsistent environments
- Lack of visibility and version control
With pipeline scripts, the pipeline becomes:
- Code: Stored in source control (Git)
- Auditable: Change history available
- Shareable: Reused across teams
- Portable: Easily recreated in other environments
Common Pipeline Script Features
| Feature | Description |
|---|---|
| Stages | Logical sections (build, test, deploy) |
| Steps | Commands or scripts executed in each stage |
| Conditions | Only run stages under certain criteria |
| Matrix Builds | Run across different OSes, versions |
| Environment Variables | Set and use secrets, paths, settings |
| Artifacts | Store and transfer build outputs |
| Parallelism | Run jobs concurrently |
| Triggers | Define when pipeline runs (push, PR, cron) |
Example 1: Jenkins Declarative Pipeline (Groovy)
pipeline {
agent any
environment {
NODE_ENV = 'production'
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install') {
steps {
sh 'npm install'
}
}
stage('Test') {
steps {
sh 'npm test'
}
}
stage('Build') {
steps {
sh 'npm run build'
}
}
stage('Deploy') {
when {
branch 'main'
}
steps {
sh './deploy.sh'
}
}
}
}
This Groovy-based script defines:
- 5 stages
- A branch-specific deployment
- Environmental variable
Example 2: GitHub Actions Workflow (YAML)
name: Node CI
on:
push:
branches: [main]
pull_request:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install
- run: npm test
- run: npm run build
Highlights:
- Triggered on push or PR
- Installs dependencies
- Runs tests and builds app
Example 3: GitLab CI/CD (YAML)
stages:
- build
- test
- deploy
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- dist/
test:
stage: test
script:
- npm test
deploy:
stage: deploy
only:
- main
script:
- ./scripts/deploy.sh
GitLab’s pipeline script defines 3 stages and a conditional deployment.
Scripted vs Declarative Pipelines (Jenkins)
| Type | Characteristics |
|---|---|
| Declarative | Structured, easy to read, validates syntax |
| Scripted | Groovy-based logic, flexible, more powerful |
Declarative example:
pipeline {
agent any
stages {
stage('Build') {
steps { sh 'make build' }
}
}
}
Scripted example:
node {
stage('Build') {
sh 'make build'
}
}
Reusability in Pipeline Scripts
| Technique | Tool |
|---|---|
| Includes | GitLab (include:), CircleCI (orbs:) |
| Shared Libraries | Jenkins (vars/, src/) |
| Reusable Workflows | GitHub Actions (reusable workflows) |
| Helm/Kustomize Templates | Kubernetes deployment logic |
| Scripts Directory | Bash scripts under /scripts/ |
Environment Variables and Secrets
Example in GitHub Actions:
env:
NODE_ENV: production
jobs:
build:
steps:
- run: echo $NODE_ENV
Secrets:
env:
API_KEY: ${{ secrets.API_KEY }}
In Jenkins:
environment {
API_KEY = credentials('my-api-key')
}
Artifact Handling
Artifacts are files you want to store or pass between stages.
- Jenkins:
archiveArtifacts artifacts: 'dist/**' - GitHub:
actions/upload-artifact - GitLab:
artifacts:
paths:
- dist/
Used for build outputs, test reports, binaries, etc.
Pipeline Script Triggers
| Trigger Type | Examples |
|---|---|
| Push/PR | Trigger on code changes |
| Schedule | cron jobs (nightly builds) |
| Tag Release | Run on version tagging |
| Manual/Approval | Require human interaction |
| API/Webhook | Trigger from external system |
Debugging Pipelines
| Problem | Solution |
|---|---|
| Failing script command | Use verbose logging (set -x) |
| Missing dependencies | Ensure pre-steps install all packages |
| Secret not injected | Check vault/secret manager permissions |
| Stage skipped | Recheck conditional logic (if, when) |
| Workflow not triggered | Verify on: or trigger: rules |
Best Practices
| Practice | Benefit |
|---|---|
| Store pipelines in code repository | Versioned and traceable |
| Break into logical stages | Easier debugging |
| Use caching wisely | Speed up builds |
| Avoid code duplication | Use includes, templates, shared libs |
| Parameterize environments | Use input vars and secrets |
| Handle failures gracefully | Retry logic, try/catch, notifications |
| Secure sensitive info | Vaults, secrets manager, masked variables |
| Use linting and validators | Catch YAML/Groovy errors early |
Advanced Features
- Dynamic Matrix Jobs
Build/test across multiple OSes or Node versions - Conditional Execution
Only run tests on modified files - Slack/Email Notifications
Alert on failed builds or deployments - Parallel Execution
Run tests or builds simultaneously to save time - Resource Locking
Prevent race conditions when deploying shared infrastructure
Summary
| Topic | Explanation |
|---|---|
| Purpose | Define CI/CD pipelines as code |
| Language | YAML, Groovy, Bash, etc. |
| Key Tools | Jenkins, GitHub Actions, GitLab CI, CircleCI |
| Benefits | Version control, automation, scalability |
| Common Elements | Stages, steps, environment vars, triggers |
| Best Practices | DRY, secure secrets, error handling, caching |
Related Keywords
- CI/CD Pipeline
- Declarative Pipeline
- Groovy DSL
- Jenkinsfile
- Pipeline as Code
- Shared Library
- Step Function
- Workflow Automation
- YAML Workflow
- YAML Syntax









