Built-in Functions

Hello,

I tried searching for similar topics but didn’t find anything related to this specific matter, but maybe I’ve been using the wrong terminology so I’ll try to break it down.

Problem

There’s a recurring pattern in our build files related to string manipulation of environment variables and parameters that apparently cannot be solved “natively” through the CircleCI config file, and it forces us to embed custom scripts into our workflows and jobs declarations.

Example

  • We want to create a Kubernetes namespace for each Git branch that we push to our repository
  • The natural approach would be to name the Kubernetes namespace after the branch name itself
  • Branches are not always named in a way that Kubernetes would accept them as namespace. For instance, a branch named PROJ-123-some-crazy-feature would not qualify as a valid namespace name due to the PROJ uppercase characters
  • Transforming the branch name into lowercase-only characters would solve this, but in order to apply such transformation we’d need to embed some scripting into every place where we need the transformation to happen, something like:
workflows:
  development:
    jobs:
      - build
      # Some other jobs...
      - prepare-infra:
          context: dev
          kubernetes-namespace: $(echo "${CIRCLE_PROJECT_REPONAME}-${CIRCLE_BRANCH}" | awk '{print tolower($0)}')
      - deploy-chart:
          context: dev
          kubernetes-namespace: $(echo "${CIRCLE_PROJECT_REPONAME}-${CIRCLE_BRANCH}" | awk '{print tolower($0)}')
          requires:
            - prepare-infra

In particular, I was expecting something like this (notice the var parameter in the terraform/apply step):

jobs:
  - prepare-infra:
      parameters:
        kubernetes-namespace:
          type: string
      steps:
        - terraform/apply:
            var: 'namespace_name=<< parameters.kubernetes-namespace | tolower >>'
workflows:
  development:
    jobs:
      - build
      # Some other jobs...
      - prepare-infra:
          context: dev
          kubernetes-namespace: '${CIRCLE_PROJECT_REPONAME}-${CIRCLE_BRANCH}'
      - deploy-chart:
          context: dev
          kubernetes-namespace: '${CIRCLE_PROJECT_REPONAME}-${CIRCLE_BRANCH}'
          requires:
            - prepare-infra

I guess it would be something similar to what Jinja offers as “filters”.

Questions

  1. Is this possible?
  2. Are there built-in functions in the lines of tolower that we can use to avoid embedding custom scripts?
  3. Moreover, is there for us to define custom functions/filters?

The challenge here is the idea of trying to do this at compile time. When talking about Jinja, you are not too far off from how << >> is expanded into a compiled configuration. With that said, the template compilation does not provide features like Jinja filters or Mustache lambdas. It is essentially a straight text replacement with few extras. Like you can actually do <<#parameters.truthy>>included<</parameters.truthy>> if you have a true / false boolean parameter.

You might want to think about making a feature request about that since I was a little surprised I could not find one there already.

With that said, the best option available right now is to perform those transformations in bash once they get to an executed script. I imagine in your case, this may be more difficult if you are making use of Orbs that you do not control.

Hope that is a little bit helpful and once again, I would encourage you to send in a feature request to raise the visibility of your use-case.

1 Like

Thank you!
The link to the feature request is: Built-in Functions | API Feature Requests | CircleCI Ideas