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

Evaluation/references of variables in Scripted Pipeline

    Details

    • Similar Issues:

      Description

      Consider the following Scripted Pipeline:

      def axisPlatform = [
          "native", 
          "cross", 
      ]
      
      def axisBuildType = [
          "RelWithDebInfo",
          "Debug"
      ]
      
      tasks = [:]
      
      // build packages
      axisPlatform.unique().each { level ->
          axisBuildType.each { buildType ->
              platform = "${level}-${buildType}"
      
              // build package
              tasks["package-${platform}"] = {
                  node("server2") {
                      println level
                      println buildType
                      println platform
                  }
              }
          }
      }
      
      stage("1") {
          parallel tasks
      }
      

      I'm getting:

      [package-native-RelWithDebInfo] native
      [package-native-RelWithDebInfo] RelWithDebInfo
      [package-native-RelWithDebInfo] cross-Debug
      
      [package-native-Debug] native
      [package-native-Debug] Debug
      [package-native-Debug] cross-Debug
      
      [package-cross-RelWithDebInfo] cross
      [package-cross-RelWithDebInfo] RelWithDebInfo
      [package-cross-RelWithDebInfo] cross-Debug
      
      [package-cross-Debug] cross
      [package-cross-Debug] Debug
      [package-cross-Debug] cross-Debug
      

      It seems that the iterator-variables are copied by value, but the platform-variable is taken by reference.

      Is this the expected behavior?

        Attachments

          Activity

          Hide
          abayer Andrew Bayer added a comment -

          So you're getting bit by Groovy's variable scoping in scripts. Specifically, platform = .... If you declare a variable without a type or def, it gets scoped across the entire script, not just the scope you think you're defining it. So you're effectively calling def platform outside of your .each loops, meaning that when the parallel branches actually execute, platform is set to the last value from the loops - cross-Debug in this case.

          Change that line to def platform = ... or String platform = ... and you'll be good to go.

          Show
          abayer Andrew Bayer added a comment - So you're getting bit by Groovy's variable scoping in scripts. Specifically, platform = ... . If you declare a variable without a type or def , it gets scoped across the entire script, not just the scope you think you're defining it. So you're effectively calling def platform outside of your .each loops, meaning that when the parallel branches actually execute, platform is set to the last value from the loops - cross-Debug in this case. Change that line to def platform = ... or String platform = ... and you'll be good to go.

            People

            • Assignee:
              Unassigned
              Reporter:
              pboettch Patrick Boettcher
            • Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: