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

Allow variables and functions to be defined within pipeline to be used in any stage

      I have several use cases where I may operate on a list or map on different stages of a pipeline. This variable may not be known ahead of time - it could be defined within a stage. I'd like a syntax that allows me to define variables within a pipeline.

      Today, I have to define a shared variable before entering pipeline {}.

      Jenkinsfile
      #!/bin/groovy
      // Define outside of pipeline to make sure accessible in all script {} blocks
      def my_list
      
      pipeline {
          agent { label 'label' }
          stages {
              stage('stage1') {
                steps {
                 script {
                     my_list = [1,2,3]
                 }
                }
              }
          
              stage('stage2') {
                steps {
                  script {
                      for(int i=0; i<my_list.size();i++) {
                          echo "Doing something with ${my_list[i]}"
                      }
                  }
                }
              }
          }
      }
      

      A simple approach would be to allow "def" to work anywhere within pipeline {}. This avoids any overly new syntax for pipeline.

      Another option would allow the user to provide a special pipeline {} block for defining non-env/params style variables. This could be helpful in allowing the user to use items available in script {} for defining shared state.

      Jenkinsfile with possible example syntax
      #!/bin/groovy
      
      
      pipeline {
          agent { label 'label' }    
      
          define {
             def my_map = [:] //empty map
             def my_list //undefined shared variable
           }
      
          stages {
              stage('stage1') {
                steps {
                  script {
                    //If def can be anywhere in pipeline {}, drop script {}
                    my_list = [1,2,3]
                  }
                }
              }
          
              stage('stage2') {
                steps {
                  script {
                      for(int i=0; i<my_list.size();i++) {
                          echo "Doing something with ${my_list[i]}"
                      }
                  }
                }
              }
          }
      }
      

          [JENKINS-41335] Allow variables and functions to be defined within pipeline to be used in any stage

          Robby Pocase created issue -

          Andrew Bayer added a comment -

          I like the define block idea, though I can't yet guarantee I can make that work in implementation. Will experiment in that direction when I get a chance. I've also long been kicking around the idea of having functions available for setting the value of variables to deal with the = blocking but haven't fallen in love with it enough to actually do it. =)

          Andrew Bayer added a comment - I like the define block idea, though I can't yet guarantee I can make that work in implementation. Will experiment in that direction when I get a chance. I've also long been kicking around the idea of having functions available for setting the value of variables to deal with the = blocking but haven't fallen in love with it enough to actually do it. =)

          Andrew Bayer added a comment -

          hrmpw jamesdumay michaelneale rsandell - something else I'd like your thoughts on.

          Andrew Bayer added a comment - hrmpw jamesdumay michaelneale rsandell - something else I'd like your thoughts on.

          Patrick Wolf added a comment -

          Using top-level define and then def inside the block seems a bit redundant.

          This would make the use of Artifactory much simpler. They rely heavily on defining configuration settings. That can easily be done in a script but I could see it used with this, too.

          Patrick Wolf added a comment - Using top-level define and then def inside the block seems a bit redundant. This would make the use of Artifactory much simpler. They rely heavily on defining configuration settings. That can easily be done in a script but I could see it used with this, too.

          Robby Pocase added a comment -

          Not a huge fan of the redundant def either, but wanted a compromise to possibly allow script expressions. An alternative would be using expression (similar to when) to be explicit about when script style usage is allowed. I'm not overly fond of this syntax either, but it does provide some consistency with other declarative constructs.

          define {
              my_var = expression { return "foo" == "bar" }
          }
          

          Robby Pocase added a comment - Not a huge fan of the redundant def either, but wanted a compromise to possibly allow script expressions. An alternative would be using expression (similar to when) to be explicit about when script style usage is allowed. I'm not overly fond of this syntax either, but it does provide some consistency with other declarative constructs. define { my_var = expression { return "foo" == "bar" } }

          Andrew Bayer added a comment -

          Worth mentioning that in any scenario, the def would literally be redundant no matter what we're doing with the value - we wouldn't be literally calling this Groovy code at parse time, we'd be saying "Ok, here's the variable name, and here's what to set it to - evaluate that value at runtime and set the variable to that result".

          Andrew Bayer added a comment - Worth mentioning that in any scenario, the def would literally be redundant no matter what we're doing with the value - we wouldn't be literally calling this Groovy code at parse time, we'd be saying "Ok, here's the variable name, and here's what to set it to - evaluate that value at runtime and set the variable to that result".
          Liam Newman made changes -
          Link New: This issue relates to JENKINS-41396 [ JENKINS-41396 ]
          Andrew Bayer made changes -
          Summary Original: Allow variable to be defined within pipeline to be used in any stage New: Allow variables and functions to be defined within pipeline to be used in any stage
          Andrew Bayer made changes -
          Link New: This issue is duplicated by JENKINS-41396 [ JENKINS-41396 ]
          Andrew Bayer made changes -
          Priority Original: Minor [ 4 ] New: Critical [ 2 ]

            abayer Andrew Bayer
            rpocase Robby Pocase
            Votes:
            43 Vote for this issue
            Watchers:
            57 Start watching this issue

              Created:
              Updated:
              Resolved: