How to create a reusable command?

Hello. I am new to CircleCI and trying to create my first reusable command. My current config looks like this :

version: 2.1
orbs:
  aws-cli: circleci/aws-cli@3.1
jobs:
  build:
    parameters:
      stage:
        type: string
        default: ""
    executor: aws-cli/default
    steps:
      - aws-cli/setup
      - checkout
      - run: 
          command: |
            stage="${CIRCLE_USERNAME}"
            if [[ -n "<< parameters.stage >>" ]]; then
              STAGE="<< parameters.stage >>"
              stage="<< parameters.stage >>"
            fi
            sed -i "s~SOME_VALUE~$stage~g" test-file.json
            cat test-file.json
workflows:
  build-and-deploy:
    jobs:
      - build:
          stage: development

So essentially if i pass a stage in my workflow, it sets the stage to development if not then set the stage to ${CIRCLE_USERNAME}. I am trying to convert this to a reusable command but having a hard time in doing so and could use some guidance as to what i am doing wrong.

This is my config which is trying to use reusable command :

version: 2.1
orbs:
  aws-cli: circleci/aws-cli@3.1
commands:
  set_stage:
    parameters:
      stage:
        type: string
        default: ""
    steps:
      - run: |
          if [[ -n "<< parameters.stage >>" ]]; then
            stage="<< parameters.stage >>"
          fi
jobs:
  build:
    executor: aws-cli/default
    steps:
      - aws-cli/setup
      - checkout
      - set_stage:
          stage: ${CIRCLE_USERNAME}
      - run: 
          command: |
            sed -i "s~SOME_VALUE~$stage~g" test-file.json
            cat test-file.json

workflows:
  build-and-deploy:
    jobs:
      - build:
          stage: development

Thank you for the assistance.

One of the limitations of the CircleCI scripting ‘language’ is that scripts are pre-processed before execution. The result is that the environment variables made available at runtime are not available/known at the pre-processing stage and so when you do

      - set_stage:
          stage: ${CIRCLE_USERNAME}

You in fact pass the string “${CIRCLE_USERNAME}” as a parameter rather than the runtime value of CIRCLE_USERNAME.

The end result is that you have to place more of your logic within the shell scripts where the environment variables are correctly defined.

The issue is complicated by the way that the script is pre-processed. As the script is now passing “${CIRCLE_USERNAME}” to the command as parameter ‘stage’ it will be injected into the generated script for the shell run command as “${CIRCLE_USERNAME}”, the shell will then process it as an env variable.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.