A Scripted Jenkinsfile uses Groovy-based scripting within a node block to define the entire CI/CD workflow with full programmatic control, including stages, environment variables, error handling, and post-build actions
A Scripted Jenkinsfile is the original implementation of Pipeline as Code, built on the Groovy programming language. Unlike Declarative Pipeline's structured format, Scripted Pipeline gives developers the full power of Groovy to create complex, conditional, and highly customized CI/CD workflows. The entire script runs on the Jenkins controller and requires a node block to allocate an executor and workspace. This example demonstrates a complete Scripted Pipeline with all common sections explained.
1. Node Block: The mandatory node block allocates an executor on a Jenkins agent and creates a workspace for the build. Without a node block, Scripted Pipeline cannot execute any steps. This is where the actual build work happens.
2. Stage-Level Properties: Scripted Pipeline allows Groovy variable declarations anywhere in the script. These variables can hold configuration values, build metadata, or results from previous steps.
3. Stage Definition: Stages are defined with the stage keyword and a name. Unlike Declarative, Scripted Pipeline doesn't require stages to be inside a stages block—they can appear anywhere in the code flow.
4. Environment Variables: Groovy variables can be defined for build configuration. These can be simple strings or capture outputs from shell commands using sh(returnStdout: true).
5. Try-Catch Block: Scripted Pipeline uses Groovy's native exception handling. The try-catch-finally structure provides fine-grained control over error scenarios and cleanup operations.
6. SCM Operations: The checkout step checks out source code from version control. Scripted Pipeline uses the same step syntax as Declarative but with full Groovy flexibility.
7. Shell Execution: The sh step runs shell commands. Multi-line strings (triple quotes) allow complex shell scripts to be embedded directly in the pipeline.
8. Output Capture: Scripted Pipeline can capture command output using sh with returnStdout: true, enabling dynamic configuration based on build results.
9. Parallel Execution: The parallel block runs multiple tasks concurrently. Each task is defined as a closure that can contain its own stages and steps.
10. Conditional Execution: Scripted Pipeline uses standard Groovy if/else statements for conditional logic, providing complete flexibility for complex branching.
11. Manual Approval: The input step pauses the pipeline and waits for human approval. This is essential for production deployment gates.
12. Error Handling: The catch block captures exceptions and allows setting build status with currentBuild.result. The exception can be re-thrown to properly fail the build.
13. Cleanup: The finally block ensures cleanup runs regardless of success or failure. cleanWs() is a standard step to clean the workspace.
14. Build Status: At the end, the pipeline can check currentBuild.result to determine overall status and take appropriate actions.
Scripted Pipeline offers several unique capabilities that make it suitable for complex scenarios. It has full access to the Groovy standard library, allowing complex data manipulation, file operations, and custom function definitions. The script can dynamically generate stages at runtime using loops and conditionals—for example, creating a stage for each microservice in a mono-repo. However, this power comes with complexity: Scripted Pipeline is harder to validate statically, and syntax errors may only appear at runtime. The Jenkins official documentation recommends using Declarative Pipeline for most use cases due to its simplicity and built-in validation, reserving Scripted Pipeline for advanced scenarios requiring programmatic flexibility.
Unlike Declarative Pipeline, Scripted Pipeline does not enforce a rigid structure. There are no pipeline blocks, stages containers, or built-in post conditions. Everything is Groovy code. Environment variables are accessed via env.VAR_NAME or as Groovy variables. Error handling requires explicit try-catch rather than post sections. While this flexibility is powerful, it also means the pipeline script can become complex and harder to maintain, making good coding practices and comments essential for team collaboration.