当前位置: 首页 > 面试题库 >

Jenkins管道可以有一个可选的输入步骤吗?

孔星宇
2023-03-14
问题内容

是否可以创建具有可选输入阶段的Jenkins管道?

以下代码段未实现此目标。

预期行为

该阶段(以及输入提示)仅应针对特定分支运行。

实际行为

此阶段适用于所有分支。使用输入步骤时,将忽略when过滤器。

stage('Approve') {
            when {
                expression { BRANCH_NAME ==~ /^qa[\w-_]*$/ }
            }
            input {
                message "Approve release?"
                ok "y"
                submitter "admin"
                parameters {
                    string(name: 'IS_APPROVED', defaultValue: 'y', description: 'Deploy to master?')
                }
            }
            steps {
                script {
                    if (IS_APPROVED != 'y') {
                        currentBuild.result = "ABORTED"
                        error "User cancelled"
                    }
                }
            }
        }

问题答案:

过滤器不会被忽略,它只是在输入步骤之后进行评估。在您的示例中,将始终询问您是否进行部署,并且如果您不在QA分支上,则什么也不会发生。

现在您可以问为什么詹金斯不首先评估“何时”指令。在这种情况下,您将无法在when条件中使用输入参数。

并且具有多个when指令就像在声明性管道中编写脚本。

但是,有一个表达式可以让您控制何时评估“何时”指令。这是beforeAgent。它使您可以在分配代理之前评估when语句。与此类似,您将需要诸如beforeInput之类的东西。您可以为此创建功能请求。

我不再使用input指令,而是现在在脚本块中使用input,因为它提供了更大的灵活性,例如,当有人必须批准某些内容时,我将发送Slack通知,这对于声明式方法是不可能的。您将需要一个notify指令。如果有一个,是否要在输入步骤之前或之后进行评估?

您会发现,进行声明式的操作并不总是最好的方法。因此,我推荐的方法如下(免责声明:未经测试!):

pipeline {
  // We want to use agents per stage to avoid blocking our build agents
  // while we are waiting for user input.
  agent none
  ...
  // The question mark naming convention is helpful to show you which
  //  approval stage belongs to which work stage.
  stage('Release?') {
    // Don't allocate an agent because we don't want to block our
    // slaves while waiting for user input.
    agent none
    when {
      // You forgot the 'env.' in your example above ;)
      expression { env.BRANCH_NAME ==~ /^qa[\w-_]*$/ }
    }
    options {
      // Optionally, let's add a timeout that we don't allow ancient
      // builds to be released.
      timeout time: 14, unit: 'DAYS' 
    }
    steps {
      // Optionally, send some notifications to the approver before
      // asking for input. You can't do that with the input directive
      // without using an extra stage.
      slackSend ...

      // The input statement has to go to a script block because we
      // want to assign the result to an environment variable. As we 
      // want to stay as declarative as possible, we put noting but
      // this into the script block.
      script {
        // Assign the 'DO_RELEASE' environment variable that is going
        //  to be used in the next stage.
        env.DO_RELEASE = input ...
      }
      // In case you approved multiple pipeline runs in parallel, this
      // milestone would kill the older runs and prevent deploying
      // older releases over newer ones.
      milestone 1
    }
  }
  stage('Release') {
    // We need a real agent, because we want to do some real work.
    agent any
    when {
      // Evaluate the 'when' directive before allocating the agent.
      beforeAgent true
      // Only execute the step when the release has been approved.
      environment name: 'DO_RELEASE', value: 'yes'
    }
    steps {
      // Make sure that only one release can happen at a time.
      lock('release') {
        // As using the first milestone only would introduce a race 
        // condition (assume that the older build would enter the 
        // milestone first, but the lock second) and Jenkins does
        // not support inter-stage locks yet, we need a second 
        // milestone to make sure that older builds don't overwrite
        // newer ones.
        milestone 2

        // Now do the actual work here.
        ...
      }
    }
  }


 类似资料:
  • 在Jenkins管道中,我使用构建步骤触发其他几个作业,并向其传递一些参数。除了管道之外,我在可视化我触发的不同工作时遇到了问题。我已经设置了Jenkins Delivery Pipeline插件,但是它的文档非常模糊,我只能可视化管道中的步骤,尽管用阶段和任务名称标记作业。 例子: 我在Jenkins中有两个作业作为管道/工作流作业,具有以下管道脚本: 工作坊: 作业栏: 我如何使它也显示在工作

  • 根据Andrew Bayer的说法,您不应该向其他人注入声明性管道。将来可能会有人支持它,但可能不会。 我目前正在尝试在管道中启动一个管道,但我想知道我需要做什么才能使它工作。jenkins网页上的文档说明,如果新作业或管道与第一个作业或管道位于同一文件夹中,则可以从直接名称或绝对路径调用它。我已经尝试了所有不同的方法,目前我正在尝试一个文件的绝对路径,我刚刚检查过它一秒钟前存在,但它说它不存在。

  • 我试图建立一个jenkins多分支管道,在docker容器中运行我的所有代码验证步骤,然后构建docker映像并将其推出docker容器。 目前,我的 Jenkinsfile 看起来有点像这样(为了便于阅读,它精简了): 这里的问题是,我使用 dockerfile 代理的每个阶段,jenkins 都会尝试重建 docker 映像。这些阶段都被缓存了,但是发送构建上下文并实际处理所有内容仍然需要比我

  • 问题内容: 我有带有输入步骤的Jenkins管道,我想通过脚本提交此输入(单字符串参数)。到目前为止,我正在尝试使用curl,理想情况下,我将通过Python请求库发送它。这应该是一个简单的POST请求,但是使用CSRF变得棘手。我已经获得Jenkins- Crumb(在这种情况下,使用curl是在同一台机器和同一bash会话上进行的),但仍然无法发送内容… 我正在发送标头,就像在https://

  • 问题内容: 仅在构建特定分支时,如何运行构建步骤/阶段? 例如,仅在调用分支的情况下才运行部署步骤,而其他所有都保持不变。 问题答案: 在声明性管道语法中执行相同的操作,以下是一些示例: 出现更有效的方法-https: //issues.jenkins- ci.org/browse/JENKINS-41187 另请 参阅- https://jenkins.io/doc/book/pipeline/

  • 仅当构建特定分支时,如何运行构建步骤/阶段? 例如,仅当分支被称为时才运行部署步骤,其他操作保持不变。