Declarative pipeline with loop and input timeout

4,251 views
Skip to first unread message

Guy Knights

unread,
Aug 1, 2017, 3:17:42 PM8/1/17
to jenkins...@googlegroups.com
I have an input step in a declarative pipeline and I want to add some logic so that if the input step waits too long for someone to proceed, it will send a reminder notification and loop, starting a new timeout.

What I have so far is this:

waitUntil {
          timeout(time: 3, unit: 'MINUTES' ) {
            input message: "Deploy ${CODE} codebase to ${ENVIRONMENT}?", ok: 'Deploy'
          }
          slackSend (channel: "${slack_channel}", color: 'good', message: "Notification: ${env.JOB_NAME} is waiting for deployment")
}

Unfortunately, I don't know how to trigger a 'FALSE' when the timeout is exceeded - which, as I understand it, is what is required to cause the waitUntil to loop again. I initially had return statements in the above code, but jenkins was giving me an error "Expected a step" when it hit them.

How would I make the code above loop until the user hits the 'Deploy' option for the input step?

Thanks,
Guy

Guy Knights

unread,
Aug 15, 2017, 2:22:08 PM8/15/17
to Jenkins Users
Does anyone have any suggestions for how I can make this work?

Thanks,
Guy

Victor Martinez

unread,
Aug 15, 2017, 4:49:07 PM8/15/17
to Jenkins Users
I did a kind of similar but not equally implementation. The important bit is to try/catch and ensure the last true/false command is in the right logic, please read the below:

My use case was to run a certain Integration Test, then if it failed for whatever reason, prompt to the user whether to rerun them again with a certain timeout to avoid infinite waits.

    stage('TestCase') {
      steps {
        script {
          def filter = 'all'
          waitUntil {
            def bRun = build job: 'jobX', propagate: false  // To avoid failfast/propagate errors
            if (bRun.getRawBuild().result.isWorseOrEqualTo(hudson.model.Result.FAILURE)) {
              def userInput = true
              def didTimeout = false
              def inputValue
              try {
                // Timeout in case to avoid running this forever
                timeout(time: 60, unit: 'SECONDS') {
                  inputValue = input(
                  id: 'userInput', message: 'jobX failed let\'s rerun it?', parameters: [
                    [$class: 'BooleanParameterDefinition', defaultValue: true, description: '', name: 'Please confirm you agree with this']
                  ])
                }
              } catch(err) { // timeout reached or input false
                echo err.toString()
                def user = err.getCauses()[0].getUser()
                if('SYSTEM' == user.toString()) { // SYSTEM means timeout.
                  didTimeout = true
                } else {
                  userInput = false
                  echo "Aborted by: [${user}]"
                }
              }
              if (didTimeout) {
                echo "no input was received before timeout"
                false // false will cause infinite loops but it's a way to keep retrying, otherwise use true and will exit the loop
              } else if (userInput == true) {
                echo "this was successful"
                false // if user answered then iterate through the loop again
              } else {
                echo "this was not successful"
                currentBuild.result = 'ABORTED'
                true  // if user aborted the input then exit the loop
              }
            } else {
              currentBuild.result = 'SUCCESS'
              true  // if build finished successfully as expected then exit the loop
            }
          }
        }
      }
    }

The above snippet was based on the below how-to:

I hope it helps

Guy Knights

unread,
Aug 16, 2017, 12:25:21 PM8/16/17
to jenkins...@googlegroups.com
Thanks Victor, I'll take a look at it when I get a chance and see if I can use your solution.

Cheers,
Guy

--
You received this message because you are subscribed to a topic in the Google Groups "Jenkins Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-users/upVzT3SOZy8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-users+unsubscribe@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/dc49bafb-5772-4f03-9ff3-81bb465a8953%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages