Jenkins Pipeline: “input” step blocks executor

匿名 (未验证) 提交于 2019-12-03 01:55:01

问题:

After going through the pipeline and Jenkinsfile documentation, I am a bit confused on how to create a Stage -> Production pipeline.

One way is to use the input step like

node() {   stage 'Build to Stage'   sh '# ...'    input 'Deploy to Production'   stage 'Build to Production'   sh '# ...' } 

This seems a bit clunky, as this will block an executor all the time until you want to deploy to production. Is there any alternative way of being able to deploy to production, from Jenkins.

回答1:

EDIT (Oct 2016): Please see my other answer "Use milestone and lock" below, which includes recently introduced features.

Use timeout Step

As first option, you can wrap your sh step into a timeout step.

node() {   stage 'Build to Stage' {     sh '# ...'   }    stage 'Promotion' {     timeout(time: 1, unit: 'HOURS') {       input 'Deploy to Production?'     }   }    stage 'Deploy to Production' {     sh '# ...'   } } 

This stops the build after the timeout.

Move input Step to Flyweight Executor

Another option is to not allocate a heavyweight executor for the input step. You can do this by using the input step outside of the node block, like this:

stage 'Build to Stage' {   node {       sh "echo building"       stash 'complete-workspace'   } }  stage 'Promotion' {   input 'Deploy to Production?' }  stage 'Deploy to Production' {   node {     unstash 'complete-workspace'     sh "echo deploying"   } } 

This is was probably the more elegant way, but can still be combined with the timeout step.

EDIT: As pointed out by @amuniz, you have to stash/unstash the contents of the workspace, as different nodes respectively workspace directories might be allocated for the two node steps.



回答2:

Given the recent advances of Jenkins pipelines, the probably best way would be the following (source: jenkins.io/blog):

Use milestone and lock

  • The lock step (from the lockable-resources plugin) allows to lock some specified resource so that only a single pipeline execution can enter this stage simultaneously (you don't want to run two deployments simultaneously, don't you?)
  • The milestone step (from the pipeline-milestone-step plugin) will abort any older pipeline executions, if a more recent commit already reached the milestone (you don't want to let an older commit that hangs longer in CI overwrite the deployment of a newer commit, don't you?).
stage('Deploy') {   input "Deploy?"   milestone()   lock('Deployment') {     node {       echo "Deploying"     }   } } 

The Deploy stage does not limit concurrency but requires manual input from a user. Several builds might reach this step waiting for input. When a user promotes a specific build all preceding builds are aborted, ensuring that the latest code is always deployed.

I recommend to read the whole story, which includes further helpful information.

Credits go to @amuniz, who is maintaining these plugins.



回答3:

You have to use the input step outside any node block, so it does not hold any executor:

stage 'Build' node('build-node') {   sh 'call you build tool'   stash includes: 'target/my-output-artifact.whatever', name: 'built' }  input 'Continue to deploy stage?'  stage 'Deploy' node('deploy-node') {   unstash 'built'   sh 'scp target/my-output-artifact.whatever user@deploy-server:/deploy' } 

And you can lock the deploy stage if you want only one deploy at time:

lock ('deploy-server') {   stage 'Deploy'   node('deploy-node') {     unstash 'built'     sh 'scp target/my-output-artifact.whatever user@deploy-server:/deploy'   } } 

Note that the key part here is the stash step as you can move artifacts from one node to another (you could share the same node for both actions but the workspace is not granted to be untouched between the two node calls, specially if some time passes waiting on input).



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!