Search code examples
jenkinsgroovyjenkins-pipelinejenkins-groovy

I don't want the jenkins to hold onto the agent for approval step. How can I do that?


I am trying to write a jenkins pipeline wherein, my jobs shouldn't hold onto the slave executers while waiting on the input. This is an inappropriate way to wait on input as it makes those nodes unavailable to other users while, at the same time, they’re sitting idle and waiting. So, I am trying to write a pipeline job in such a way that they're waiting outside the block. Below is my groovy script which gets called by the Jenkinsfile. Here in the below code, I don't want agent holding onto the approval step waiting for the input. How can I do that?

void call(Map configuration = [:], env) {
    pipeline{
        agent { label 'docker-kitchensink-slave' }

        environment {
            K8S_DEV_NS_TOKEN= "dev-ns-cicd"
            K8S_TEST_NS_TOKEN= "test-ns-cicd"
        }

        stages{
            stage('Checkout') {
                steps{
                    checkout scm
                }
            }

            // Maven Build and Unit Tests Dev
            stage('Maven Build and Unit Tests') {
                steps{
                    build(configuration)
                }
            }

            // SonarQube Analysis
            stage('SonarQube analysis') {
                steps{
                    sonarQubeGating(configuration)
                }
            }

            // Build Docker Image and Push to Artifactory
            stage('Build Docker Image and Push to Artifactory') {
                steps{
                    artifactoryImagePush(configuration)
                }
            }

            // Approve DEV Deployment
            stage('Approve K8s Dev Deployment') {
                steps{
                    approveDeployment()
                }
            }

            // Create and Deploy to Dev Environment
            stage('Create and Deploy to k8s Dev Environment') {
                steps {
                    withCredentials([string(credentialsId: "$env.K8S_DEV_NS_TOKEN", variable: 'DEV_TOKEN')]) {
                        kubernetesDeploy(Env: 'dev', Token: "${DEV_TOKEN}")
                    }
                }
            }

            // Approve TEST Deployment
            stage('Approve K8s Test Deployment') {
                steps{
                    approveDeployment()
                }
            }

            // Create and Deploy to Test Environment
            stage ('Create and Deploy to k8s Test Environment') {
                options {
                    skipDefaultCheckout()
                }
                steps {
                    withCredentials([string(credentialsId: "$env.K8S_TEST_NS_TOKEN" , variable: 'TEST_TOKEN')]) {
                        kubernetesDeploy(Env: 'test', Token: "${TEST_TOKEN}")
                    }
                }
            }
        }
    }
}

Solution

  • I was able to get it working directly by something like this. The key point is that the agent has to be specified for each stage so that you can wait without tying up an agent. Additionally, you have to manually checkout as that requires an agent as well. The milestones are not strictly needed but stop you from deploying older waiting jobs by cancelling any that are older than the job being run.

    pipeline {
        agent none
    
        options { skipDefaultCheckout() }
        
        stages {
            stage ('Checkout') {
                agent { label 'build' }
                steps {
                    checkout scm
                }
            }
            
            stage ('Build') {
                agent { label 'build' }
                steps {
                    milestone 1
                    echo "Build steps"
                }
            }
            
            stage ('Deploy dev') {
                agent { label 'build' }
                when {
                    expression {
                        input message: 'Deploy dev?'
                        return true
                    }
                    beforeAgent true
                }
                steps {
                    milestone 2
                
                    echo "deploy dev"
                }
            }
                
            stage ('Deploy test') {
                agent { label 'build' }
                when {
                    expression {
                        input message: 'Deploy test?'
                        return true
                    }
                    beforeAgent true
                }
                steps {
                    milestone 3
                    
                    echo "deploy test"
                }
            }
        }
    }