Jenkins Pipeline Samples

Jenkins CI/CD pipeline configuration examples including declarative and scripted pipelines for various deployment scenarios

💻 Jenkins Declarative Pipeline Hello World groovy

🟢 simple ⭐⭐

Basic Jenkins declarative pipeline example with fundamental stages and steps

⏱️ 15 min 🏷️ jenkins, pipeline, ci/cd, automation
Prerequisites: Jenkins basics, Groovy syntax
// Jenkins Declarative Pipeline - Hello World Example

pipeline {
    agent any

    tools {
        maven 'Maven-3.8.6'
        jdk 'JDK-11'
    }

    environment {
        APP_NAME = 'MyApplication'
        VERSION = '1.0.0'
        BUILD_NUMBER = env.BUILD_NUMBER
    }

    stages {
        stage('Checkout') {
            steps {
                // Checkout source code from SCM
                checkout scm

                echo "Checking out ${APP_NAME} version ${VERSION}"
                echo "Build number: ${BUILD_NUMBER}"
            }
        }

        stage('Build') {
            steps {
                echo "Building ${APP_NAME}..."

                // Example Maven build
                sh 'mvn clean compile'

                // Display build information
                echo "Build completed successfully!"
            }
        }

        stage('Test') {
            steps {
                echo "Running tests for ${APP_NAME}..."

                // Run unit tests
                sh 'mvn test'

                // Archive test results
                junit 'target/surefire-reports/*.xml'
            }
        }

        stage('Package') {
            steps {
                echo "Packaging ${APP_NAME}..."

                // Create application package
                sh 'mvn package'

                // Archive artifacts
                archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
            }
        }

        stage('Deploy') {
            steps {
                echo "Deploying ${APP_NAME} to staging..."

                // Deploy to staging environment
                sh '''
                    echo "Deploying to staging server..."
                    # Add your deployment commands here
                    # scp target/*.jar user@staging-server:/opt/app/
                    # ssh user@staging-server "systemctl restart myapp"
                '''
            }
        }
    }

    post {
        always {
            echo 'Pipeline execution completed'
            cleanWs() // Clean workspace
        }

        success {
            echo 'Pipeline succeeded! 🎉'

            // Send success notification
            emailext (
                subject: "✅ ${APP_NAME} Build #${BUILD_NUMBER} - SUCCESS",
                body: """<html>
                    <body>
                        <h2>Build Success</h2>
                        <p><strong>Application:</strong> ${APP_NAME}</p>
                        <p><strong>Version:</strong> ${VERSION}</p>
                        <p><strong>Build:</strong> #${BUILD_NUMBER}</p>
                        <p><strong>Branch:</strong> ${env.BRANCH_NAME}</p>
                        <p><strong>Duration:</strong> ${currentBuild.durationString}</p>
                        <br>
                        <a href="${env.BUILD_URL}">View Build Details</a>
                    </body>
                </html>""",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }

        failure {
            echo 'Pipeline failed! ❌'

            // Send failure notification
            emailext (
                subject: "❌ ${APP_NAME} Build #${BUILD_NUMBER} - FAILED",
                body: """<html>
                    <body>
                        <h2>Build Failed</h2>
                        <p><strong>Application:</strong> ${APP_NAME}</p>
                        <p><strong>Version:</strong> ${VERSION}</p>
                        <p><strong>Build:</strong> #${BUILD_NUMBER}</p>
                        <p><strong>Branch:</strong> ${env.BRANCH_NAME}</p>
                        <p><strong>Failed Stage:</strong> ${currentBuild.currentResult}</p>
                        <br>
                        <a href="${env.BUILD_URL}">View Build Details</a>
                    </body>
                </html>""",
                to: "${env.CHANGE_AUTHOR_EMAIL}"
            )
        }

        unstable {
            echo 'Pipeline is unstable! ⚠️'
        }
    }
}

💻 Jenkins Multi-Branch Pipeline groovy

🟡 intermediate ⭐⭐⭐⭐

Advanced multi-branch pipeline with environment-specific deployments and parallel stages

⏱️ 30 min 🏷️ jenkins, pipeline, multi-branch, deployment
Prerequisites: Jenkins declarative pipeline, Docker, Kubernetes basics, Helm
// Jenkins Multi-Branch Pipeline with Environment-Specific Deployments

pipeline {
    agent any

    tools {
        nodejs 'NodeJS-16'
        maven 'Maven-3.8.6'
        docker 'Docker-Latest'
    }

    environment {
        REGISTRY = 'your-registry.com'
        CREDENTIALS_ID = 'docker-registry-credentials'
        APP_NAME = 'microservice-app'

        // Environment-specific configurations
        DEV_ENV = 'development'
        STAGING_ENV = 'staging'
        PROD_ENV = 'production'
    }

    parameters {
        choice(
            name: 'DEPLOY_ENVIRONMENT',
            choices: ['none', 'dev', 'staging', 'production'],
            description: 'Select deployment environment'
        )

        booleanParam(
            name: 'RUN_INTEGRATION_TESTS',
            defaultValue: false,
            description: 'Run integration tests after build'
        )

        string(
            name: 'RELEASE_VERSION',
            defaultValue: '',
            description: 'Release version (leave empty for snapshot)'
        )
    }

    options {
        buildDiscarder(logRotator(numToKeepStr: '20'))
        timeout(time: 60, unit: 'MINUTES')
        timestamps()

        // Skip stages based on parameters
        skipStagesAfterUnstable()

        // Retry on failure
        retry(3)
    }

    triggers {
        // Poll SCM every 5 minutes
        pollSCM('H/5 * * * *')

        // Build on PR creation
        pullRequest()
    }

    stages {
        stage('Initialize') {
            steps {
                script {
                    // Set version based on parameters
                    if (params.RELEASE_VERSION) {
                        env.APP_VERSION = params.RELEASE_VERSION
                        env.IS_RELEASE = 'true'
                    } else {
                        env.APP_VERSION = "${env.BUILD_NUMBER}-SNAPSHOT"
                        env.IS_RELEASE = 'false'
                    }

                    echo "Building version: ${env.APP_VERSION}"
                    echo "Deploying to: ${params.DEPLOY_ENVIRONMENT}"
                    echo "Is release: ${env.IS_RELEASE}"
                }
            }
        }

        stage('Parallel Build & Test') {
            parallel {
                stage('Backend Build') {
                    steps {
                        dir('backend') {
                            echo "Building backend services..."

                            sh '''
                                mvn clean compile
                                mvn test
                                mvn package -DskipTests
                            '''

                            // Archive backend artifacts
                            archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
                            junit 'target/surefire-reports/*.xml'
                        }
                    }
                }

                stage('Frontend Build') {
                    steps {
                        dir('frontend') {
                            echo "Building frontend application..."

                            sh '''
                                npm install
                                npm run lint
                                npm run test:coverage
                                npm run build
                            '''

                            // Archive test coverage
                            publishHTML([
                                allowMissing: false,
                                alwaysLinkToLastBuild: true,
                                keepAll: true,
                                reportDir: 'coverage',
                                reportFiles: 'index.html',
                                reportName: 'Coverage Report'
                            ])
                        }
                    }
                }

                stage('Security Scan') {
                    steps {
                        echo "Running security vulnerability scans..."

                        // OWASP Dependency Check
                        sh '''
                            mvn org.owasp:dependency-check-maven:check                                 -DskipTests                                 -DfailBuildOnCVSS=7
                        '''

                        // Static code analysis
                        withSonarQubeEnv('SonarQube-Server') {
                            sh 'mvn sonar:sonar'
                        }
                    }
                }
            }
        }

        stage('Integration Tests') {
            when {
                expression {
                    return params.RUN_INTEGRATION_TESTS ||
                           env.BRANCH_NAME == 'main' ||
                           env.BRANCH_NAME == 'develop'
                }
            }

            steps {
                echo "Running integration tests..."

                script {
                    // Start test environment
                    try {
                        sh 'docker-compose -f docker-compose.test.yml up -d'
                        sleep 30 // Wait for services to be ready

                        // Run integration tests
                        sh 'mvn verify -Pintegration-tests'

                        // Generate test report
                        junit 'target/failsafe-reports/*.xml'
                    } finally {
                        // Cleanup test environment
                        sh 'docker-compose -f docker-compose.test.yml down'
                    }
                }
            }
        }

        stage('Build Docker Image') {
            when {
                anyOf {
                    branch 'main'
                    branch 'develop'
                    expression { params.DEPLOY_ENVIRONMENT != 'none' }
                }
            }

            steps {
                script {
                    def imageTag = "${env.REGISTRY}/${env.APP_NAME}:${env.APP_VERSION}"

                    echo "Building Docker image: ${imageTag}"

                    // Build Docker image
                    sh """
                        docker build -t ${imageTag} .
                        docker tag ${imageTag} ${env.REGISTRY}/${env.APP_NAME}:latest
                    """

                    // Push to registry
                    withDockerRegistry([credentialsId: env.CREDENTIALS_ID, url: "https://${env.REGISTRY}"]) {
                        sh """
                            docker push ${imageTag}
                            docker push ${env.REGISTRY}/${env.APP_NAME}:latest
                        """
                    }

                    env.DOCKER_IMAGE = imageTag
                }
            }
        }

        stage('Deploy to Environment') {
            when {
                expression { params.DEPLOY_ENVIRONMENT != 'none' }
            }

            steps {
                script {
                    def deployEnv = params.DEPLOY_ENVIRONMENT

                    echo "Deploying to ${deployEnv} environment..."

                    // Environment-specific deployment logic
                    switch(deployEnv) {
                        case 'dev':
                            deployToDevelopment()
                            break
                        case 'staging':
                            deployToStaging()
                            break
                        case 'production':
                            deployToProduction()
                            break
                    }
                }
            }
        }

        stage('Health Check') {
            when {
                expression { params.DEPLOY_ENVIRONMENT != 'none' }
            }

            steps {
                echo "Performing health check..."

                script {
                    def deployUrl = getDeployUrl(params.DEPLOY_ENVIRONMENT)

                    // Wait for deployment and perform health check
                    retry(10) {
                        sleep 30

                        sh """
                            curl -f ${deployUrl}/health || exit 1
                            echo "Health check passed for ${deployUrl}"
                        """
                    }
                }
            }
        }
    }

    post {
        always {
            // Cleanup
            script {
                // Clean Docker images
                sh 'docker system prune -f'

                // Clean workspace
                cleanWs()
            }

            // Generate build summary
            script {
                def summary = """
                    <h2>Build Summary</h2>
                    <ul>
                        <li><strong>Application:</strong> ${env.APP_NAME}</li>
                        <li><strong>Version:</strong> ${env.APP_VERSION}</li>
                        <li><strong>Branch:</strong> ${env.BRANCH_NAME}</li>
                        <li><strong>Environment:</strong> ${params.DEPLOY_ENVIRONMENT}</li>
                        <li><strong>Duration:</strong> ${currentBuild.durationString}</li>
                        <li><strong>Result:</strong> ${currentBuild.currentResult}</li>
                    </ul>
                """

                echo summary
            }
        }

        success {
            echo "🎉 Pipeline completed successfully!"

            // Send Slack notification
            slackSend(
                channel: '#ci-cd',
                color: 'good',
                message: "✅ *${env.APP_NAME}* Build #${BUILD_NUMBER} succeeded\nBranch: ${env.BRANCH_NAME}\nEnvironment: ${params.DEPLOY_ENVIRONMENT}"
            )
        }

        failure {
            echo "❌ Pipeline failed!"

            // Send failure notifications
            slackSend(
                channel: '#ci-cd',
                color: 'danger',
                message: "❌ *${env.APP_NAME}* Build #${BUILD_NUMBER} failed\nBranch: ${env.BRANCH_NAME}\n<${env.BUILD_URL}|View Details>"
            )

            // Create JIRA ticket on production failure
            script {
                if (params.DEPLOY_ENVIRONMENT == 'production') {
                    jiraIssueSelector(
                        issueSelector: [$class: 'DefaultIssueSelector'],
                        site: 'JIRA-SERVER'
                    )
                }
            }
        }
    }
}

// Helper functions
def deployToDevelopment() {
    sh """
        kubectl set image deployment/${env.APP_NAME} ${env.APP_NAME}=${env.DOCKER_IMAGE} -n development
        kubectl rollout status deployment/${env.APP_NAME} -n development --timeout=300s
    """
}

def deployToStaging() {
    input message: 'Deploy to staging environment?', ok: 'Deploy'

    sh """
        helm upgrade --install ${env.APP_NAME}-staging ./helm-chart \
            --namespace staging \
            --set image.repository=${env.REGISTRY}/${env.APP_NAME} \
            --set image.tag=${env.APP_VERSION} \
            --set environment=staging
    """
}

def deployToProduction() {
    input message: 'Deploy to PRODUCTION? This requires approval!', ok: 'Deploy to Production'

    // Manual approval required for production
    timeout(time: 15, unit: 'MINUTES') {
        input message: 'Approve production deployment?', ok: 'Approve'
    }

    sh """
        # Blue-green deployment for production
        ./scripts/blue-green-deploy.sh ${env.DOCKER_IMAGE} production
    """
}

def getDeployUrl(environment) {
    switch(environment) {
        case 'dev':
            return 'https://dev.example.com'
        case 'staging':
            return 'https://staging.example.com'
        case 'production':
            return 'https://api.example.com'
        default:
            return 'http://localhost:8080'
    }
}

💻 Jenkins Scripted Pipeline Advanced Example groovy

🔴 complex ⭐⭐⭐⭐⭐

Complex scripted pipeline with dynamic stage generation and custom logic

⏱️ 45 min 🏷️ jenkins, scripted pipeline, dynamic, deployment strategies
Prerequisites: Advanced Jenkins, Groovy programming, Docker, Kubernetes, DevOps concepts
// Jenkins Scripted Pipeline - Advanced Dynamic Pipeline

node('linux') {
    // Global variables
    def appName = 'advanced-app'
    def buildNumber = env.BUILD_NUMBER
    def gitCommit = env.GIT_COMMIT?.take(8)
    def branchName = env.BRANCH_NAME

    // Tools configuration
    def tools = [
        maven: tool 'Maven-3.8.6',
        jdk: tool 'JDK-11',
        nodejs: tool 'NodeJS-16'
    ]

    // Environment variables
    environment {
        PATH = "${tools.jdk}/bin:${tools.maven}/bin:${tools.nodejs}/bin:${env.PATH}"
        MAVEN_OPTS = '-Xmx1024m'
        NODE_OPTIONS = '--max-old-space-size=4096'
    }

    try {
        stage('Preparation') {
            // Clean workspace
            cleanWs()

            // Checkout code
            checkout scm

            // Load configuration
            def config = readYaml file: 'jenkins-config.yaml'

            echo """
                ========================================
                Build Configuration:
                Application: ${appName}
                Branch: ${branchName}
                Commit: ${gitCommit}
                Build: #${buildNumber}
                ========================================
            """

            // Store config for later use
            env.JENKINS_CONFIG = groovy.json.JsonOutput.toJson(config)
        }

        // Dynamic stages generation
        def stages = []

        // Add stages based on configuration
        if (hasBackendCode()) {
            stages << 'Backend Build'
            stages << 'Backend Test'
        }

        if (hasFrontendCode()) {
            stages << 'Frontend Build'
            stages << 'Frontend Test'
        }

        if (hasMicroservices()) {
            stages << 'Microservices Build'
            stages << 'Service Integration Test'
        }

        stages << 'Security Scan'
        stages << 'Quality Gates'

        // Conditional deployment stages
        if (shouldDeploy()) {
            stages << 'Docker Build'
            stages << 'Deploy'
        }

        // Execute dynamic stages
        stages.each { stageName ->
            stage(stageName) {
                executeStage(stageName)
            }
        }

    } catch (error) {
        echo "Pipeline failed: ${error}"
        currentBuild.result = 'FAILURE'

        // Error handling and notifications
        handleError(error)

        throw error
    } finally {
        stage('Cleanup') {
            // Always run cleanup
            cleanup()
        }
    }
}

// Helper functions for dynamic execution

def hasBackendCode() {
    return fileExists('backend/pom.xml') || fileExists('backend/build.gradle')
}

def hasFrontendCode() {
    return fileExists('frontend/package.json')
}

def hasMicroservices() {
    return fileExists('microservices/') && fileExists('docker-compose.yml')
}

def shouldDeploy() {
    def config = new groovy.json.JsonSlurper().parseText(env.JENKINS_CONFIG)
    return (branchName == 'main' ||
            branchName == 'develop' ||
            config.forceDeploy == true) &&
           params.DEPLOY_TO != 'none'
}

def executeStage(stageName) {
    switch(stageName) {
        case 'Backend Build':
            executeBackendBuild()
            break
        case 'Backend Test':
            executeBackendTests()
            break
        case 'Frontend Build':
            executeFrontendBuild()
            break
        case 'Frontend Test':
            executeFrontendTests()
            break
        case 'Microservices Build':
            executeMicroservicesBuild()
            break
        case 'Service Integration Test':
            executeIntegrationTests()
            break
        case 'Security Scan':
            executeSecurityScan()
            break
        case 'Quality Gates':
            executeQualityGates()
            break
        case 'Docker Build':
            executeDockerBuild()
            break
        case 'Deploy':
            executeDeployment()
            break
        default:
            echo "Unknown stage: ${stageName}"
    }
}

// Stage execution functions

def executeBackendBuild() {
    dir('backend') {
        echo "Building backend services..."

        // Detect build tool
        if (fileExists('pom.xml')) {
            sh 'mvn clean compile -DskipTests'
        } else if (fileExists('build.gradle')) {
            sh './gradlew compileJava -x test'
        } else {
            error "Unsupported build system for backend"
        }

        // Archive compiled classes
        archiveArtifacts artifacts: '**/target/classes/**/*,**/build/classes/**/*', fingerprint: true
    }
}

def executeBackendTests() {
    dir('backend') {
        echo "Running backend tests..."

        // Run tests with coverage
        if (fileExists('pom.xml')) {
            sh '''
                mvn clean test jacoco:report
                mvn sonar:sonar -Dsonar.host.url=${SONAR_HOST_URL}
            '''

            // Archive test results
            junit 'target/surefire-reports/*.xml'

            // Publish coverage report
            publishHTML([
                allowMissing: false,
                alwaysLinkToLastBuild: true,
                keepAll: true,
                reportDir: 'target/site/jacoco',
                reportFiles: 'index.html',
                reportName: 'Backend Coverage Report'
            ])
        } else if (fileExists('build.gradle')) {
            sh '''
                ./gradlew test jacocoTestReport sonarqube
            '''

            junit 'build/test-results/test/*.xml'
        }
    }
}

def executeFrontendBuild() {
    dir('frontend') {
        echo "Building frontend application..."

        sh '''
            npm ci
            npm run lint
            npm run build
        '''

        // Archive build artifacts
        archiveArtifacts artifacts: 'dist/**/*,build/**/*', fingerprint: true
    }
}

def executeFrontendTests() {
    dir('frontend') {
        echo "Running frontend tests..."

        sh '''
            npm run test:unit
            npm run test:e2e
        '''

        // Archive test results
        junit 'test-results/**/*.xml'

        // Publish coverage
        publishHTML([
            allowMissing: false,
            alwaysLinkToLastBuild: true,
            keepAll: true,
            reportDir: 'coverage',
            reportFiles: 'index.html',
            reportName: 'Frontend Coverage Report'
        ])
    }
}

def executeMicroservicesBuild() {
    echo "Building microservices..."

    // Build each service
    def services = sh(
        script: 'find microservices -name "pom.xml" -o -name "build.gradle" | sed "s|/[^/]*$||" | sort -u',
        returnStdout: true
    ).trim().split('
')

    services.each { service ->
        dir(service) {
            echo "Building service: ${service}"

            if (fileExists('pom.xml')) {
                sh 'mvn clean package -DskipTests'
            } else if (fileExists('build.gradle')) {
                sh './gradlew build -x test'
            }

            // Archive service artifacts
            archiveArtifacts artifacts: 'target/*.jar,build/libs/*.jar', fingerprint: true
        }
    }
}

def executeIntegrationTests() {
    echo "Running integration tests..."

    // Start test environment
    def composeFile = 'docker-compose.test.yml'

    try {
        sh "docker-compose -f ${composeFile} up -d"

        // Wait for services to be ready
        sleep time: 60, unit: 'SECONDS'

        // Run integration tests
        sh '''
            mvn verify -Pintegration-tests
        '''

        junit 'target/failsafe-reports/*.xml'

    } finally {
        sh "docker-compose -f ${composeFile} down -v"
    }
}

def executeSecurityScan() {
    echo "Running security scans..."

    parallel(
        'Dependency Scan': {
            sh '''
                mvn org.owasp:dependency-check-maven:check                     -DskipTests                     -DfailBuildOnCVSS=7
            '''
        },
        'Static Analysis': {
            sh '''
                mvn spotbugs:check
                find . -name "*.py" -exec bandit -r {} + || true
                find . -name "*.js" -exec eslint {} + || true
            '''
        },
        'Container Scan': {
            sh '''
                docker build -t security-scan .
                trivy image --exit-code 1 --severity HIGH,CRITICAL security-scan
            '''
        }
    )
}

def executeQualityGates() {
    echo "Checking quality gates..."

    script {
        def sonarStatus = waitForQualityGate()

        if (sonarStatus.status != 'OK') {
            error "Pipeline aborted due to quality gate failure: ${sonarStatus.status}"
        }

        echo "Quality gates passed: ${sonarStatus.status}"
    }
}

def executeDockerBuild() {
    echo "Building Docker images..."

    def config = new groovy.json.JsonSlurper().parseText(env.JENKINS_CONFIG)
    def registry = config.docker.registry
    def appName = config.docker.appName
    def version = "${buildNumber}-${gitCommit}"

    // Build and push images for microservices
    def services = sh(
        script: 'find microservices -name Dockerfile | sed "s|/Dockerfile||" | sort -u',
        returnStdout: true
    ).trim().split('
')

    services.each { service ->
        def serviceName = service.substring(service.lastIndexOf('/') + 1)
        def imageTag = "${registry}/${appName}-${serviceName}:${version}"

        sh """
            cd ${service}
            docker build -t ${imageTag} .
            docker push ${imageTag}
            docker tag ${imageTag} ${registry}/${appName}-${serviceName}:latest
            docker push ${registry}/${appName}-${serviceName}:latest
        """

        echo "Built and pushed: ${imageTag}"
    }
}

def executeDeployment() {
    def deployEnv = params.DEPLOY_TO

    echo "Deploying to ${deployEnv}..."

    // Manual approval for production
    if (deployEnv == 'production') {
        timeout(time: 15, unit: 'MINUTES') {
            input message: 'Deploy to production? Manual approval required.', ok: 'Approve'
        }
    }

    // Deploy using chosen strategy
    switch(params.DEPLOY_STRATEGY) {
        case 'rolling':
            rollingDeploy(deployEnv)
            break
        case 'blue-green':
            blueGreenDeploy(deployEnv)
            break
        case 'canary':
            canaryDeploy(deployEnv)
            break
        default:
            rollingDeploy(deployEnv)
    }

    // Post-deployment validation
    postDeployValidation(deployEnv)
}

def rollingDeploy(environment) {
    echo "Performing rolling deployment to ${environment}..."

    sh """
        kubectl set image deployment/app app=${registry}/app:${version} -n ${environment}
        kubectl rollout status deployment/app -n ${environment} --timeout=600s
    """
}

def blueGreenDeploy(environment) {
    echo "Performing blue-green deployment to ${environment}..."

    sh """
        ./scripts/blue-green-deploy.sh \
            --image ${registry}/app:${version} \
            --namespace ${environment} \
            --service app
    """
}

def canaryDeploy(environment) {
    echo "Performing canary deployment to ${environment}..."

    // Deploy 10% traffic
    sh """
        kubectl patch deployment app -n ${environment} -p '{"spec":{"template":{"spec":{"containers":[{"name":"app","image":"${registry}/app:${version}"}]}}}}'
        kubectl patch service app -n ${environment} -p '{"spec":{"selector":{"version":"new"}}}'
    """

    // Wait and monitor
    sleep time: 300, unit: 'SECONDS'

    // Check canary metrics
    if (canaryHealthy()) {
        echo "Canary deployment successful, proceeding with full rollout"
        sh "kubectl patch service app -n ${environment} -p '{"spec":{"selector":{"version":"latest"}}}'"
    } else {
        echo "Canary deployment failed, rolling back"
        sh "kubectl rollout undo deployment/app -n ${environment}"
        error "Canary deployment failed"
    }
}

def canaryHealthy() {
    // Implement health check logic
    def response = sh(
        script: 'curl -s -o /dev/null -w "%{http_code}" http://app-service/health',
        returnStdout: true
    ).trim()

    return response == '200'
}

def postDeployValidation(environment) {
    echo "Performing post-deployment validation..."

    def deployUrl = getEnvironmentUrl(environment)

    // Health check
    retry(10) {
        sleep 30

        def healthResponse = sh(
            script: "curl -f ${deployUrl}/health",
            returnStatus: true
        )

        if (healthResponse != 0) {
            error "Health check failed for ${deployUrl}"
        }
    }

    // Run smoke tests
    sh "./scripts/smoke-tests.sh ${deployUrl}"

    echo "Post-deployment validation completed successfully"
}

def getEnvironmentUrl(environment) {
    def urls = [
        'dev': 'https://dev-api.example.com',
        'staging': 'https://staging-api.example.com',
        'production': 'https://api.example.com'
    ]

    return urls[environment] ?: "http://localhost:8080"
}

def handleError(error) {
    echo "Handling error: ${error}"

    // Create incident for production failures
    if (params.DEPLOY_TO == 'production') {
        createIncident(error)
    }

    // Send failure notifications
    sendFailureNotification(error)

    // Auto-rollback if deployment failure
    if (error.message?.contains('deployment')) {
        rollbackDeployment()
    }
}

def createIncident(error) {
    // Create incident in monitoring system
    sh """
        curl -X POST "${INCIDENT_API_URL}" \
            -H "Authorization: Bearer ${INCIDENT_API_TOKEN}" \
            -H "Content-Type: application/json" \
            -d '{
                "title": "Pipeline Failure: ${appName}",
                "description": "Build #${buildNumber} failed: ${error.message}",
                "severity": "high",
                "service": "${appName}",
                "environment": "${params.DEPLOY_TO}"
            }'
    """
}

def sendFailureNotification(error) {
    def message = """
        🔴 **Pipeline Failure**

        **Application:** ${appName}
        **Build:** #${buildNumber}
        **Branch:** ${branchName}
        **Error:** ${error.message}
        **Environment:** ${params.DEPLOY_TO}

        <${env.BUILD_URL}|View Build Details>
    """

    slackSend(
        channel: '#alerts',
        color: 'danger',
        message: message
    )
}

def rollbackDeployment() {
    if (params.DEPLOY_TO != 'none') {
        echo "Rolling back deployment..."

        sh """
            kubectl rollout undo deployment/app -n ${params.DEPLOY_TO}
            kubectl rollout status deployment/app -n ${params.DEPLOY_TO} --timeout=300s
        """

        echo "Rollback completed"
    }
}

def cleanup() {
    echo "Performing cleanup..."

    // Clean Docker resources
    sh '''
        docker system prune -f --volumes
        docker volume prune -f
    '''

    // Clean workspace
    cleanWs()

    // Archive logs
    archiveLog()

    echo "Cleanup completed"
}

def archiveLog() {
    echo "Archiving build logs..."

    def logFile = "${env.WORKSPACE}/build-${buildNumber}.log"

    sh """
        echo "Build log for #${buildNumber}" > ${logFile}
        echo "Branch: ${branchName}" >> ${logFile}
        echo "Commit: {gitCommit}" >> ${logFile}
        echo "Result: ${currentBuild.result}" >> ${logFile}
        echo "Duration: ${currentBuild.durationString}" >> ${logFile}
        echo "----------------------------------------" >> ${logFile}
        cat ${env.WORKSPACE}@tmp/durable-*/script.sh >> ${logFile} 2>/dev/null || true
    """

    archiveArtifacts artifacts: "build-${buildNumber}.log", fingerprint: true
}