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

Strings from the "echo" step are suppressed in BlueOcean UI if they contain values found in an environment variable

    Details

    • Type: Bug
    • Status: Open (View Workflow)
    • Priority: Minor
    • Resolution: Unresolved
    • Component/s: blueocean-plugin
    • Labels:
    • Environment:
      Jenkins: 2.138.1
      BlueOcean plugin: 1.8.2
      A clean install on Windows 7 with just a standard set of plugins
      Reproed with Chrome on Windows and Firefox on a Linux desktop
    • Similar Issues:

      Description

      When a string is displayed in the BlueOcean UI from an "echo" step, the string "Print Message" is displayed IF the string being echoed contains a substring that matches the contents of any environment variable. 

      Repro steps:

      Create a pipeline with this code:

      pipeline {
          agent any
          stages {
              stage('test') {
                  environment {
                      THING = 'foobarbuzz'
                  }
                  steps {
                      echo "blah"
                      echo "foobarbuzz"
                      echo "foobarZZZbuzz"
                      echo "This is a $THING here"
                  }
              }
          }
      }

      Run the pipeline via Blue Ocean

      Observe that there are four step labels displayed in the Blue Ocean UI. (see attached screenshot)  The first and third steps display the strings from "echo" as expected.  But, the second and fourth steps display only "Print Message" and don't show the expected string.  The user needs to click the step to expand it to see the string.  I would expect that all strings from all echo statements should show up in the main Blue Ocean UI and would not require some to be manually expended.

       

        Attachments

          Issue Links

            Activity

            sirgnip S Nelson created issue -
            sirgnip S Nelson made changes -
            Field Original Value New Value
            Summary Strings from the "echo" step are suppressed in BlueOcean UI if they contain values found in ENVIRONMENT Strings from the "echo" step are suppressed in BlueOcean UI if they contain values found in an environment variable
            Description When a string is displayed in the BlueOcean UI from an "echo" step, the string "Print Message" is displayed IF the string being echoed contains a substring that matches the contents of any environment variable. 

            Repro steps:

            Create a pipeline with this code:
            {noformat}
            pipeline {
                agent any
                stages {
                    stage('test') {
                        environment {
                            THING = 'foobarbuzz'
                        }
                        steps {
                            echo "blah"
                            echo "foobarbuzz"
                            echo "foobarZZZbuzz"
                            echo "This is a $THING here"
                        }
                    }
                }
            }{noformat}
            Run the pipeline via BlueOcean

            Observe that there are four step labels displayed in the BlueOcean UI.  The first and third steps display the strings as expected.  But, the second and fourth steps display only "Print Message" and don't show the expected string.  The user needs to click the step to expand it to see the string.

             
            When a string is displayed in the BlueOcean UI from an "echo" step, the string "Print Message" is displayed IF the string being echoed contains a substring that matches the contents of any environment variable. 

            Repro steps:

            Create a pipeline with this code:
            {noformat}
            pipeline {
                agent any
                stages {
                    stage('test') {
                        environment {
                            THING = 'foobarbuzz'
                        }
                        steps {
                            echo "blah"
                            echo "foobarbuzz"
                            echo "foobarZZZbuzz"
                            echo "This is a $THING here"
                        }
                    }
                }
            }{noformat}
            Run the pipeline via Blue Ocean

            Observe that there are four step labels displayed in the Blue Ocean UI. (see attached screenshot)  The first and third steps display the strings from "echo" as expected.  But, the second and fourth steps display only "Print Message" and don't show the expected string.  The user needs to click the step to expand it to see the string.  I would expect that all strings from all echo statements should show up in the main Blue Ocean UI and would not require some to be manually expended.

             
            Attachment EchoNotShowingSomeStrings.PNG [ 44522 ]
            Hide
            alisdair_robertson Alisdair Robertson added a comment -

            This does not happen for me for the step echo "Executing On: $env.NODE_NAME" but I do observe it using echo "branch sync @ $scmVars.P4_CHANGELIST" (scmVars returned from the p4sync step) and echo "$tp_mkspec sync @ $env.P4_CHANGELIST" (tp_mkspec is a groovy var)

            Show
            alisdair_robertson Alisdair Robertson added a comment - This does not happen for me for the step echo "Executing On: $env.NODE_NAME" but I do observe it using echo "branch sync @ $scmVars.P4_CHANGELIST" (scmVars returned from the p4sync step) and echo "$tp_mkspec sync @ $env.P4_CHANGELIST" (tp_mkspec is a groovy var)
            Hide
            hbfernandes Hilario Fernandes added a comment -

            I've created a step and implemented the String argumentsToString(Map<String, Object> namedArgs) method and it works most of the time, but it seems that if the argument has and env value in it the argument passed is empty. Is there a way to disable this behaviour or override it?

            Show
            hbfernandes Hilario Fernandes added a comment - I've created a step and implemented the  String argumentsToString(Map<String, Object> namedArgs) method and it works most of the time, but it seems that if the argument has and env value in it the argument passed is empty. Is there a way to disable this behaviour or override it?
            Hide
            marcellodesales Marcello de Sales added a comment - - edited

            Works with Strings = Displays Correctly

            I'm on the same boat... I observed the following:

            • Strings work as expected
            echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server}"
            • If the Strings are separate, they just work (notice the space between the variable and the String "/dashboard/index/"

             

            echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server} /dashboard/index/"

             

            Doesn't work with GStringImpl = Print Message

            • But concatenating Strings with variables, it will result in a GStringImpl, which won't work

             

            echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server}"
            def url = "${context.reports.sonarqube.server}/dashboard/index/${context.library.groupId}:${context.library.artifactId}"
            echo "URL is ${url}"
            • If I concat the String on the same URL above it won't work either

             

            echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server}/dashboard/index/"
            Show
            marcellodesales Marcello de Sales added a comment - - edited Works with Strings = Displays Correctly I'm on the same boat... I observed the following: Strings work as expected echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server}" If the Strings are separate, they just work (notice the space between the variable and the String "/dashboard/index/"   echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server} /dashboard/index/"   Doesn't work with GStringImpl = Print Message But concatenating Strings with variables, it will result in a GStringImpl, which won't work   echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server}" def url = "${context.reports.sonarqube.server}/dashboard/index/${context.library.groupId}:${context.library.artifactId}" echo "URL is ${url}" If I concat the String on the same URL above it won't work either   echo "Running Sonar Scan with reports at ${context.reports.sonarqube.server}/dashboard/index/"
            Hide
            hbfernandes Hilario Fernandes added a comment -

            Marcello de Sales i do not think this is related to GStrings. I've tested with pure hardcoded strings and if any part of the string matches a value of an enviroment variable the string is not shown.

            Show
            hbfernandes Hilario Fernandes added a comment - Marcello de Sales i do not think this is related to GStrings. I've tested with pure hardcoded strings and if any part of the string matches a value of an enviroment variable the string is not shown.
            Hide
            ianfixes Ian Katz added a comment -

            I also question this String/GStringImpl correlation.  You can reproduce this issue by echoing a static string multiple times, as shown in the original attachment for this issue.  In my own case, echoing the exact same static string multiple times produced inconsistent results.

            Show
            ianfixes Ian Katz added a comment - I also question this String/GStringImpl correlation.  You can reproduce this issue by echoing a static string multiple times, as shown in the original attachment for this issue.  In my own case, echoing the exact same static string multiple times produced inconsistent results.
            rkomarov Roman Komarov made changes -
            Attachment print_message_param_string.png [ 47494 ]
            rkomarov Roman Komarov made changes -
            Attachment print_message_param_string.png [ 47495 ]
            Hide
            rkomarov Roman Komarov added a comment -

            Same happens if echo uses a variable from parameters (i.e. anything from params.*). Does not matter if the variable is a String or not, even explicitly converting the params value to String does not help. 

             

            String param_str
            String text_var_2
            
                parameters {
                    string(name: 'str_param', defaultValue: 'no value')
                }
            
            ...
                                param_str = params.str_param.toString()
            
                                echo "string text in double quotes is ${param_str}"
                                echo "simple quoted string is here"
                                echo 'simple quoted string is here' 
                                echo 'Single quoted with str ' + param_str + ' is here'
                                echo param_str                    
                                text_var_2 = 'Single quoted str ' + param_str + ' combined' 
                                echo "GString global text2 is ${text_var_2}" 
                                echo 'String global text2 is' +  text_var_2
            
            

             

             

            The output is as this:

            Anything that contains the variable from param is "Print Message".

            If a variable is a simple string or a calculated integer - it is shown in the step label normally. 

            Show
            rkomarov Roman Komarov added a comment - Same happens if echo uses a variable from parameters (i.e. anything from params.*). Does not matter if the variable is a String or not, even explicitly converting the params value to String does not help.    String param_str String text_var_2 parameters { string(name: 'str_param' , defaultValue: 'no value' ) } ...                     param_str = params.str_param.toString()                     echo "string text in double quotes is ${param_str}"                     echo "simple quoted string is here"                     echo 'simple quoted string is here'                     echo 'Single quoted with str ' + param_str + ' is here'                     echo param_str                                        text_var_2 = 'Single quoted str ' + param_str + ' combined'                     echo "GString global text2 is ${text_var_2}"                     echo ' String global text2 is' +  text_var_2     The output is as this: Anything that contains the variable from param is "Print Message". If a variable is a simple string or a calculated integer - it is shown in the step label normally. 
            Hide
            marcellodesales Marcello de Sales added a comment -

            Ian Katz Hilario Fernandes I will have to take it back after looking at your examples... So far we have observed:

            • Values with references to params
            • Values with references to env

            This is definitely an annoying situation when we want to show information to users

             

            Show
            marcellodesales Marcello de Sales added a comment - Ian Katz Hilario Fernandes I will have to take it back after looking at your examples... So far we have observed: Values with references to params Values with references to env This is definitely an annoying situation when we want to show information to users  
            Hide
            larry_west Larry West added a comment - - edited

            My $0.02 – this is such an annoying bug.  And seemingly trivial to fix.

            We had been telling our users to look in the Blue Ocean output to see what happened to their build, because the graphic view of pipelines has the potential to make it much clearer.

            But then they see 10 or 20 or 50 "Print message" lines and have to click most of them to see the important messages.

            It's not clear there is any purpose behind hiding the text.

            And we often have to tell them how to find their way to the "pipeline.log" to get the full story.

            So it's easier to tell people to just go to the old style console log  

            Show
            larry_west Larry West added a comment - - edited My $0.02 – this is such an annoying bug.  And seemingly trivial to fix. We had been telling our users to look in the Blue Ocean output to see what happened to their build, because the graphic view of pipelines has the potential to make it much clearer. But then they see 10 or 20 or 50 "Print message" lines and have to click most of them to see the important messages. It's not clear there is any purpose behind hiding the text. And we often have to tell them how to find their way to the "pipeline.log" to get the full story. So it's easier to tell people to just go to the old style console log  
            Hide
            rkomarov Roman Komarov added a comment - - edited

            Larry West, I've found an ugly workaround to this - avoid using env and params in echo output as much as possible and then make a second echo showing the actual output. This still leaves lots of "Print message" in BlueOcean output, but at least people can see the actual action within the step.

            But you are right, this is very annoying and users become reluctant to use BO because of this. 

            Show
            rkomarov Roman Komarov added a comment - - edited Larry West , I've found an ugly workaround to this - avoid using env and params in echo output as much as possible and then make a second echo showing the actual output. This still leaves lots of "Print message" in BlueOcean output, but at least people can see the actual action within the step. But you are right, this is very annoying and users become reluctant to use BO because of this. 
            Hide
            mcw Matt C. Wilson added a comment -

            A workaround that we're having success with is removing informational echo calls and instead using the `label` property on `sh`.  This was recently introduced in the Pipeline: Nodes and Processes plugin - required us to upgrade.  

            So 

            echo Doing the thing...

            sh ./the_thing.sh

            becomes

            sh(script: "./the_thing.sh", label: "Doing the thing...")

            and has the nice side effect of reducing the number of rows overall in Blue Ocean.

            https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script
            https://plugins.jenkins.io/workflow-durable-task-step

            Show
            mcw Matt C. Wilson added a comment - A workaround that we're having success with is removing informational echo calls and instead using the ` label ` property on ` sh `.  This was recently introduced in the Pipeline: Nodes and Processes plugin - required us to upgrade.   So  echo Doing the thing... sh ./the_thing.sh becomes sh(script: "./the_thing.sh", label: "Doing the thing...") and has the nice side effect of reducing the number of rows overall in Blue Ocean. https://jenkins.io/doc/pipeline/steps/workflow-durable-task-step/#sh-shell-script https://plugins.jenkins.io/workflow-durable-task-step
            Hide
            marcellodesales Marcello de Sales added a comment -

            Matt C. Wilson Can you specify the versions you tested those? I guess we can just write a script instruction to not echo anything and place the actual String in the label... have you tried that?

            Show
            marcellodesales Marcello de Sales added a comment - Matt C. Wilson Can you specify the versions you tested those? I guess we can just write a script instruction to not echo anything and place the actual String in the label... have you tried that?
            brianjmurrell Brian J Murrell made changes -
            Attachment image-2019-10-24-07-05-23-113.png [ 49301 ]
            Hide
            brianjmurrell Brian J Murrell added a comment - - edited

            Matt C. Wilson Even using {{label:}}s produces inconsistent results:

            Those two steps in the red box are both of the form:

            sh label: <label_name>,
               script: '''...'''
            

            The first one is in the steps portion of the stage and looks like:

            sh label: env.STAGE_NAME,
               script: '''...'''
            

            and the second one is in the post->success portion of the stage and looks like:

             sh label: "Collect artifacts",
                 script: '''...'''
            

            But as you can see, they are displayed quite differently.

            I've opened JENKINS-59918 about this, FWIW.

            Show
            brianjmurrell Brian J Murrell added a comment - - edited Matt C. Wilson Even using {{label:}}s produces inconsistent results: Those two steps in the red box are both of the form: sh label: <label_name>, script: '''...''' The first one is in the steps portion of the stage and looks like: sh label: env.STAGE_NAME, script: '''...''' and the second one is in the post -> success portion of the stage and looks like: sh label: "Collect artifacts", script: '''...''' But as you can see, they are displayed quite differently. I've opened  JENKINS-59918 about this, FWIW.
            Hide
            mcshauno Shaun McDonnell added a comment -

            It's been a year and this hasn't been fixed.  Perhaps the standard/static Jenkins community is starting to die out a little bit in favor of things like Jenkins-X.  

            Show
            mcshauno Shaun McDonnell added a comment - It's been a year and this hasn't been fixed.  Perhaps the standard/static Jenkins community is starting to die out a little bit in favor of things like Jenkins-X.  
            kellcomnet CHRISTOPHER KELLY made changes -
            Link This issue is duplicated by JENKINS-60939 [ JENKINS-60939 ]
            reinholdfuereder Reinhold Füreder made changes -
            Link This issue is related to JENKINS-55612 [ JENKINS-55612 ]
            Hide
            reinholdfuereder Reinhold Füreder added a comment -

            I would also be very happy about this issue being resolved (in order to nicely show a parameter value) and actually would have hoped that this is easy for someone like Liam Newman (of course I am not just trying to challenge him in any way )...

            The workaround with sh step using label attribute also requires a node wrapping context and thus is quite some runtime overhead too.
            JENKINS-55612 could also be considered some overhead with respect to written pipeline code.
            I am quite confused/concerned/surprised about the mentioned/found inconsistencies and whether or not this is actually on purpose (cf. parameter and env values) and why?
            Another workaround is adding a non-printable anywhere in the middle, e.g. for an URL parameter: echo "URL: '${params.URL.replace('.', '.\u007F')}'"

            Show
            reinholdfuereder Reinhold Füreder added a comment - I would also be very happy about this issue being resolved (in order to nicely show a parameter value) and actually would have hoped that this is easy for someone like Liam Newman (of course I am not just trying to challenge him in any way )... The workaround with sh step using label attribute also requires a node wrapping context and thus is quite some runtime overhead too. JENKINS-55612 could also be considered some overhead with respect to written pipeline code. I am quite confused/concerned/surprised about the mentioned/found inconsistencies and whether or not this is actually on purpose (cf. parameter and env values) and why? Another workaround is adding a non-printable anywhere in the middle, e.g. for an URL parameter: echo "URL: '${params.URL.replace('.', '.\u007F')}'"
            Hide
            zett42 Andreas Meyer added a comment -

            I believe this is one of the little bugs that are not really serious but still would make many people happy when fixed, because it is so annoying.

            I've found a generic workaround that doesn't use a shell step, so it's much more efficient. The trick is to temporarily clear the EnvVars for the duration of the "echo" call.

            DISCLAIMER: This workaround disables the masking of secrets during the echo call, so use it at your own risk and especially don't use it within "withCredentials" scope!

            If anyone has an idea to prevent this issue, please reply. We could propably call "getContext" to detect any "withCredentials" context and fallback to plain "echo" in this case. I could live with an occassional "Print Message" in "withCredentials" scopes. Unfortunately "getContext" prints a message on its own, so it's not very useful .

            Sample code:

            pipeline{
                agent any
            
                environment {
                    MY_ENV1 = 'foobarbaz'
                }
                
                parameters { 
                    string(name: 'MY_PARAM', defaultValue: 'bazbarfoo') 
                }
                
                stages {
                    stage('test') {
                        steps {
                            script {
                                env.MY_ENV2 = 'foobazbar'
                                
                                withEnv(['MY_ENV3=bazfoobar']) {
            
                                    // Any of the resolved variable values trigger the "Print message" of plain echo
                                    def msg = "MY_ENV1=$MY_ENV1, MY_ENV2=$MY_ENV2, MY_ENV3=$MY_ENV3, MY_PARAM=$MY_PARAM"
            
                                    echo "echo: $msg"        // Displays "Print Message" as the step label
            
                                    myecho "myecho: $msg"    // Displays the message as the step label, as expected
                                }
                            }
                        }
                    }
                }
            }
            
            // Workaround for "Print message" that is displayed by original echo step if the message
            // contains a value of an environment variable or a pipeline parameter.
            //
            // WARNING: This disables masking of secrets in the output, so don't call it within witCredentials{} scope!
            
            void myecho( String msg ) {
                withContext( new MyEnvClearer() ) {
                    echo msg
                }
            }
            
            // Clears all environment variables, to be used from withContext{}.
            class MyEnvClearer extends org.jenkinsci.plugins.workflow.steps.EnvironmentExpander {
                @NonCPS
                void expand( hudson.EnvVars env ) throws IOException, InterruptedException {
                    env.clear()    
                }    
            }
            
            Show
            zett42 Andreas Meyer added a comment - I believe this is one of the little bugs that are not really serious but still would make many people happy when fixed, because it is so annoying. I've found a generic workaround that doesn't use a shell step, so it's much more efficient. The trick is to temporarily clear the EnvVars for the duration of the "echo" call. DISCLAIMER: This workaround disables the masking of secrets during the echo call, so use it at your own risk and especially don't use it within "withCredentials" scope! If anyone has an idea to prevent this issue, please reply. We could propably call "getContext" to detect any "withCredentials" context and fallback to plain "echo" in this case. I could live with an occassional "Print Message" in "withCredentials" scopes. Unfortunately "getContext" prints a message on its own, so it's not very useful . Sample code: pipeline{ agent any environment { MY_ENV1 = 'foobarbaz' } parameters { string(name: 'MY_PARAM' , defaultValue: 'bazbarfoo' ) } stages { stage( 'test' ) { steps { script { env.MY_ENV2 = 'foobazbar' withEnv([ 'MY_ENV3=bazfoobar' ]) { // Any of the resolved variable values trigger the "Print message" of plain echo def msg = "MY_ENV1=$MY_ENV1, MY_ENV2=$MY_ENV2, MY_ENV3=$MY_ENV3, MY_PARAM=$MY_PARAM" echo "echo: $msg" // Displays "Print Message" as the step label myecho "myecho: $msg" // Displays the message as the step label, as expected } } } } } } // Workaround for "Print message" that is displayed by original echo step if the message // contains a value of an environment variable or a pipeline parameter. // // WARNING: This disables masking of secrets in the output, so don't call it within witCredentials{} scope! void myecho( String msg ) { withContext( new MyEnvClearer() ) { echo msg } } // Clears all environment variables, to be used from withContext{}. class MyEnvClearer extends org.jenkinsci.plugins.workflow.steps.EnvironmentExpander { @NonCPS void expand( hudson.EnvVars env ) throws IOException, InterruptedException { env.clear() } }

              People

              • Assignee:
                Unassigned
                Reporter:
                sirgnip S Nelson
              • Votes:
                22 Vote for this issue
                Watchers:
                25 Start watching this issue

                Dates

                • Created:
                  Updated: