Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-41392

disableConcurrentBuilds should take an optional boolean parameter that defaults to "true"

    • Icon: Improvement Improvement
    • Resolution: Not A Defect
    • Icon: Minor Minor
    • workflow-job-plugin
    • None

      Pipeline is now script, that means that one part of the script (or some library) might call disableConcurrentBuilds and a later part of the script might want to reenable concurrent builds.

      Right now that is not possible:
      https://github.com/jenkinsci/workflow-job-plugin/blob/b7b488057d42a2c4a0f173795dd16bde3b86a3f6/src/main/java/org/jenkinsci/plugins/workflow/job/properties/DisableConcurrentBuildsJobProperty.java

          [JENKINS-41392] disableConcurrentBuilds should take an optional boolean parameter that defaults to "true"

          Jesse Glick added a comment -

          If you do not want to disable them, just remove the property.

          Jesse Glick added a comment - If you do not want to disable them, just remove the property.

          Hi jglick, sorry for jumping on an old ticket but is there any reason this cannot be done?

          I have the following use case:

          • a single Jenkinsfile is being used for multiple jobs
          • each job can have a different configuration (parameter default values, options such as the buildDiscarder, etc)
          • option values can be set using a custom pipeline config step cOption(String optionName) which returns the value for that particular job (e.g. release branches being given a longer build history than topic branches, etc)

          At the moment it looks like this:

          pipeline {
              agent none
              options {
              skipDefaultCheckout()
              timestamps()
              buildDiscarder(logRotator(
                  artifactDaysToKeepStr: cOption('artifactDaysToKeepStr'),
                  artifactNumToKeepStr: cOption('artifactDaysToKeepStr'),
                  daysToKeepStr: cOption('daysToKeepStr'),
                  numToKeepStr: cOption('numToKeepStr')
                  )
              )
              disableConcurrentBuilds()
          }
          

          I would like to be able to add something like:

              disableConcurrentBuilds(cOption('disableConcurrentBuilds'))
          

          and have the disableConcurrentBuilds value set depending on the job calling it.

          I would be happy to make the changes for it. Just wanted to make sure it is okay to do so first.

          Steve Boardwell added a comment - Hi jglick , sorry for jumping on an old ticket but is there any reason this cannot be done? I have the following use case: a single Jenkinsfile is being used for multiple jobs each job can have a different configuration (parameter default values, options such as the buildDiscarder, etc) option values can be set using a custom pipeline config step cOption(String optionName) which returns the value for that particular job (e.g. release branches being given a longer build history than topic branches, etc) At the moment it looks like this: pipeline { agent none options { skipDefaultCheckout() timestamps() buildDiscarder(logRotator( artifactDaysToKeepStr: cOption('artifactDaysToKeepStr'), artifactNumToKeepStr: cOption('artifactDaysToKeepStr'), daysToKeepStr: cOption('daysToKeepStr'), numToKeepStr: cOption('numToKeepStr') ) ) disableConcurrentBuilds() } I would like to be able to add something like: disableConcurrentBuilds(cOption('disableConcurrentBuilds')) and have the disableConcurrentBuilds value set depending on the job calling it. I would be happy to make the changes for it. Just wanted to make sure it is okay to do so first.

          Jesse Glick added a comment -

          lostinberlin if you want to have a generic Pipeline script used for multiple jobs, I would advise you to use Scripted syntax rather than Declarative.

          Jesse Glick added a comment - lostinberlin if you want to have a generic Pipeline script used for multiple jobs, I would advise you to use Scripted syntax rather than Declarative.

          jglick Sorry, I didn't add the context. It is not meant to be a generic Pipeline script to serve multiple and different jobs. The jobs in question are all the same job in principle, doing the same thing, just for a different branch. We could just as well have the Jenkinsfile configured as a Multibranch Pipeline or even Github Organisation job.

          A little off topic, but the cOption thing is simply a way to set some defaults (for the buildDiscarder task for example) based on the BRANCH_NAME. This is possible for stages within the pipeline itself using the "when ... expression" but not at the configuration level.

          So whilst we can say "if on release_branch then archive these artifacts (else do not)", we can't say "if on release_branch then keep all the build history else only keep the last 30 builds and artifacts of the last 10 builds". It's either have all your branches save all the build history, or accept losing some of your release branches build history.

          Following this, it makes sense to allow the disableConcurrentBuilds to accept a boolean in the same way skipDefaultCheckout does. Having an optional boolean would allow this to be configured rather than being static statement.

          Steve Boardwell added a comment - jglick Sorry, I didn't add the context. It is not meant to be a generic Pipeline script to serve multiple and different jobs. The jobs in question are all the same job in principle, doing the same thing, just for a different branch. We could just as well have the Jenkinsfile configured as a  Multibranch Pipeline or even Github Organisation job. A little off topic, but the  cOption thing is simply a way to set some defaults (for the buildDiscarder task for example) based on the BRANCH_NAME . This is possible for stages within the pipeline itself using the " when ... expression " but not at the configuration level. So whilst we can say "if on release_branch then archive these artifacts (else do not)", we can't say "if on release_branch then keep all the build history else only keep the last 30 builds and artifacts of the last 10 builds". It's either have all your branches save all the build history, or accept losing some of your release branches build history. Following this, it makes sense to allow the  disableConcurrentBuilds to accept a boolean in the same way skipDefaultCheckout does. Having an optional boolean would allow this to be configured rather than being static statement.

          Jesse Glick added a comment -

          Since your need is specific to Declarative (this would be trivial in Scripted), you should rather open an RFE for Declarative to permit parts of options to use a when clause.

          Jesse Glick added a comment - Since your need is specific to Declarative (this would be trivial in Scripted), you should rather open an RFE for Declarative to permit parts of options to use a when clause.

          Hi jglick, sorry for the late reply. I understand that we can do this quite easily with the Scripted syntax, but then one would lose the benefits of the declarative pipeline such as post-conditions, etc.

          I can open an RFE but at the same time I can still see the advantage in being able to configure this parameter with a boolean value. Using templating to create jenkins files, for example, where you could just have an IS_CONCURRENT boolean placeholder to replace á la disableConcurrentBuilds($IS_CONCURRENT), rather than have to set IS_CONCURRENT to either disableConcurrentBuilds() or '' and have an empty line in your Jenkinsfile.

          Sorry for being a pain . If it is a 'Won't Do' then so be it.

          Steve Boardwell added a comment - Hi jglick , sorry for the late reply. I understand that we can do this quite easily with the Scripted syntax, but then one would lose the benefits of the declarative pipeline such as post-conditions, etc. I can open an RFE but at the same time I can still see the advantage in being able to configure this parameter with a boolean value. Using templating to create jenkins files, for example, where you could just have an IS_CONCURRENT boolean placeholder to replace á la disableConcurrentBuilds($IS_CONCURRENT) , rather than have to set IS_CONCURRENT to either disableConcurrentBuilds() or '' and have an empty line in your Jenkinsfile. Sorry for being a pain . If it is a 'Won't Do' then so be it.

          Qun Zhou added a comment -

          Is there update for the issue? I really love the concept of declarative pipeline. We have similar situation. There are multiple repositories and branches share the same jenkinsfile, we want disableConcurrentBuilds for development branches but not the master branch, and we don't want too many jenkinsfile which will bring too much maintenance effort. So a boolean parameter will be perfect, and "when...expression" is an acceptable work-round. But now, we have to define different but very similar jenkinsfile to get the function work.

          Qun Zhou added a comment - Is there update for the issue? I really love the concept of declarative pipeline. We have similar situation. There are multiple repositories and branches share the same jenkinsfile, we want disableConcurrentBuilds for development branches but not the master branch, and we don't want too many jenkinsfile which will bring too much maintenance effort. So a boolean parameter will be perfect, and "when...expression" is an acceptable work-round. But now, we have to define different but very similar jenkinsfile to get the function work.

          jglick:

          this would be trivial in Scripted

          Can you please explain here how "enable concurrent builds" can be activate with in a Scripted Pipeline?

          Jeremie Bresson added a comment - jglick : this would be trivial in Scripted Can you please explain here how "enable concurrent builds" can be activate with in a Scripted Pipeline?

          Jesse Glick added a comment -

          You can pass whatever expression you like to a properties step. Please post to the Jenkins users’ list for usage questions.

          Jesse Glick added a comment - You can pass whatever expression you like to a properties step. Please post to the Jenkins users’ list for usage questions.

          Amir Barkal added a comment -

          Joining Op's request, our use case is very similar: Using the same Jenkinsfile for different jobs with declarative syntax.
          This can be implemented by either having the options{} block accept a when{} clause, or (preferably) by having all the options support configurable parameters.

          IMO this ticket should be reopened with a definition of done like Op's subject.

          Amir Barkal added a comment - Joining Op's request, our use case is very similar: Using the same Jenkinsfile for different jobs with declarative syntax. This can be implemented by either having the options{} block accept a when{} clause, or (preferably) by having all the options support configurable parameters. IMO this ticket should be reopened with a definition of done like Op's subject.

          Anthony O'Gorman added a comment - - edited

          This issue should be reopened - the issue is not resolved - those who wish to use declarative syntax cannot easily change the build behavior programmatically for build concurrency. This would be a nice (and simple) way to allow us to do that. Also, it would help to keep directives consistent, skipDefaultCheckout for example uses the same implementation suggested on this ticket: https://issues.jenkins-ci.org/browse/JENKINS-41391

          Anthony O'Gorman added a comment - - edited This issue should be reopened - the issue is not resolved - those who wish to use declarative syntax cannot easily change the build behavior programmatically for build concurrency. This would be a nice (and simple) way to allow us to do that. Also, it would help to keep directives consistent, skipDefaultCheckout for example uses the same implementation suggested on this ticket:  https://issues.jenkins-ci.org/browse/JENKINS-41391

          Jesse Glick added a comment -

          antogo do not reopen. Read my comment of 2018-07-20.

          Jesse Glick added a comment - antogo do not reopen. Read my comment of 2018-07-20.

          Nik Geo added a comment - - edited

          Removing of disableConcurrentBuilds() in PR from scripted pipeline didn't affect my develop branch until I went and manually removed it from branch's config.xml

           

          node {
           properties(
            [
             disableConcurrentBuilds(),
            ]
           )
           stage('stage 1') {
            sleep(30000)
           }
          }

          manual changes to config.xml

          <?xml version='1.1' encoding='UTF-8'?>
          <flow-definition plugin="workflow-job@2.34">
            <actions>
              <org.jenkinsci.plugins.workflow.multibranch.JobPropertyTrackerAction plugin="workflow-multibranch@2.21">
                <jobPropertyDescriptors>
          --        <string>org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty</string>
                </jobPropertyDescriptors>
              </org.jenkinsci.plugins.workflow.multibranch.JobPropertyTrackerAction>
            </actions>
          
          ...
          
             </org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty>
          --    <org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/>
            </properties>
            <definition class="org.jenkinsci.plugins.workflow.multibranch.SCMBinder" plugin="workflow-multibranch@2.21">
              <scriptPath>Jenkinsfile</scriptPath>
            </definition>
            <triggers/>
            <disabled>false</disabled>

           

           

          Nik Geo added a comment - - edited Removing of disableConcurrentBuilds() in PR from scripted pipeline didn't affect my develop branch until I went and manually removed it from branch's config.xml   node { properties( [ disableConcurrentBuilds(), ] ) stage( 'stage 1' ) { sleep(30000) } } manual changes to config.xml <?xml version= '1.1' encoding= 'UTF-8' ?> <flow-definition plugin= "workflow-job@2.34" > <actions> <org.jenkinsci.plugins.workflow.multibranch.JobPropertyTrackerAction plugin= "workflow-multibranch@2.21" > <jobPropertyDescriptors> -- <string>org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty</string> </jobPropertyDescriptors> </org.jenkinsci.plugins.workflow.multibranch.JobPropertyTrackerAction> </actions> ... </org.jenkinsci.plugins.workflow.multibranch.BranchJobProperty> -- <org.jenkinsci.plugins.workflow.job.properties.DisableConcurrentBuildsJobProperty/> </properties> <definition class= "org.jenkinsci.plugins.workflow.multibranch.SCMBinder" plugin= "workflow-multibranch@2.21" > <scriptPath>Jenkinsfile</scriptPath> </definition> <triggers/> <disabled> false </disabled>    

          Amit Dar added a comment -

          question:

          If I write

          properties()

          inside my scripted pipeline, doesn't this remove the previously set properties (with the disableConcurrentBuilds)?

          Amit Dar added a comment - question: If I write properties() inside my scripted pipeline, doesn't this remove the previously set properties (with the disableConcurrentBuilds)?

          christian added a comment -

          I also love the concept of Steve. 

          I work only with decorative pipeline (IMO state of the art) and would like to:

           

          options { disableConcurrentBuilds(abortPrevious: false) } 

          when building branches

          and 

          options { disableConcurrentBuilds(abortPrevious: true) } 

          when building pull requests

           

           

          maybe with something like:

          options { disableConcurrentBuilds(abortPrevious: env.CHANGE_ID ? true : false) } 

           

          christian added a comment - I also love the concept of Steve.  I work only with decorative pipeline (IMO state of the art) and would like to:   options { disableConcurrentBuilds(abortPrevious: false ) } when building branches and  options { disableConcurrentBuilds(abortPrevious: true ) } when building pull requests     maybe with something like: options { disableConcurrentBuilds(abortPrevious: env.CHANGE_ID ? true : false ) }   

            Unassigned Unassigned
            bitwiseman Liam Newman
            Votes:
            0 Vote for this issue
            Watchers:
            13 Start watching this issue

              Created:
              Updated:
              Resolved: