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

Boolean parameters injected as String

    XMLWordPrintable

Details

    Description

      Consider the following workflow script:

      echo "bool=$bool"
      echo bool.getClass().toString()

      Output:

      Started by user Jos Backus
      Running: Print Message
      bool=false
      Running: Print Message
      class java.lang.String
      Running: End of Workflow
      Finished: SUCCESS

      I would expect the name of the class to be java.lang.Boolean, not java.lang.String. This forces one to add lines such as:

      bool = bool == 'true'

      Attachments

        Issue Links

          Activity

            git Thomas Gimpel added a comment -

            Thank you for the explanation. I understand now: global variables initialized by environment variables cannot change their type when a new value is assigned. In former plugin versions they could change e.g. from string to boolean. Now I have to assign the boolean to a different variable. Otherwise the boolean type would be ignored.
            I can live with that change, but it was a bit confusing, because within the Groovy script one cannot distinguish between a global variable and an unqualified parameter. The difference becomes clear only within the context of the pipeline configuration.

            git Thomas Gimpel added a comment - Thank you for the explanation. I understand now: global variables initialized by environment variables cannot change their type when a new value is assigned. In former plugin versions they could change e.g. from string to boolean. Now I have to assign the boolean to a different variable. Otherwise the boolean type would be ignored. I can live with that change, but it was a bit confusing, because within the Groovy script one cannot distinguish between a global variable and an unqualified parameter. The difference becomes clear only within the context of the pipeline configuration.
            dkarr David Karr added a comment -

            I would appreciate a clear summary of the current and desired state for this situation.

            The context is a pipeline job with a parameter clearly defined as a "Boolean Parameter". In my experience, this is provisioned as a string, which with no other information, is just confusing.

            So, is this going to be fixed, or is this considered to be acceptable? I'm having trouble discerning a clear message on this. If this isn't going to change, at the least, the job configuration page should make it clear that it will be provisioned as a String type. Otherwise, every single person who discovers this for the first time is going to assume this is a bug.

            dkarr David Karr added a comment - I would appreciate a clear summary of the current and desired state for this situation. The context is a pipeline job with a parameter clearly defined as a "Boolean Parameter". In my experience, this is provisioned as a string, which with no other information, is just confusing. So, is this going to be fixed, or is this considered to be acceptable? I'm having trouble discerning a clear message on this. If this isn't going to change, at the least, the job configuration page should make it clear that it will be provisioned as a String type. Otherwise, every single person who discovers this for the first time is going to assume this is a bug.
            hrmpw Patrick Wolf added a comment - - edited

            dkarr This is my understanding based on the comments above and the release notes of the Pipeline Groovy Plugin

            Parameters are passed into the run as environment variables and are captured in a params object. This means there are three references to that parameter value:

            env.foo
            foo
            params.foo
            

            The first two return that environment variable that was set. This has to be a string because it is an environment variable. The third method retains the parameter type set because it is not used in the environment. In this case:

            This functions as expected because it is a boolean param

            properties([parameters([booleanParam(defaultValue: false, description: '', name: 'foo')])])
            if (params.foo) {
                echo "true: $foo"
            }
            else echo "false: $foo"
            

            But this will not because it is a string from environment variable:

            properties([parameters([booleanParam(defaultValue: false, description: '', name: 'foo')])])
            if (foo) {
                echo "true: $foo"
            }
            else echo "false: $foo"
            
            hrmpw Patrick Wolf added a comment - - edited dkarr This is my understanding based on the comments above and the release notes of the Pipeline Groovy Plugin Parameters are passed into the run as environment variables and are captured in a params object. This means there are three references to that parameter value: env.foo foo params.foo The first two return that environment variable that was set. This has to be a string because it is an environment variable. The third method retains the parameter type set because it is not used in the environment. In this case: This functions as expected because it is a boolean param properties([parameters([booleanParam(defaultValue: false , description: '', name: ' foo')])]) if (params.foo) { echo " true : $foo" } else echo " false : $foo" But this will not because it is a string from environment variable: properties([parameters([booleanParam(defaultValue: false , description: '', name: ' foo')])]) if (foo) { echo " true : $foo" } else echo " false : $foo"
            dkarr David Karr added a comment -

            So then, in general, if the name of a pipeline parameter specified in the job configuration is "foo", then referencing it in the body of the pipeline script as "foo" will get a variable of a type equivalent to what is specified in the job configuration, EXCEPT if the type in the job configuration is "Boolean Parameter", which will result in a String type. In that case, referencing it as "params.foo" will always guarantee that it will be provisioned as a type that is equivalent to what is specified in the job configuration, including a "Boolean Parameter". Under those circumstances, would you conclude that it would be reasonable to document this understanding in the pipeline documentation?

            dkarr David Karr added a comment - So then, in general, if the name of a pipeline parameter specified in the job configuration is "foo", then referencing it in the body of the pipeline script as "foo" will get a variable of a type equivalent to what is specified in the job configuration, EXCEPT if the type in the job configuration is "Boolean Parameter", which will result in a String type. In that case, referencing it as "params.foo" will always guarantee that it will be provisioned as a type that is equivalent to what is specified in the job configuration, including a "Boolean Parameter". Under those circumstances, would you conclude that it would be reasonable to document this understanding in the pipeline documentation?
            hrmpw Patrick Wolf added a comment - - edited

            I would say that it is a best practice to always use the params object if you want the ensure that the type is consistent. Referencing the parameter as either foo or env.foo returns the value as it was injected into an environment variable and will always be of type String.

            properties([parameters([booleanParam(defaultValue: false, description: '', name: 'foo')])])
            
            echo "foo: " + foo.getClass().toString()
            echo "env.foo: " +  env.foo.getClass().toString()
            echo "params.foo: " + params.foo.getClass().toString()
            

            returns:

            [Pipeline] echo
            foo: class java.lang.String
            [Pipeline] echo
            env.foo: class java.lang.String
            [Pipeline] echo
            params.foo: class java.lang.Boolean
            [Pipeline] 
            
            hrmpw Patrick Wolf added a comment - - edited I would say that it is a best practice to always use the params object if you want the ensure that the type is consistent. Referencing the parameter as either foo or env.foo returns the value as it was injected into an environment variable and will always be of type String . properties([parameters([booleanParam(defaultValue: false , description: '', name: ' foo')])]) echo "foo: " + foo.getClass().toString() echo "env.foo: " + env.foo.getClass().toString() echo "params.foo: " + params.foo.getClass().toString() returns: [Pipeline] echo foo: class java.lang. String [Pipeline] echo env.foo: class java.lang. String [Pipeline] echo params.foo: class java.lang. Boolean [Pipeline]

            People

              jglick Jesse Glick
              josb Jos Backus
              Votes:
              1 Vote for this issue
              Watchers:
              15 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: