最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

groovy - How to enabledisable certain Jenkinsfile properties in a declarative pipeline? - Stack Overflow

programmeradmin2浏览0评论

I want to prevent concurrent builds for certain branches, so I have this in my scripted Jenkinsfile, and it works. So when BRANCH_NAME is a production branch, I allow concurrent builds, else not via the disableConcurrentBuilds() option. How can I convert this into declarative pipeline syntax?

@Library('shared-library') _

// For production, we want to be able to build concurrently
if (env.BRANCH_NAME.equals(env.PROD_BRANCH)) {
  properties([
    [$class: "jenkins.model.BuildDiscarderProperty", strategy: [$class: "LogRotator", numToKeepStr: "50", artifactNumToKeepStr: "20"]],
    parameters([
      editableChoice(name: "BUILD_NODE", choices: ["linux-ubuntu", "ec2-fleet-0"], description: "Build node to use"),
      choiceParam(name: "AWS_REGION", choices: ["us-east-1", "eu-north-1"], description: "AWS region to build at"),
      booleanParam(name: "CONFIRM", defaultValue: true, description: "Actually do the build?"),
      choiceParam(name: "DEBUG_LEVEL", choices: ["0", "1", "2", "3"], description: "Debugger verbosity.")
    ])
  ])
}
else {
  properties([
    disableConcurrentBuilds(),
    [$class: "jenkins.model.BuildDiscarderProperty", strategy: [$class: "LogRotator", numToKeepStr: "50", artifactNumToKeepStr: "20"]],
    parameters([
      editableChoice(name: "BUILD_NODE", choices: ["linux-ubuntu", "ec2-fleet-0"], description: "Build node to use"),
      choiceParam(name: "AWS_REGION", choices: ["us-east-1", "eu-north-1"], description: "AWS region to build at"),
      booleanParam(name: "CONFIRM", defaultValue: true, description: "Actually do the build?"),
      choiceParam(name: "DEBUG_LEVEL", choices: ["0", "1", "2", "3"], description: "Debugger verbosity.")
    ])
  ])
}

node("linux-node") {
  stage("Do build") {
    // do something
  }
}

I want to prevent concurrent builds for certain branches, so I have this in my scripted Jenkinsfile, and it works. So when BRANCH_NAME is a production branch, I allow concurrent builds, else not via the disableConcurrentBuilds() option. How can I convert this into declarative pipeline syntax?

@Library('shared-library') _

// For production, we want to be able to build concurrently
if (env.BRANCH_NAME.equals(env.PROD_BRANCH)) {
  properties([
    [$class: "jenkins.model.BuildDiscarderProperty", strategy: [$class: "LogRotator", numToKeepStr: "50", artifactNumToKeepStr: "20"]],
    parameters([
      editableChoice(name: "BUILD_NODE", choices: ["linux-ubuntu", "ec2-fleet-0"], description: "Build node to use"),
      choiceParam(name: "AWS_REGION", choices: ["us-east-1", "eu-north-1"], description: "AWS region to build at"),
      booleanParam(name: "CONFIRM", defaultValue: true, description: "Actually do the build?"),
      choiceParam(name: "DEBUG_LEVEL", choices: ["0", "1", "2", "3"], description: "Debugger verbosity.")
    ])
  ])
}
else {
  properties([
    disableConcurrentBuilds(),
    [$class: "jenkins.model.BuildDiscarderProperty", strategy: [$class: "LogRotator", numToKeepStr: "50", artifactNumToKeepStr: "20"]],
    parameters([
      editableChoice(name: "BUILD_NODE", choices: ["linux-ubuntu", "ec2-fleet-0"], description: "Build node to use"),
      choiceParam(name: "AWS_REGION", choices: ["us-east-1", "eu-north-1"], description: "AWS region to build at"),
      booleanParam(name: "CONFIRM", defaultValue: true, description: "Actually do the build?"),
      choiceParam(name: "DEBUG_LEVEL", choices: ["0", "1", "2", "3"], description: "Debugger verbosity.")
    ])
  ])
}

node("linux-node") {
  stage("Do build") {
    // do something
  }
}
Share Improve this question edited Mar 6 at 15:00 Chris F asked Mar 4 at 19:57 Chris FChris F 16.9k37 gold badges121 silver badges228 bronze badges 2
  • 1 The problem here is that options and when blocks both pertain to an entire stage, and not to each other. This means you would need an entire stage for production, and another for non-production, and the only difference would be the options block. If you are using global variable methods/shared libraries then this is less of a mess, but please clarify if this path forward is ok. – Matthew Schuchard Commented Mar 5 at 13:30
  • @MatthewSchuchard, thanks for taking the time to respond. Functionally, I want to be able to build concurrently ONLY for production branches, and am able to do it with the above descriptive pipeline. How do I achieve the same functionality with a declarative pipeline? I'm using shared libraries, and BRANCH_NAME is of course a Jenkins variable. – Chris F Commented Mar 5 at 15:27
Add a comment  | 

1 Answer 1

Reset to default 1

The asker has confirmed in the comments that the awkward implementation in declarative DSL is fine due to shared libraries mitigating DRY issues. Therefore we would use a combination of the when (conditionals) and options (settings) directives. However, the when directive is only allowed at the stage scope, and the options directive is almost completely exclusive to the pipeline root scope. The exceptions are described in the documentation:

The options directive for a stage is similar to the options directive at the root of the Pipeline. However, the stage-level options can only contain steps like retry, timeout, or timestamps, or Declarative options that are relevant to a stage, like skipDefaultCheckout.

and therefore as of the date of the current revision of this answer the desired functionality is impossible in the Jenkins Pipeline declarative DSL. If the disableConcurrentBuilds() pipeline method were to be allowed at the stage scope, then the following code illustrates how the desired functionality would be accomplished.

stage('Production') {
  when {
    environment name: 'BRANCH_NAME', value: env.PROD_BRANCH
  }
  ...
}
stage('Non-Production') {
  when {
    not {
      environment name: 'BRANCH_NAME', value: env.PROD_BRANCH
    }
    beforeOptions true
  }
  options { disableConcurrentBuilds() }
  ...
}
  

There is more information in the documentation for when and documentation for option. Note that you can use the branch parameter if this is a multibranch pipeline, but that was not specified in the question.

For multibranch pipeline the when block syntax is slightly easier:

when { branch env.PROD_BRANCH }
when {
  not {
    branch env.PROD_BRANCH
  }
  beforeOptions true
}
发布评论

评论列表(0)

  1. 暂无评论