title: How do I retry an input step in groovy pipeline if input is determined to be invalid later in that stage?
body: <p>I am building a Jenkins declarative pipeline for code release automation.</p>
  <p>Our pipeline has a few different steps.</p>
  <p>First, an email is sent out to one set of approvers who are directed to an input step where the input is pretty meaningless.</p>
  <p>Second, an email is sent to a second set of approvers who directed to an input step and are asked to put in a ticket number.</p>
  <p>The ticket number is then determined to be:</p>
  <ol>
  <li>Valid and existing</li>
  <li>In the correct state.</li>
  </ol>
  <p>If either of these conditions are not met, the pipeline quits and we must do the entire pipeline again. How do I give these approvers a second chance to input the ticket without restarting the pipeline?</p>
  <p>Here is my code for the particular step in question:</p>
  <pre><code>stage (&quot;Awaiting RM input approval&quot;) {
              steps {
                  script {
                      try {
                          timeout(time: 5, unit: 'DAYS') {
                              def desc = &quot;&quot;&quot;Please input Change Ticket for release. &lt;br&gt;&lt;br&gt;
  
                                  ${releaseInfo}&quot;&quot;&quot;
                              userInput_RM = input(
                                      id: 'Approval by RM', message: &quot;GO-NO-GO Approval for Release ${BRANCH_NAME}&quot;, parameters: [
                                      [$class: 'StringParameterDefinition', defaultValue: &quot;&quot;, description: desc, name: 'ChangeTicket']
                              ], submitter: approvers_RM, submitterParameter: &quot;submitter&quot;)
  
                              if (userInput_RM.ChangeTicket.equals(&quot;&quot;)) {
                                  println(&quot;NO change ticket Listed.&quot;)
                                  throw new Exception(&quot;No Change Ticket Number Listed.&quot;)
                              }
  
                              println(&quot;Approved by ${userInput_RM.submitter}&quot;)
                          }
                      } catch (e) {
                          println(&quot;Pipeline was aborted&quot;)
                          error(&quot;Approval aborted&quot;)
                      }
                  }
              }
          }
  </code></pre>
  <p>And here are the validation steps:</p>
  <pre><code>stage(&quot;Check CHG validity and check status&quot;) {
              agent { label 'docker-maven-slave' }
              stages {
                  stage(&quot;Check CHG validity&quot;) {
                      steps {
                          script {
                              dir(&quot;release-automation&quot;) {
                                  if ( userInput_RM.ChangeTicket.size() != 0 &amp;&amp; userInput_RM.ChangeTicket.startsWith('CHG')) {
                                      withCredentials([usernamePassword(credentialsId: 'test_servicenow_creds', usernameVariable: 'SN_USER', passwordVariable: 'SN_PASSWORD')]) {
                                          withPythonEnv('/tools/python/python3.6/bin/python3') {
                                              sh &quot;python -m pip install -r ${WORKSPACE}/python/requirements.txt&quot;
                                              def isValid = sh returnStatus: true, script: &quot;python3 ${WORKSPACE}/python/is_valid_chg.py --step validChange --change_num ${userInput_RM.ChangeTicket}&quot;
                                              if (isValid == 1) {
                                                  println(&quot;Erroring out due to invalid change ticket&quot;)
                                                  currentBuild.result = 'ABORTED'
                                                  error(&quot;Please rerun the job and enter a valid change ticket&quot;)
                                              } else {
                                                  println(&quot;CHG ticket is valid&quot;)
                                              }
                                          }
                                      }
                                  } else {
                                      currentBuild.result = 'ABORTED'
                                      error(&quot;Change ticket must start with CHG&quot;)
                                  }
                              }
                          }
                      }
                  }
                  stage(&quot;Get SN Status&quot;) {
                      steps {
                          script {
                              dir(&quot;release-automation&quot;) {
                                  withCredentials([usernamePassword(credentialsId: 'test_servicenow_creds', usernameVariable: 'SN_USER', passwordVariable: 'SN_PASSWORD')]) {
                                      snStatus = sh(returnStdout: true, script: &quot;python ${WORKSPACE}/python/is_valid_chg.py --step getStatus --change_num ${userInput_RM.ChangeTicket}&quot;).toString().trim()
                                  }
                              }
                          }
                      }
                  }
              }
          }
  </code></pre>
  <p>Ideally, I will move the validation steps into the same stage so then it will be as simple as restarting that stage.</p>
  <p>I have tried checkpoints, but I think retry is a more viable option. Any ideas?</p>