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

Allow different "Discard Old Build" options per branch on multibranch pipelines

      Currently I'm setting a buildDiscarder option in my declarative Jenkinsfile.

      The problem is that I cannot setup a different strategy per branch.

      Why do it need this? Well, I'd like to keep during more time the build and artifacts of the master and release/* branches while I keep a low number for any other branch.

      I'm sure this will be useful for a lot of people.

          [JENKINS-47717] Allow different "Discard Old Build" options per branch on multibranch pipelines

          Martin Ulmschneider added a comment - - edited

          I'm running into the same problem, and am surprised that this doesn't seem to be a common issue - how do other people handle loads of feature branch / pull request builds?

          Edit:

          I'm using the following code snippet as a workaround:

                  script{
                    if (env.BRANCH_NAME=='master'){
                      echo 'master branch - disable build discarding'
                      properties([buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: ''))])
                    }
                    else {
                      echo 'non-master branch - only keeping the last 5 build artifacts'
                      properties([buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '5', daysToKeepStr: '', numToKeepStr: ''))])
                    }
          
          

          Martin Ulmschneider added a comment - - edited I'm running into the same problem, and am surprised that this doesn't seem to be a common issue - how do other people handle loads of feature branch / pull request builds? Edit: I'm using the following code snippet as a workaround: script{ if (env.BRANCH_NAME== 'master' ){ echo 'master branch - disable build discarding' properties([buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: ' ', daysToKeepStr: ' ', numToKeepStr: ' '))]) } else { echo 'non-master branch - only keeping the last 5 build artifacts' properties([buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: ' 5 ', daysToKeepStr: ' ', numToKeepStr: ' '))]) }

          buildDiscarder(logRotator(numToKeepStr: env.BRANCH_NAME == 'master' ? '10' : '25'))

           

          James Richardson added a comment - buildDiscarder(logRotator(numToKeepStr: env.BRANCH_NAME == 'master' ? '10' : '25'))  

          Roman Muntyanu added a comment - - edited

          A more sophisticated example of a per-branch clean-up policy workaround (thank you, richajam!). Multibranch Pipeline. Declarative build.jenkinsfile.

          The policy:

          | Branch name | # Builds | # Artifacts |
          |-------------|----------|-------------|
          | master      |      100 |           1 |
          | test        |       10 |           1 |
          | production  |       10 |           5 |
          | feature/*   |        5 |           1 |
          | bug/*       |        5 |           1 |
          | <other>     |        1 |           0 |
          

          The solution:

          pipeline {
          
              options {
                  buildDiscarder(logRotator(
                      // number of builds to keep
                      numToKeepStr:         env.BRANCH_NAME ==~ /master/ ? '100' :
                                            env.BRANCH_NAME ==~ /production|test/ ?  '10' :
                                            env.BRANCH_NAME ==~ /feature\/.*|bug\/.*/ ? '5' : '1',
                      // number of builds to keep the artifacts from
                      artifactNumToKeepStr: env.BRANCH_NAME ==~ /master|test/ ? '1' :
                                            env.BRANCH_NAME ==~ /production/ ?  '5' :
                                            env.BRANCH_NAME ==~ /feature\/.*|bug\/.*/ ? '1' : '0'
                  ))
              }
          
          .....
          }
          

          Roman Muntyanu added a comment - - edited A more sophisticated example of a per-branch clean-up policy workaround (thank you, richajam !). Multibranch Pipeline. Declarative build.jenkinsfile. The policy: | Branch name | # Builds | # Artifacts | |-------------|----------|-------------| | master | 100 | 1 | | test | 10 | 1 | | production | 10 | 5 | | feature/* | 5 | 1 | | bug/* | 5 | 1 | | <other> | 1 | 0 | The solution: pipeline { options { buildDiscarder(logRotator( // number of builds to keep numToKeepStr: env.BRANCH_NAME ==~ /master/ ? '100' : env.BRANCH_NAME ==~ /production|test/ ? '10' : env.BRANCH_NAME ==~ /feature\/.*|bug\/.*/ ? '5' : '1' , // number of builds to keep the artifacts from artifactNumToKeepStr: env.BRANCH_NAME ==~ /master|test/ ? '1' : env.BRANCH_NAME ==~ /production/ ? '5' : env.BRANCH_NAME ==~ /feature\/.*|bug\/.*/ ? '1' : '0' )) } ..... }

          roe_p pinhas added a comment -

          This solution/workaround doesn't seems to work.

          Let's say I have configured the pipeline to use:

          buildDiscarder(logRotator(numToKeepStr: env.BRANCH_NAME == 'master' ? '5' : '1'))

          This will be as an example build (branch) history:

          #1 master  #2 master  #3 master #4 master

          #5 master #6 master #7 feature #8 feature

          In this case according to the explanation of the policy when I build the master branch 5 times it will save them and will drop build#1 when I start the 6 build. If I build #7 as non master branch it will keep all the builds (#2-6) and on #8 it will remove #7 only.

           

          However this is not the case, what really happens is that on build #7 it's evaluating the condition and now the value of the buildDiscarder is 1 so its removing all the builds and keeping #7 only regardless of the branch name (it doesn't evaluate each build with the corresponding branch name)

          roe_p pinhas added a comment - This solution/workaround doesn't seems to work. Let's say I have configured the pipeline to use: buildDiscarder(logRotator(numToKeepStr: env.BRANCH_NAME == 'master' ? '5' : '1')) This will be as an example build (branch) history: #1 master  #2 master  #3 master #4 master #5 master #6 master #7 feature #8 feature In this case according to the explanation of the policy when I build the master branch 5 times it will save them and will drop build#1 when I start the 6 build. If I build #7 as non master branch it will keep all the builds (#2-6) and on #8 it will remove #7 only.   However this is not the case, what really happens is that on build #7 it's evaluating the condition and now the value of the buildDiscarder is 1 so its removing all the builds and keeping #7 only regardless of the branch name (it doesn't evaluate each build with the corresponding branch name)

          roe_p, AFAIK, it works OK in a Multibranch Pipeline, where each branch becomes a nested project that discards its builds independently from the other branches.

          Kalle Niemitalo added a comment - roe_p , AFAIK, it works OK in a Multibranch Pipeline , where each branch becomes a nested project that discards its builds independently from the other branches.

            Unassigned Unassigned
            c3s4r Cesar Salazar
            Votes:
            12 Vote for this issue
            Watchers:
            14 Start watching this issue

              Created:
              Updated: