Problem Statement
Compare Declarative and Scripted Pipeline syntax in detail. When should you use each? Provide examples showing differences in structure, flexibility, and use cases.
Explanation
Declarative Pipeline uses structured, opinionated syntax starting with pipeline block. Required sections include agent and stages. Syntax is rigid but provides better validation, easier learning curve, and built-in best practices. Declarative example:
```groovy
pipeline {
agent any
environment {
APP_VERSION = '1.0.0'
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
stage('Test') {
steps {
sh 'mvn test'
}
}
}
post {
success {
echo 'Success!'
}
}
}
```
Scripted Pipeline uses flexible Groovy-based syntax starting with node block. Allows arbitrary Groovy code, variables, functions, and control flow. More powerful but requires more Groovy knowledge. Scripted example:
```groovy
node {
def appVersion = '1.0.0'
stage('Build') {
sh 'mvn clean package'
}
stage('Test') {
try {
sh 'mvn test'
} catch (Exception e) {
echo "Tests failed: ${e.message}"
throw e
}
}
if (env.BRANCH_NAME == 'main') {
stage('Deploy') {
sh './deploy.sh'
}
}
}
```
Key differences: Declarative uses pipeline block vs Scripted's node block, Declarative has predefined structure vs Scripted's free-form, Declarative validates syntax before execution vs Scripted fails at runtime, Declarative supports resume from stage vs Scripted restarts from beginning, Declarative has when directive vs Scripted uses if statements, Declarative uses post for cleanup vs Scripted uses try-catch-finally.
Flexibility: Scripted allows complex logic (loops, conditionals, functions) that's cumbersome in Declarative. Declarative can embed Groovy in script step but encourages using predefined directives. Example complex logic better suited for Scripted:
```groovy
def envs = ['dev', 'staging', 'prod']
for (env in envs) {
stage("Deploy to ${env}") {
if (shouldDeploy(env)) {
deployTo(env)
}
}
}
```
When to use Declarative: recommended for most pipelines, new pipeline development, teams with limited Groovy experience, when you want structure and validation, simpler maintenance requirements, need restart from stage feature. When to use Scripted: complex dynamic logic (loops, advanced conditionals), need full Groovy capabilities, existing Scripted pipelines (no need to rewrite if working), highly customized workflows not fitting Declarative model.
Mixed approach: use Declarative as default with script blocks for complex logic when needed:
```groovy
pipeline {
agent any
stages {
stage('Complex Logic') {
steps {
script {
def result = complexGroovyFunction()
if (result.success) {
echo "Success: ${result.value}"
}
}
}
}
}
}
```
Best practices: prefer Declarative for consistency and maintainability, use script blocks sparingly in Declarative for complex logic, document why Scripted is used if chosen, consider Shared Libraries for complex logic instead of inline Scripted code. Understanding both syntaxes enables choosing appropriate approach and maintaining diverse pipeline codebases.