diff --git a/docker-dive-pipeline.groovy b/docker-dive-pipeline.groovy new file mode 100644 index 00000000..49b181f3 --- /dev/null +++ b/docker-dive-pipeline.groovy @@ -0,0 +1,67 @@ +pipeline { + agent any + + environment { + DOCKER_REPOSITORY = 'onurozcelikse/nginx-demos' + LOWEST_EFFICIENCY = '0.95' + HIGHEST_USER_WASTED_PERCENT = '0.20' + HIGHEST_WASTED_BYTES = '20MB' + } + + parameters { + string(name: 'BUILD_NUMBER', description: 'Build number from the previous pipeline') + } + + + stages { + stage('Pull Docker Image') { + steps { + script { + // Get the BUILD_NUMBER parameter + def buildNumber = params.BUILD_NUMBER + + // Define the tagged image + def dockerTaggedImage = "${DOCKER_REPOSITORY}:${buildNumber}" + + // Pull the Docker image + sh "docker pull ${dockerTaggedImage}" + } + } + } + + stage('Analyze Tagged Docker Image with Dive') { + steps { + script { + // Get the BUILD_NUMBER parameter + def buildNumber = params.BUILD_NUMBER + + // Define the tagged image + def dockerTaggedImage = "${DOCKER_REPOSITORY}:${buildNumber}" + // Define the Dive command with parameters + def diveCommand = "dive --ci --lowestEfficiency \"${env.LOWEST_EFFICIENCY}\" --highestUserWastedPercent \"${env.HIGHEST_USER_WASTED_PERCENT}\" --highestWastedBytes \"${env.HIGHEST_WASTED_BYTES}\" ${dockerTaggedImage}" + + // Execute Dive and capture the status + def status = sh(script: diveCommand, returnStatus: true) + + if (status == 0) { + echo "Dive analysis completed successfully for ${dockerTaggedImage}." + } else { + error("Dive found inefficiencies in the ${dockerTaggedImage} Docker image.") + } + + // Execute Dive and capture the output + def diveOutput = sh(script: diveCommand, returnStdout: true).trim() + + // Parse the Dive output to extract and print the desired values + def efficiency = (diveOutput =~ /efficiency:\s+([\d.]+ %)/)[0][1] + def userWastedPercent = (diveOutput =~ /userWastedPercent:\s+([\d.]+ %)/)[0][1] + def wastedBytes = (diveOutput =~ /wastedBytes:\s+([\d,]+ bytes)/)[0][1] + + echo "Lowest Efficiency: ${efficiency}" + echo "Highest User Wasted Percent: ${userWastedPercent}" + echo "Highest Wasted Bytes: ${wastedBytes}" + } + } + } + } +} diff --git a/nginx_pipeline.groovy b/nginx_pipeline.groovy new file mode 100644 index 00000000..be64082f --- /dev/null +++ b/nginx_pipeline.groovy @@ -0,0 +1,72 @@ +pipeline { + agent any + + environment { + DOCKER_REPOSITORY = 'onurozcelikse/nginx-demos' + } + + stages { + stage('Clone Repository') { + steps { + // Checkout the Git repository + checkout([$class: 'GitSCM', branches: [[name: '*/master']], userRemoteConfigs: [[url: 'https://github.com/OnurOzcelikSE/NGINX-Demos.git']]]) + echo 'Repository cloned' + } + } + stage('Build Docker Image') { + steps { + script { + // Define the Docker image tag + def dockerImageTag = "${DOCKER_REPOSITORY}:${env.BUILD_NUMBER}" + + // Use withCredentials to securely pass Docker Hub credentials + withCredentials([usernamePassword(credentialsId: 'DOCKER_HUB_CREDENTIALS', usernameVariable: 'DOCKER_USERNAME', passwordVariable: 'DOCKER_PASSWORD')]) { + echo 'Logged in to DockerHub securely' + + // Use --password-stdin to securely pass the password to docker login + sh """ + echo \${DOCKER_PASSWORD} | docker login --username \${DOCKER_USERNAME} --password-stdin docker.io + docker build -t ${dockerImageTag} ./nginx-hello + """ + echo 'Docker image built' + } + } + } + } + + stage('Push Docker Image') { + steps { + script { + // Define the Docker image tag again + def dockerImageTag = "${DOCKER_REPOSITORY}:${env.BUILD_NUMBER}" + + // Push the Docker image + sh "docker push ${dockerImageTag}" + echo 'Docker image pushed' + } + } + } + + stage('Clean Up') { + steps { + script { + // Define the image name for cleanup + def imageName = "${DOCKER_REPOSITORY}:${env.BUILD_NUMBER}" + + // Remove the Docker image + sh "docker rmi ${imageName}" + echo 'Cleanup completed' + } + } + } + + stage('Trigger Next Pipeline') { + steps { + script { + def buildNumberString = env.BUILD_NUMBER.toString() + build job: 'docker-dive-pipeline', parameters: [string(name: 'BUILD_NUMBER', value: buildNumberString)] + } + } + } + } +}