Dynamically set the value of a job parameter

Dynamically set the value of a job parameter

Sometimes it’s convenient to use a single variable that automatically resolves to the tag or branch that was pushed. You can achieve this using a job parameter along with a helper step to detect the type of push that triggered the workflow.

In your jobs you can create a parameter that uses a special type called env_var_name. This will resolve to the value of an envar matching the value provided to it. It only works in steps evaluated at run time, so it won’t work in when statements which are evaluated when the config is compiled prior to running. Though you can get around this limitation by using pipeline parameters with dynamic config.

    parameters:
      tag-or-branch:
        type: env_var_name
        default: TAGANCH

This will allow you to use parameters which resolve from environment variables throughout the job. Then using a run command we can perform some logic to generate an environment variable using bash logic. It will utilize pipeline parameters to check if a branch or tag is set, and if so assign the envar TAGANCH to it.

      - run:
          name: Tag or Branch
          command: |
              if [[ -z "<< pipeline.git.branch >>" ]]; then
                echo "export TAGANCH=<< pipeline.git.tag >>" >> $BASH_ENV
                else echo "export TAGANCH=<< pipeline.git.branch >>" >> $BASH_ENV
              fi

Then if you have a command in the job where you would like to use the new value you can do so with the parameter variable:

      - tag-image-with-tag:
          image-name: ubuntu
          tag-name: ${<< parameters.tag-or-branch >>}

Complete example

build-and-deploy-ubuntu:
    parameters:
      tag-or-branch:
        type: env_var_name
        default: TAGANCH
    executor: gcp-gcr/default
    steps:
      - checkout
      - persist_to_workspace: *persist_to_workspace
      - build-and-push-image-to-gcr:
          image-name: ubuntu
      - run:
          name: Tag or Branch
          command: |
              if [[ -z "<< pipeline.git.branch >>" ]]; then
                echo "export TAGANCH=<< pipeline.git.tag >>" >> $BASH_ENV
                else echo "export TAGANCH=<< pipeline.git.branch >>" >> $BASH_ENV
              fi
      - tag-image-with-tag:
          image-name: ubuntu
          tag-name: ${<< parameters.tag-or-branch >>}

While the tag and branch were used in this example, you can create many kinds of dynamic variable properties using this technique.

Caveats

Remember this only works in run time steps, and so when statements cannot use the env_var_name generated variable. But you can get around this limitation by using pipeline parameters with dynamic config.

1 Like

Does this example work?

something:
    working_directory: *base_working_directory
    parameters:
      tag-or-branch:
        type: env_var_name
        default: TAGANCH

    docker:
      - image: cimg/base:2020.01
    steps:
      - *checkout
      - prep-kubectl
      - run:
          name: Tag or Branch
          command: |
            if [[ -z "<< pipeline.git.tag >>" ]]; then
              echo "export TAGANCH=<< pipeline.git.tag >>" >> $BASH_ENV
              else echo "export TAGANCH=<< pipeline.git.branch >>" >> $BASH_ENV
            fi
      - run:   
          name: Tag or Branch Debug
          command: echo "tag-or-branch ${<< parameters.tag-or-branch >>}"

Output of the first command:

#!/bin/bash -eo pipefail
if [[ -z “” ]]; then
echo “export TAGANCH=” >> $BASH_ENV
else echo “export TAGANCH=tag-or-branch” >> $BASH_ENV
fi

Output of the second command:

#!/bin/bash -eo pipefail echo “tag-or-branch ${TAGANCH}”

tag-or-branch

CircleCI received exit code 0

after debugging a bit: ${<< parameters.tag-or-branch >>} and the whole env_var_name ceremony doesn’t seem to be necessary and doesn’t work:

However:
tag-name: ${TAGANCH}

works

1 Like