Jenkins - Continuous Deployment
Jenkins - Pipeline Workflows & Continuous Deployment
Section titled “Jenkins - Pipeline Workflows & Continuous Deployment”Continuous Deployment (CD) extends Continuous Integration by automating the deployment of every validated change directly into production. Jenkins Pipelines are the primary mechanism for defining and executing these complex end-to-end workflows.
A typical CI/CD workflow involves multiple stages:
Code Commit -> Build -> Unit Test -> Static Analysis -> Integration Test -> (Optional Manual Approval) -> Deploy to Staging -> Automated Acceptance Test -> (Optional Manual Approval) -> Deploy to Production -> Post-Deployment Monitoring
Jenkins allows you to model this flow using the stages within a Jenkinsfile.
Note: The older ‘Build Pipeline Plugin’ and ‘Delivery Pipeline Plugin’ provided visualizations but are largely superseded by the built-in Pipeline capabilities and visualization provided by the core Pipeline Stage View or the Blue Ocean plugin.
Building a Multi-Stage Deployment Pipeline
Section titled “Building a Multi-Stage Deployment Pipeline”Let’s enhance a basic build pipeline to include deployment stages.
Example Declarative Pipeline (Conceptual)
Section titled “Example Declarative Pipeline (Conceptual)”pipeline { agent any // Define agent globally or per stage
environment { // Define environment variables accessible across stages STAGING_SERVER = 'staging.example.com' PROD_SERVER = 'prod.example.com' APP_NAME = 'my-web-app' // Credentials should be loaded securely, not hardcoded DEPLOY_CREDENTIAL_ID = 'ssh-deploy-key' }
options { // Automatically clean workspace before build // cleanWs() // Keep only the last 5 builds buildDiscarder(logRotator(numToKeepStr: '5', artifactNumToKeepStr: '3')) // Timeout for the entire pipeline timeout(time: 1, unit: 'HOURS') }
stages { stage('Checkout') { steps { git url: 'https://github.com/your-org/your-repo.git', branch: 'main', credentialsId: 'github-credentials' } }
stage('Build') { agent { label 'build-agent' } // Use a specific agent if needed steps { echo "Building ${env.APP_NAME}..." sh 'mvn clean package -DskipTests' // Archive the artifact for later stages archiveArtifacts artifacts: 'target/*.war', fingerprint: true } }
stage('Unit & Integration Tests') { agent { label 'test-agent' } // Agent might need DB access steps { echo 'Running tests...' sh 'mvn verify' } post { always { junit '**/target/surefire-reports/*.xml' junit '**/target/failsafe-reports/*.xml' } } }
stage('Static Analysis') { steps { echo 'Running Checkstyle, SpotBugs...' // Example: sh 'mvn checkstyle:check spotbugs:check' } post { always { // Requires Warnings Next Generation plugin recordIssues tools: [ checkStyle(pattern: '**/target/checkstyle-result.xml'), spotbugs(pattern: '**/target/spotbugsXml.xml') ] } } }
// --- Continuous Delivery Point --- // Code passing up to here is potentially releasable
stage('Deploy to Staging') { steps { echo "Deploying ${env.APP_NAME} to Staging (${env.STAGING_SERVER})..." // Unarchive artifact from build stage unarchiveMapping(mapping: ['target/*.war': '.']) // Example using SSH sshagent(credentials: [env.DEPLOY_CREDENTIAL_ID]) { sh "scp *.war user@${env.STAGING_SERVER}:/path/to/deploy/" sh "ssh user@${env.STAGING_SERVER} /path/to/restart-script.sh" } } }
stage('Acceptance Tests on Staging') { agent { label 'acceptance-test-agent' } // Agent with testing tools/browsers steps { echo 'Running acceptance tests against staging environment...' // Example: sh 'run-selenium-tests.sh --env=staging' // Example: sh 'npx cypress run --env environment=staging' } post { always { // Publish acceptance test results junit '**/test-results/acceptance/*.xml' // publishHTML ... for HTML reports } } }
// --- Continuous Deployment Point --- // If this stage runs automatically, it's Continuous Deployment
stage('Deploy to Production') { // Add an input step for manual approval before production deployment input { message "Deploy ${env.APP_NAME} ${env.BUILD_NUMBER} to Production?" ok 'Yes, Deploy to Production' submitter 'approver-group,admin-user' // Optional: Restrict who can approve } steps { echo "Deploying ${env.APP_NAME} to Production (${env.PROD_SERVER})..." // Deployment steps similar to staging, but targeting production server unarchiveMapping(mapping: ['target/*.war': '.']) sshagent(credentials: [env.DEPLOY_CREDENTIAL_ID]) { sh "scp *.war user@${env.PROD_SERVER}:/path/to/deploy/" sh "ssh user@${env.PROD_SERVER} /path/to/restart-script.sh" } } } }
post { // Notifications for overall pipeline status success { slackSend channel: '#deployments', message: "SUCCESS: Pipeline '${env.JOB_NAME} [${env.BUILD_NUMBER}]' completed successfully. Deployed to Production." } failure { slackSend channel: '#alerts', color: 'danger', message: "FAILURE: Pipeline '${env.JOB_NAME} [${env.BUILD_NUMBER}]' failed. (${env.BUILD_URL})" } }}Key Concepts for CD Pipelines
Section titled “Key Concepts for CD Pipelines”- Pipeline as Code (Jenkinsfile): Defining the entire workflow in a
Jenkinsfilestored in version control is crucial for repeatability, collaboration, and disaster recovery. - Stages: Break down the workflow into logical steps (Build, Test, Deploy Staging, Deploy Prod).
- Artifact Management: Use
archiveArtifactsto save build outputs andunarchiveMappingorstash/unstashto pass them between stages, especially if stages run on different agents. - Environment Variables: Use the
environmentblock to define configuration reused across stages. - Credentials: Store all secrets (API keys, passwords, SSH keys) securely using the Jenkins Credentials system and access them via bindings (
withCredentialsstep) or directly in steps that support them (likegit,sshagent). - Manual Approval: Use the
inputstep to pause the pipeline and require human confirmation before critical actions like production deployments. - Conditional Execution: Use the
whendirective to skip stages based on conditions (e.g., only run deployment stage on the main branch). - Notifications: Use the
postblock to send notifications (Email, Slack, Teams) based on the final pipeline status or stage status.
Visualization
Section titled “Visualization”Jenkins provides built-in visualization for Pipelines:
- Pipeline Stage View: The default view on the classic UI build page shows stages, their status, and duration.
- Blue Ocean Plugin: Offers a modern, graphical representation of the pipeline flow, highlighting successes, failures, logs per stage, and pending inputs. Highly recommended for visualizing complex pipelines.
By leveraging Jenkins Pipelines and best practices, you can build robust, automated workflows for Continuous Delivery or Continuous Deployment.