Search code examples
jenkinsjenkins-pipelinejenkins-declarative-pipeline

Jenkins input on declarative pipeline


may I ask if it is do-able if I can get the user input and run a script based on what was chosen by the user? the logic whould be

IF User choose Proceed THEN run a script (in my case promote or Blue/Green deployment) IF User choose Abort THEN don't terminate the jenkins job, run a script (in my case rollback)

This is the script I'm using however I have no idea how to apply after validate stage

  pipeline {
  agent any

  stages {
    stage('Deploy') {
      steps {
        sh """#!/bin/bash +x
          echo "performing sts assume role"
          //SCRIPT-HERE//        
          echo "performing ansible deploy"
          //SCRIPT-HERE//  
        """
      }
    }
    stage('validate') {
        steps {

            timeout(30) {
                script {
                    input(message: 'Please validate, this job will automatically ABORTED after 30 minutes even if no user input provided', ok: 'Proceed')
                }
            }
        }
    }
  }

}

One more issue I'm seeing is, although this pipeline script is running, The Proceed / Abort is not clickable on the jenkins job Console output, is it a bug? I'm referring to the image shown below

enter image description here

I was able to add nandilov's suggestion however it seems that the logic is still not applying, please advise on what is missed here

pipeline {
  agent any

  stages {
    stage('Deploy') {
      steps {
        sh """#!/bin/bash +x
          echo "performing sts assume role"

          echo "performing ansible deploy"

        """
      }
    }
    stage('validate') {
        steps {
          script {
            env.flagError = "false"
              try {
              input(message: 'Please validate, this job will automatically ABORTED after 30 minutes even if no user input provided', ok: 'Proceed')

              }catch(e){
                println "input aborted or timeout expired, will try to rollback."
                env.flagError = "true"        
              }
          }
        }
    }

    stage("If user selects Proceed"){
        when{
            expression { env.inputValue == "value1" }
        }
        steps{
            sh """#!/bin/bash +x
              echo "User selected proceed"
            """
        }
    }

    stage("rollback if flag error true"){
        when{
            expression { env.inputValue == "value2" }
        }
        steps{
            sh """#!/bin/bash +x
              echo "User selected Abort"
            """
        }
    }

  }

}

from the pipeline view it never triggered either one of the last two stages when choosing "Abort" or "Proceed"

enter image description here

These are the logs when choosing Abort or Proceed

ABORT

Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/test-job-lagot
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Deploy)
[Pipeline] sh
performing sts assume role
performing ansible deploy
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (validate)
[Pipeline] script
[Pipeline] {
[Pipeline] input
Please validate, this job will automatically ABORTED after 30 minutes even if no user input provided
Proceed or Abort
[Pipeline] echo
input aborted or timeout expired, will try to rollback.
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (If user selects Proceed)
Stage "If user selects Proceed" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (rollback if flag error true)
Stage "rollback if flag error true" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

PROCEED

Started by user lagot
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/test-job-lagot
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Deploy)
[Pipeline] sh
performing sts assume role
performing ansible deploy
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (validate)
[Pipeline] script
[Pipeline] {
[Pipeline] input
Please validate, this job will automatically ABORTED after 30 minutes even if no user input provided
Proceed or Abort
Approved by lagot
[Pipeline] }
[Pipeline] // script
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (If user selects Proceed)
Stage "If user selects Proceed" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] stage
[Pipeline] { (rollback if flag error true)
Stage "rollback if flag error true" skipped due to when conditional
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
Finished: SUCCESS

Solution

  • If you want to have the job aborted and do something, you can try/catch it:

    try{
        input(message: 'Please validate, this job will automatically ABORTED after 30 minutes even if no user input provided', ok: 'Proceed')
    }catch(e){
        println "input aborted or timeout expired, will try to rollback."
        // execute rollback
    }
    
    

    You also can do it in another stage:

    pipeline {
      agent any
    
      stages {
        stage('Deploy') {
          steps {
            sh """#!/bin/bash +x
              echo "performing sts assume role"
    
              echo "performing ansible deploy"
    
            """
          }
        }
        stage('validate') {
            steps {
              script {
                env.flagError = "false"
                  try {
                  input(message: 'Please validate, this job will automatically ABORTED after 30 minutes even if no user input provided', ok: 'Proceed')
    
                  }catch(e){
                    println "input aborted or timeout expired, will try to rollback."
                    env.flagError = "true"        
                  }
              }
            }
        }
    
        stage("If user selects Proceed"){
            when{
                expression { env.flagError == "false" }
            }
            steps{
                sh """#!/bin/bash +x
                  echo "User selected proceed"
                """
            }
        }
    
        stage("rollback if flag error true"){
            when{
                expression { env.flagError == "true" }
            }
            steps{
                sh """#!/bin/bash +x
                  echo "User selected Abort"
                """
            }
        }
    
      }