26

Jenkins 2 has pipelines has a first class citizen. However, in the examples the tasks seem to be executed as a single sequence:

node {
   // Mark the code checkout 'stage'....
   stage 'Checkout'

   // Get some code from a GitHub repository
   git url: 'git@github.com:elifesciences/elife-bot.git'

   // Mark the code build 'stage'....
   stage 'Build'
   echo "Unit tests will run here"

   stage "Production"
   echo "Deploying to production environment"
}

For deployment into production system it's often useful to require manual approval; is there a way to insert a manual button to press inside a pipeline?

I have been looking for possible steps to accomplish this on the docs, to no avail.

giorgiosironi
  • 503
  • 2
  • 6
  • 9
  • I don't know Jenkins, but isn't there a way to split your build plan into several steps, and having some of these steps be run only on a "manual trigger"? – tiktak May 05 '16 at 16:06
  • Best partial solution so far: an `input` step in the pipeline which stops and asks the user for input (or to abort the build). However, the stage and the status indicator keeps flashing while I wanted a stable state (e.g. you get into it Friday afternoon and decide to deploy on Monday.) – giorgiosironi May 06 '16 at 12:19

5 Answers5

23

input is the option you are looking for. Here is the way I'm using it. It's important to have the step outside a node, otherwise jenkins will hold an agent waiting for the next step. Keep in mind the second node may not use the same workspace as the first.

node {
    stage('build'){
        echo "building"
    }
}
stage('Deploy approval'){
    input "Deploy to prod?"
}
node {
    stage('deploy to prod'){
        echo "deploying"
    }
}
  • Given multiple pipelines can get there, what happens to the older ones who do not get deployed to production? Is there a way to stop the older ones from remaining there (don't know if they will be flashing) in an incomplete state? – giorgiosironi Feb 17 '17 at 15:57
  • 1
    as far as i can tell it will flash forever until you click abort, which is pretty crappy. you could probably setup a timeout to prevent some of these from getting lost. After the timeout you would lose the ability to deploy it though. https://jenkins.io/doc/pipeline/steps/workflow-basic-steps/#code-timeout-code-enforce-time-limit – Steve Miskiewicz Feb 17 '17 at 17:56
  • 2
    I didn't understand that input could be configured to *not* hold up an agent. This makes input way more useful. – djhaskin987 Dec 06 '17 at 18:30
  • 1
    Would be nice to have the possibility to redeploy a version, without building, or to deploy the previous version. – tehnicaorg Jul 18 '19 at 12:50
  • It would be nice if one could specify who is allowed to give the approval, perhaps based the internal jenkins roles. – Bernie Lenz Oct 27 '20 at 20:46
  • When I tried this I got a couple errors including `"Expected a block for input"` and `"No message specified for input"` and `"Expected one of "steps", "stages", or "parallel" for stage "Approval"`. – Sam Oct 13 '21 at 21:14
  • Ok -- so I think if you use `input` as a declarative block then you also need to provide a `steps` block as well. I put the `steps` block in the same stage and had it echo out a simple message like what you have "deploying". – Sam Oct 13 '21 at 21:27
3

I did in as shown below way by reading this docs https://jenkins.io/doc/book/pipeline/syntax/

pipeline {
environment {
    BRANCH_NAME = "${env.BRANCH_NAME}"
}
agent any
stages{
    stage('Build-Initiator-Info'){
            steps{
                sh 'echo "Send Info"'
            }
    }
    stage('Build') {
        steps{
             catchError {
                sh 'echo "This is build"'
            }
         }
         post {
            success {
                echo 'Compile Stage Successful . . .'
            }
            failure {
                echo 'Compile stage failed'
                error('Stopping early…')

             }
    }
   }
  stage ('Deploy To Prod'){
  input{
    message "Do you want to proceed for production deployment?"
  }
    steps {
                sh 'echo "Deploy into Prod"'

              }
        }
  }
   }
user5956891
  • 131
  • 4
2

Additionally, You can also add auto-timeout like below

        stage('build') {
        steps {
            sh  """
                # Some commands
                """
            script {
              timeout(time: 10, unit: 'MINUTES') {
                input(id: "Deploy Gate", message: "Deploy ${params.project_name}?", ok: 'Deploy')
              }
            }
        }
    }

    stage('deploy') {
        when {
            branch 'master'
        }
        steps {
            sh  """
                # some commands
                """
        }
    }

If you look it up you can also bind the jenkins input to credentials of users accessing Jenkins if you only wish to permit specific individuals to be capable of answering - it also is underpinned by the fact that your Git controls are sufficient too.

Kru
  • 21
  • 3
  • Thank you. I tried a couple of syntaxes for input, but this was the only one that ended up working for me. – Sam Oct 13 '21 at 21:15
1

In the end I created separate test-project and prod-project pipelines, where at the end of test-project the code is merged into an approved branch.

Then, the prod-project pipeline can be set up not to trigger for every new commit so that it can be deployed on-demand.

giorgiosironi
  • 503
  • 2
  • 6
  • 9
0

This is just a simple example but you can trigger it however you need.

stage{
    script{
        input "Continue?"
        ...enter code here
        ...
    }
}
Oren
  • 1