Echo/Evaluate external variable to slack orb

Hi all,

I have an issue with CircleCi config.yaml version 2.1 and passing/evaluating variables. I have a script that creates a summary of a file and stores it as variable in $BASH_ENV. This variable needs to be evaluated/echoed in CircleCi’s slack orb as json custom message but unfortunately this throws a parsing error. I tried with setting a simple “hello” message but jq still cannot parse it. If I echo the variable in a different step it shows the contents of this variable correctly.

In my main job I am using a custom private image that the commands runs in, without affecting $BASH_ENV or any environment variables.

Let me know if someone can help or if I am doing something wrong on that matter.

Best Regards and thank you

config.yml

version: 2.1

orbs:
  slack: circleci/slack@4.3.0

commands:
  custom_slack_message:
    steps:
      - run:
          command: |
              ./scripts/store_variable.sh
      - slack/notify:
          custom: |
            {"blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": $MESSAGE }}]}
          event: always
          channel: "a-channel"

scripts/store_variable.sh

#!/bin/bash
# GET THE PLAN FILE
FILE="./.terraform/plan/tfplan"

# GET THE DIFF
plan_diff=$(terraform show $FILE | grep -E "^\s*[#~+-]")

echo "export MESSAGE=\"Changes to be applied from terraform: \`\`\`$plan_diff\`\`\`\"" >> $BASH_ENV; source $BASH_ENV;

Hi @christos ,

Just to rule out possible causes, could you please:

  • Add double-quotes around $MESSAGE in the custom parameter:
{"blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": "$MESSAGE" }}]}

 

  • Replace a pair of double-quotes with single-quotes in the command that sets the MESSAGE variable:
echo 'export MESSAGE=\"Changes to be applied from terraform: \`\`\`$plan_diff\`\`\`\" ' >> $BASH_ENV; source $BASH_ENV;

@christos,

Just to suggest an alternative syntax (double-quote+single-quote+double-quote):

{"blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": "'"$MESSAGE"'" }}]}

Let me know if this helps.

Hi @yannCI,

First of all, I want to thank you for your time to propose suggestions and possible solutions.

I tried all of them but unfortunately nothing worked.

  • The first suggestion was the only that actually send a slack message but unfortunately the message was empty when the variable inside the script wasn’t.

  • The second suggestion failed inside the script and then failed also inside the slack/notify with the same error. Because of that I didn’t try any combination with the 1st or 3rd suggestion. The error I received was:

    /tmp/.bash_env-609d3d727362977939a6d087-0-build: line 1: export: `terraform:’: not a valid identifier
    /tmp/.bash_env-609d3d727362977939a6d087-0-build: line 1: export: ```````"’: not a valid identifier

  • Your third suggestion failed during the slack/notify with the error:

    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 584: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 585: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 586: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 587: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 588: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 589: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 590: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 591: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 592: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 593: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 594: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 595: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 596: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 597: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 598: -: command not found
    /tmp/.bash_env-609d43ce7362977939a6e1cf-0-build: line 599: -: command not found

Do you have any other suggestions?

Thank you

Hi @christos,

Thanks for trying the suggestions out and sharing the outcome.

The errors you’re getting confirm that the issue stems from the position of the quotes and the way they are escaped.

I was able to set the MESSAGE variable with the following syntax:

echo ' export MESSAGE="Changes to be applied from terraform: \`\`\`$plan_diff\`\`\`" ' >> $BASH_ENV; source $BASH_ENV;

To confirm all variables are properly set, could you please modify the first run step as follows:

      - run:
          command: |
              ./scripts/store_variable.sh
              echo $FILE
              echo $plan_diff
              echo $MESSAGE

 
And then use either of the below syntaxes for the custom parameter:

  • “double-quote+single-quote+double-quote”
    {"blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": "'"$MESSAGE"'" }}]}
    
  • “double-quotes”
    {"blocks": [{"type": "section", "text": {"type": "mrkdwn", "text": "$MESSAGE" }}]}
    

Hi @yannCI,

Thank you for the further explanations and suggestions. Could you please elaborate more how you made your last suggestion to work with the echo of the variables. For me outside of the script it doesn’t echoing the variables. I tried with two options:

  • First I echoed inside the script file store_variable.sh:
echo ' export MESSAGE="Changes to be applied from terraform: \`\`\`$plan_diff\`\`\`" ' >> $BASH_ENV; source $BASH_ENV;
echo $FILE
echo $plan_diff
echo $MESSAGE

This echoed all the variables correctly

  • Secondly I tried your suggestion to echo the variables in the command:
  - run:
       command: |
          ./scripts/store_variable.sh
          echo $FILE
          echo $plan_diff
          echo $MESSAGE

This didn’t echo anything like the variables weren’t set at all. For the $FILE and $plan_diff variables logically this is correct as their scope is inside the script and not outside of them. However the $MESSAGE as it got exported inside the $BASH_ENV should have values.

After these two extra tries I am thinking if I am doing something of how I am exporting the variable inside the $BASH_ENV but I would like to know how you made it run on your end.

Thank you

Hi @christos,

Since every run step is a new shell, the command:

export MESSAGE="Changes to be applied from terraform: \`\`\`$plan_diff\`\`\`"

will be executed in a shell that doesn’t know of the plan_diff variable, hence the incomplete value you’re seeing for the MESSAGE variable (Changes to be applied from terraform: ``````)

And if you replace:
plan_diff=$(terraform show $FILE | grep -E "^\s*[#~+-]")
with
echo 'export plan_diff=$(terraform show $FILE | grep -E "^\s*[#~+-]")' >> $BASH_ENV

 
then you’ll also need to replace:
FILE="./.terraform/plan/tfplan"
with
echo ' export FILE="./.terraform/plan/tfplan" ' >> $BASH_ENV
for the same reason as above.

 
To make it work I exported all variables to BASH_ENV:

#!/bin/bash
# GET THE PLAN FILE
echo ' export FILE="./.terraform/plan/tfplan" ' >> $BASH_ENV

# GET THE DIFF
echo 'export plan_diff=$(echo "totototo is tititi")' >> $BASH_ENV

echo 'export MESSAGE="Changes to be applied from terraform: \`\`\`$plan_diff\`\`\`"' >> $BASH_ENV

(Note: You only need to add source $BASH_ENV in the above step if you want to echo the variables within this step. It is not needed for the variables to be interpolated in subsequent steps because in every step, CircleCI uses bash to source BASH_ENV)

Let me know if this works for you.