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

Boolean parameters injected as String

    XMLWordPrintable

    Details

    • Similar Issues:

      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

            josb Jos Backus created issue -
            Hide
            batmat Baptiste Mathus added a comment -
            Show
            batmat Baptiste Mathus added a comment - Linking to the associated thread can help: https://groups.google.com/forum/#!topic/jenkinsci-users/dO2LRFNRQ4Q
            jglick Jesse Glick made changes -
            Field Original Value New Value
            Link This issue is duplicated by JENKINS-27388 [ JENKINS-27388 ]
            Hide
            jglick Jesse Glick added a comment -

            By design; parameter values traditionally have been injected as environment variables, so Workflow just followed suit.

            Now when using parameter value implementations defined in core, or in a plugin depending on core 1.568+, the new getValue method could be called. For compatibility reasons, we cannot change the type of the existing variables, but we could introduce new variables (or a map variable parameters, etc.) based on the rich types.

            Unfortunately there is no clear way to distinguish whether a given ParameterValue implementation is specifying getValue. The Javadoc says it can return this as a fallback, yet the default implementation is null, which may be a legitimate return value in an override. Perhaps we need to just use Util.isOverridden, which is undesirable since it would give incorrect results if there are any proxying implementations, though probably there are not.

            Show
            jglick Jesse Glick added a comment - By design; parameter values traditionally have been injected as environment variables, so Workflow just followed suit. Now when using parameter value implementations defined in core, or in a plugin depending on core 1.568+, the new getValue method could be called. For compatibility reasons, we cannot change the type of the existing variables, but we could introduce new variables (or a map variable parameters , etc.) based on the rich types. Unfortunately there is no clear way to distinguish whether a given ParameterValue implementation is specifying getValue . The Javadoc says it can return this as a fallback, yet the default implementation is null , which may be a legitimate return value in an override. Perhaps we need to just use Util.isOverridden , which is undesirable since it would give incorrect results if there are any proxying implementations, though probably there are not.
            jglick Jesse Glick made changes -
            Issue Type Bug [ 1 ] Improvement [ 4 ]
            Summary Boolean parameters injected as Strings into Groovy Workflow Plugin environment Boolean parameters injected as String
            jglick Jesse Glick made changes -
            Link This issue is blocking JENKINS-27413 [ JENKINS-27413 ]
            Hide
            jglick Jesse Glick added a comment -

            Current implementation here.

            Show
            jglick Jesse Glick added a comment - Current implementation here .
            jglick Jesse Glick made changes -
            Link This issue is related to JENKINS-29952 [ JENKINS-29952 ]
            jglick Jesse Glick made changes -
            Link This issue is related to SECURITY-170 [ SECURITY-170 ]
            jglick Jesse Glick made changes -
            Link This issue is related to JENKINS-30222 [ JENKINS-30222 ]
            jglick Jesse Glick made changes -
            Link This issue is related to JENKINS-30519 [ JENKINS-30519 ]
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in jenkins
            User: Jesse Glick
            Path:
            multibranch/src/test/java/org/jenkinsci/plugins/workflow/multibranch/JobPropertyStepTest.java
            http://jenkins-ci.org/commit/workflow-plugin/4320015acd28c40e6cce462c15e86d4873762f55
            Log:
            ParametersDefinitionProperty not set when the first build begins.
            Without JENKINS-27295, this makes it awkward to have a default parameter value.

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Jesse Glick Path: multibranch/src/test/java/org/jenkinsci/plugins/workflow/multibranch/JobPropertyStepTest.java http://jenkins-ci.org/commit/workflow-plugin/4320015acd28c40e6cce462c15e86d4873762f55 Log: ParametersDefinitionProperty not set when the first build begins. Without JENKINS-27295 , this makes it awkward to have a default parameter value.
            jglick Jesse Glick made changes -
            Link This issue is related to JENKINS-30222 [ JENKINS-30222 ]
            Hide
            rodrigc Craig Rodrigues added a comment - - edited

            Jos Backus: in my job, I defined a boolean parameter called SKIP_TEST and in the workflow script I did this:

            boolean skip_test = false
            
            if (getBinding().hasVariable("SKIP_TEST")) {
                skip_test = SKIP_TEST.toBoolean()
            }
            

            Jos Backus: My full workflow script is described here: https://groups.google.com/forum/#!msg/jenkinsci-users/jSKwSKbaXq8/dG2mn6iyDQAJ . Please feel free to review and provide feedback. I am learning workflow DSL as I go along (as most of us are).

            Show
            rodrigc Craig Rodrigues added a comment - - edited Jos Backus : in my job, I defined a boolean parameter called SKIP_TEST and in the workflow script I did this: boolean skip_test = false if (getBinding().hasVariable( "SKIP_TEST" )) { skip_test = SKIP_TEST.toBoolean() } Jos Backus : My full workflow script is described here: https://groups.google.com/forum/#!msg/jenkinsci-users/jSKwSKbaXq8/dG2mn6iyDQAJ . Please feel free to review and provide feedback. I am learning workflow DSL as I go along (as most of us are).
            Hide
            josb Jos Backus added a comment -

            @rodrigc thanks for the metaprogramming workaround.

            Show
            josb Jos Backus added a comment - @rodrigc thanks for the metaprogramming workaround.
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in jenkins
            User: Jesse Glick
            Path:
            multibranch/src/test/java/org/jenkinsci/plugins/workflow/multibranch/JobPropertyStepTest.java
            http://jenkins-ci.org/commit/workflow-multibranch-plugin/e1a041f89b15d7505e005fa66b51a955fc68d1b7
            Log:
            ParametersDefinitionProperty not set when the first build begins.
            Without JENKINS-27295, this makes it awkward to have a default parameter value.
            Originally-Committed-As: 4320015acd28c40e6cce462c15e86d4873762f55

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Jesse Glick Path: multibranch/src/test/java/org/jenkinsci/plugins/workflow/multibranch/JobPropertyStepTest.java http://jenkins-ci.org/commit/workflow-multibranch-plugin/e1a041f89b15d7505e005fa66b51a955fc68d1b7 Log: ParametersDefinitionProperty not set when the first build begins. Without JENKINS-27295 , this makes it awkward to have a default parameter value. Originally-Committed-As: 4320015acd28c40e6cce462c15e86d4873762f55
            jglick Jesse Glick made changes -
            Link This issue is related to JENKINS-34101 [ JENKINS-34101 ]
            jglick Jesse Glick made changes -
            Epic Link JENKINS-35394 [ 171187 ]
            jglick Jesse Glick made changes -
            Link This issue is related to JENKINS-35698 [ JENKINS-35698 ]
            rtyler R. Tyler Croy made changes -
            Workflow JNJira [ 161500 ] JNJira + In-Review [ 180721 ]
            abayer Andrew Bayer made changes -
            Component/s pipeline-general [ 21692 ]
            abayer Andrew Bayer made changes -
            Component/s workflow-plugin [ 18820 ]
            jglick Jesse Glick made changes -
            Component/s workflow-cps-plugin [ 21713 ]
            Component/s pipeline [ 21692 ]
            Hide
            jglick Jesse Glick added a comment -

            Cf. CpsScript.$initialize.

            Show
            jglick Jesse Glick added a comment - Cf. CpsScript.$initialize .
            jglick Jesse Glick made changes -
            Status Open [ 1 ] In Progress [ 3 ]
            jglick Jesse Glick made changes -
            Remote Link This issue links to "PR 60 (Web Link)" [ 14843 ]
            jglick Jesse Glick made changes -
            Status In Progress [ 3 ] In Review [ 10005 ]
            Hide
            scm_issue_link SCM/JIRA link daemon added a comment -

            Code changed in jenkins
            User: Jesse Glick
            Path:
            src/main/java/org/jenkinsci/plugins/workflow/cps/ParamsVariable.java
            src/main/resources/org/jenkinsci/plugins/workflow/cps/ParamsVariable/help.jelly
            src/test/java/org/jenkinsci/plugins/workflow/cps/ParamsVariableTest.java
            http://jenkins-ci.org/commit/workflow-cps-plugin/ac463507fcfb8e12b34ed6b45af49c2ae204a773
            Log:
            [FIXED JENKINS-27295] Offering a new global variable params for typed access to ParametersAction.

            Show
            scm_issue_link SCM/JIRA link daemon added a comment - Code changed in jenkins User: Jesse Glick Path: src/main/java/org/jenkinsci/plugins/workflow/cps/ParamsVariable.java src/main/resources/org/jenkinsci/plugins/workflow/cps/ParamsVariable/help.jelly src/test/java/org/jenkinsci/plugins/workflow/cps/ParamsVariableTest.java http://jenkins-ci.org/commit/workflow-cps-plugin/ac463507fcfb8e12b34ed6b45af49c2ae204a773 Log: [FIXED JENKINS-27295] Offering a new global variable params for typed access to ParametersAction.
            jglick Jesse Glick made changes -
            Resolution Fixed [ 1 ]
            Status In Review [ 10005 ] Resolved [ 5 ]
            Hide
            josb Jos Backus added a comment -

            Thanks, @jglick!

            Show
            josb Jos Backus added a comment - Thanks, @jglick!
            Hide
            git Thomas Gimpel added a comment -

            With the update of pipeline plugin "Pipeline: Groovy" from version 2.17 to version 2.18, which includes the fix for issue JENKINS-27295 the following Jenkins file does not work any longer:

            /*
             * Make booleans from string parameters
             */
            skipVs2012 = skipVs2012.toBoolean();
            skipUbuntu32 = skipUbuntu32.toBoolean();
            
            class Slave {
                String name;
                Boolean skip;
            };
            stage('Build') {
                Slave[] slaves = [
                    [
                        name: 'vs2012',
                        skip: skipVs2012
                    ], [
                        name: 'ubuntu1404-32',
                        skip: skipUbuntu32
                    ]
                ];
                
                for (int i = 0; i < slaves.size(); i++) {
                    Slave slave = slaves.get(i);
                    echo "checking slave ${slave.name}";
                    echo "${slave.name}: ${slave.skip}";
                    if (!slave.skip) {
                        echo "!slave.skip works for ${slave.name}";
                    }
                    if (slave.skip==false) {
                        echo "slave.skip==false works for ${slave.name}";
                    }
                }
            }
            

            Obviously the slave.skip member is now considered to be a string and not a boolean.

            Show
            git Thomas Gimpel added a comment - With the update of pipeline plugin "Pipeline: Groovy" from version 2.17 to version 2.18, which includes the fix for issue JENKINS-27295 the following Jenkins file does not work any longer: /* * Make booleans from string parameters */ skipVs2012 = skipVs2012.toBoolean(); skipUbuntu32 = skipUbuntu32.toBoolean(); class Slave { String name; Boolean skip; }; stage( 'Build' ) { Slave[] slaves = [ [ name: 'vs2012' , skip: skipVs2012 ], [ name: 'ubuntu1404-32' , skip: skipUbuntu32 ] ]; for ( int i = 0; i < slaves.size(); i++) { Slave slave = slaves.get(i); echo "checking slave ${slave.name}" ; echo "${slave.name}: ${slave.skip}" ; if (!slave.skip) { echo "!slave.skip works for ${slave.name}" ; } if (slave.skip== false ) { echo "slave.skip== false works for ${slave.name}" ; } } } Obviously the slave.skip member is now considered to be a string and not a boolean.
            Hide
            jglick Jesse Glick added a comment -

            Thomas Gimpel not sure exactly what “does not work any longer”. Unqualified parameter names are now taken from the environment and would continue to be of type String. If you have a minimal, self-contained, reproducible test case please file a separate issue with details and mark it as blocking this one.

            Show
            jglick Jesse Glick added a comment - Thomas Gimpel not sure exactly what “does not work any longer”. Unqualified parameter names are now taken from the environment and would continue to be of type String . If you have a minimal, self-contained, reproducible test case please file a separate issue with details and mark it as blocking this one.
            Hide
            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.

            Show
            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.
            Hide
            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.

            Show
            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.
            Hide
            hrmpw Patrick Wolf added a comment - - edited

            David Karr 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"
            
            Show
            hrmpw Patrick Wolf added a comment - - edited David Karr 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"
            Hide
            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?

            Show
            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?
            Hide
            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] 
            
            Show
            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]
            cloudbees CloudBees Inc. made changes -
            Remote Link This issue links to "CloudBees Internal OSS-65 (Web Link)" [ 19248 ]

              People

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

                Dates

                Created:
                Updated:
                Resolved: