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

Multibranch plugin is missing "Discard Old Builds"

      "Freestyle" jobs have a section for "Discard old builds", so I can clear out builds so the disk space doesn't just grow and grow.

      For "Mutlibranch pipeline" jobs, no such option exists. What is the best way to clear out out builds with this type of job?

          [JENKINS-35642] Multibranch plugin is missing "Discard Old Builds"

          I believe you can set those in the Jenkins file using set property.

          Pedro Algarvio added a comment - I believe you can set those in the Jenkins file using set property.

          Ruby Paasche added a comment - - edited

          Take a look at the comment:
          https://issues.jenkins-ci.org/browse/JENKINS-34738?focusedCommentId=263489&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-263489

          You simply need to add to your pipline somthing like:
          properties [[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '20', artifactNumToKeepStr: '30', daysToKeepStr: '20', numToKeepStr: '30']]]

          Ruby Paasche added a comment - - edited Take a look at the comment: https://issues.jenkins-ci.org/browse/JENKINS-34738?focusedCommentId=263489&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-263489 You simply need to add to your pipline somthing like: properties [[$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '20', artifactNumToKeepStr: '30', daysToKeepStr: '20', numToKeepStr: '30'] ]]

          James Hogarth added a comment -

          For the benefit of google and the next person that needs to set discard properties on all their pipeline jobs due to lack of control of Jenkinsfiles from developers ...

          Just knocked up this bit of groovy which respects any existing setting, but mandates some limits if not set and ensures the rotate log is run when there are jobs that may only run infrequently:

          #!/usr/bin/env groovy
          
          import org.jenkinsci.plugins.workflow.job.WorkflowJob
          import hudson.tasks.LogRotator
          
          def allItems = Jenkins.instance.getAllItems(WorkflowJob)
          
          allItems.each { job ->
          
            // defaults to use
            newArtifactDaysToKeep = 7
            newArtifactNumToKeep = 10
            newDaysToKeep = 30
            newNumToKeep = 100
          
            newDiscarder = false
          
            buildDiscarder = job.getBuildDiscarder()
          
            // if the buildDiscarder is already configured, then check if it is partially configured
            // and honour whatever settings are in the jenkinsfile
            if (buildDiscarder) {
              if (buildDiscarder instanceof LogRotator) {
                artifactDaysToKeep = buildDiscarder.getArtifactDaysToKeep()
                artifactNumToKeep = buildDiscarder.getArtifactNumToKeep()
                daysToKeep = buildDiscarder.getDaysToKeep()
                numToKeep = buildDiscarder.getNumToKeep()
          
                println "Existing config is: artifactDaysToKeep (${artifactDaysToKeep}) artifactNumToKeep (${artifactNumToKeep}) daysToKeep (${daysToKeep}) numToKeep (${numToKeep})"
          
                if ((artifactDaysToKeep < 1) || (artifactNumToKeep < 1) || (daysToKeep < 1) || (numToKeep < 1)) {
                  newDiscarder = true
                }
          
                if (artifactDaysToKeep > 0) {
                  newArtifactDaysToKeep = artifactDaysToKeep
                }
          
                if (artifactNumToKeep > 0) {
                  newArtifactNumToKeep = artifactNumToKeep
                }
          
                if (daysToKeep > 0) {
                  newDaysToKeep = daysToKeep
                }
          
                if (numToKeep > 0) {
                  newNumToKeep = numToKeep
                }
          
              } else {
                // enforce LogRotator discarder just in case another appears
                newDiscarder = true
              }
            } else {
              // if no discarder is configured yet then we'll add our agreed defaults
              newDiscarder = true
            }
          
            if (newDiscarder == true) {
              // we'll persist this as that allows the settings to survive restart
              // note that a jenkinsfile will only touch this is properties() is set in it
              println "New config is: artifactDaysToKeep (${newArtifactDaysToKeep}) artifactNumToKeep (${newArtifactNumToKeep}) daysToKeep (${newDaysToKeep}) numToKeep (${newNumToKeep})"
          
              newBuildDiscarder = new LogRotator(newDaysToKeep, newNumToKeep, newArtifactDaysToKeep, newArtifactNumToKeep)
          
              job.setBuildDiscarder(newBuildDiscarder)
              job.save()
            }
          
            // At this point either we've set a configure or verified the Jenkinsfile for the workflow has already got values assigned
            println "Running cleanup of " + job.getFullName()
            job.logRotate()
          
          }
          
          return "completed"
          

          James Hogarth added a comment - For the benefit of google and the next person that needs to set discard properties on all their pipeline jobs due to lack of control of Jenkinsfiles from developers ... Just knocked up this bit of groovy which respects any existing setting, but mandates some limits if not set and ensures the rotate log is run when there are jobs that may only run infrequently: #!/usr/bin/env groovy import org.jenkinsci.plugins.workflow.job.WorkflowJob import hudson.tasks.LogRotator def allItems = Jenkins.instance.getAllItems(WorkflowJob) allItems.each { job -> // defaults to use newArtifactDaysToKeep = 7 newArtifactNumToKeep = 10 newDaysToKeep = 30 newNumToKeep = 100 newDiscarder = false buildDiscarder = job.getBuildDiscarder() // if the buildDiscarder is already configured, then check if it is partially configured // and honour whatever settings are in the jenkinsfile if (buildDiscarder) { if (buildDiscarder instanceof LogRotator) { artifactDaysToKeep = buildDiscarder.getArtifactDaysToKeep() artifactNumToKeep = buildDiscarder.getArtifactNumToKeep() daysToKeep = buildDiscarder.getDaysToKeep() numToKeep = buildDiscarder.getNumToKeep() println "Existing config is: artifactDaysToKeep (${artifactDaysToKeep}) artifactNumToKeep (${artifactNumToKeep}) daysToKeep (${daysToKeep}) numToKeep (${numToKeep})" if ((artifactDaysToKeep < 1) || (artifactNumToKeep < 1) || (daysToKeep < 1) || (numToKeep < 1)) { newDiscarder = true } if (artifactDaysToKeep > 0) { newArtifactDaysToKeep = artifactDaysToKeep } if (artifactNumToKeep > 0) { newArtifactNumToKeep = artifactNumToKeep } if (daysToKeep > 0) { newDaysToKeep = daysToKeep } if (numToKeep > 0) { newNumToKeep = numToKeep } } else { // enforce LogRotator discarder just in case another appears newDiscarder = true } } else { // if no discarder is configured yet then we'll add our agreed defaults newDiscarder = true } if (newDiscarder == true ) { // we'll persist this as that allows the settings to survive restart // note that a jenkinsfile will only touch this is properties() is set in it println "New config is: artifactDaysToKeep (${newArtifactDaysToKeep}) artifactNumToKeep (${newArtifactNumToKeep}) daysToKeep (${newDaysToKeep}) numToKeep (${newNumToKeep})" newBuildDiscarder = new LogRotator(newDaysToKeep, newNumToKeep, newArtifactDaysToKeep, newArtifactNumToKeep) job.setBuildDiscarder(newBuildDiscarder) job.save() } // At this point either we've set a configure or verified the Jenkinsfile for the workflow has already got values assigned println "Running cleanup of " + job.getFullName() job.logRotate() } return "completed"

          Raphael Reitzig added a comment - - edited

          For fellow googlers: in a declarative pipeline, use something like

          options {
              buildDiscarder(logRotator(
                  artifactDaysToKeepStr: '17',
                  artifactNumToKeepStr: '7',
                  daysToKeepStr: '100',
                  numToKeepStr: '100'
              ))
          }

          Raphael Reitzig added a comment - - edited For fellow googlers: in a declarative pipeline, use something like options { buildDiscarder(logRotator( artifactDaysToKeepStr: '17' , artifactNumToKeepStr: '7' , daysToKeepStr: '100' , numToKeepStr: '100' )) }

            recena Manuel Recena Soto
            dc00 D Claus
            Votes:
            5 Vote for this issue
            Watchers:
            11 Start watching this issue

              Created:
              Updated:
              Resolved: