Jenkins 管道:"input" 步骤块执行程序

Jenkins Pipeline: "input" step blocks executor

阅读 pipeline and Jenkinsfile 文档后,我对如何创建 Stage -> Production 管道感到有些困惑。

一种方法是使用 input 步骤,例如

node() {
  stage 'Build to Stage'
  sh '# ...'

  input 'Deploy to Production'
  stage 'Build to Production'
  sh '# ...'
}

这看起来有点笨拙,因为这会一直阻塞执行程序,直到您想要部署到生产环境。是否有任何其他方法可以从 Jenkins 部署到生产环境。

编辑(2016 年 10 月):请参阅下面我的其他回答 ,其中包括最近引入的功能。

使用timeout步骤

作为第一个选项,您可以将 sh 步骤包装成 timeout 步骤。

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

  stage 'Promotion' {
    timeout(time: 1, unit: 'HOURS') {
      input 'Deploy to Production?'
    }
  }

  stage 'Deploy to Production' {
    sh '# ...'
  }
}

这会在超时后停止构建。

input 步骤移动到享元执行器

另一种选择是不为 input 步骤分配重量级执行程序。您可以通过在 node 块之外使用 input 步骤来执行此操作,如下所示:

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"
  }
}

这个 可能是更优雅的方式,但仍然可以与 timeout 步骤结合使用。

编辑:正如@a​​muniz 所指出的,您必须 stash/unstash 工作区的内容,因为可能会为两个 node 步骤分配不同的节点和工作区目录。

您必须在任何节点块之外使用输入步骤,因此它不包含任何执行程序:

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'
}

如果您一次只想部署一个,您可以锁定部署阶段:

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

请注意,这里的关键部分是 stash 步骤,因为您可以 工件从一个节点移动到另一个节点(您可以为两个操作共享同一个节点,但是不允许在两个节点调用之间保持工作区不变,特别是如果等待 input).

鉴于 Jenkins 管道的最新进展,可能最好的方法如下(来源:jenkins.io/blog):

使用milestonelock

  • lock step (from the lockable-resources 插件)允许锁定一些指定的资源,这样只有一个管道执行可以同时进入这个阶段(你不想 运行 同时部署两个,是吗? )
  • milestone step (from the pipeline-milestone-step 插件)将中止任何旧的管道执行,如果更新的构建已经达到里程碑(你不想让在 CI 中挂起更长时间的旧构建覆盖部署更新版本,你呢?)。
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.

我建议阅读 the whole story,其中包含更多有用信息。

感谢维护这些插件的 @amuniz