0

My bash command looks like this:

BRANCH="v23"
ENV="local"
COMPONENTS=(alpha beta gamma)
CLUSTERs=()

echo "Branch:       ${BRANCH}"
echo "Environment:  ${ENV}"
echo "Components:   ${COMPONENTS[@]}"

for A_COMPONENT in ${COMPONENTS[@]}; do
  CLUSTERs+=("${ENV}-${A_COMPONENT}")
done

echo "Will deploy '${BRANCH}' in CLUSTERs:"
for A_CLUSTER in ${CLUSTERs[@]}; do
  echo "  - ${A_CLUSTER}"
done

which produces the following output:

Branch:       v23
Environment:  local
Components:   alpha beta gamma
Will deploy 'v23' in CLUSTERs:
  - local-alpha
  - local-beta
  - local-gamma


However, my github action looks like this (following similar pattern as the bash script above):

env:
  BRANCH: v23
  ENV: local
  COMPONENTS: (alpha beta gamma)
  CLUSTERs: ()

jobs:
  deploy:
    runs-on: [gha-runner]
    permissions:
      contents: 'read'
      id-token: 'write'
    steps:
      - name: Parameters
        run: |
          echo "Branch:       ${BRANCH}"
          echo "Environment:  ${ENV}"
          echo "Components:   ${COMPONENTS[@]}"

          for A_COMPONENT in ${COMPONENTS[@]}; do
            CLUSTERs+=("${ENV}-${A_COMPONENT}")
          done
          
          echo "Will deploy '${BRANCH}' in CLUSTERs:"
          for A_CLUSTER in ${CLUSTERs[@]}; do
            echo "  - ${A_CLUSTER}"
          done

But the output it produces is this:

Branch:       v23
Environment:  local
Components:   (alpha beta gamma)
Will deploy 'v23' in CLUSTERs:
  - ()
  - local-(alpha
  - local-beta
  - local-gamma)

Notice how the items inside the $CLUSTERs array have broken formats and have produced 4 values instead of 3.


How should i fix this in github actions syntax?

Rakib
  • 12,376
  • 16
  • 77
  • 113
  • 1
    Environment variables can only contain strings, not arrays. – Barmar Aug 24 '23 at 22:16
  • hi @Barmar. Not sure i understand the comment correctly. My bash example is producing the desired behavior using array in envvar, whereas my GitHubAction example is not (which is also using bash). Can you suggest how can i produce the desired output in GHA? – Rakib Aug 24 '23 at 22:40
  • 1
    There are no environment variables in the first example. Those are shell variables. – Barmar Aug 24 '23 at 22:52
  • 1
    Environment variables are variables that are defined in one process then exported so that they'll be inherited by child processes. Since the environment only contains strings, you can't export arrays. – Barmar Aug 24 '23 at 22:54
  • See https://stackoverflow.com/questions/3341372/difference-between-shell-and-environment-variables – Barmar Aug 24 '23 at 22:55

1 Answers1

2

As Barmar said in a comment, environment variables can only be plain strings, not arrays. This means when you define environment variables like this:

COMPONENTS: (alpha beta gamma)
CLUSTERs: ()

You're not defining those variables as arrays with three and zero elements respectively, you're defining them as the strings "(alpha beta gamma)" and "()" (and in both cases the parentheses are part of the string).

As long as the components in the list don't contain any funny characters (specifically whitespace, asterisks, question marks, or square brackets), you could define COMPONENTS as a space-delimited list, and use word splitting to break it into elements (and don't even try to define CLUSTERs as an env var, just create it directly in bash):

env:
  [...]
  COMPONENTS: alpha beta gamma
[...]
      CLUSTERs=()    # Bash will parse this as an array
      for A_COMPONENT in ${COMPONENTS}; do    # No double-quotes = word splitting
        CLUSTERs+=("${ENV}-${A_COMPONENT}")
      done
[...]

Note that this assumes that the script will run under bash or some other shell that supports arrays; it will fail horribly if run under something like dash (the default shell on Debian and Ubuntu). I'm not familiar with what github actions promise here, but you might want to take whatever steps are appropriate to make sure it uses bash.

BTW, I'd recommend running your script through shellcheck.net and fixing what it points out except for where it complains about ${COMPONENTS} being unquoted -- in this case, it's intentional. Its other recommendation(s) about double-quoting variables are good scripting hygiene, and should be followed.

I'd also recommend switching to lower- or mixed-case variable names. There are a lot of all-caps names that have special meanings or functions, and accidentally using one of those for something else can cause weird problems. So unless you want one of those special meanings, lower- and mixed-case names are safer.

Gordon Davisson
  • 118,432
  • 16
  • 123
  • 151