Using git function to compute cache key hash fails

Hi,

We use in our project a javascript CLI for dev related tasks and we wanted to cache the compiled version across workflows as it changes less the code. To do so, I tried the following code:

  install_standalone_cli:
    steps:
      - restore_cache:
          keys:
            # `git log -n 1 --pretty=format:%H -- cli/` finds the last commit hash modifying the cli folder
            - javascript-cli-v1-{{ git log -n 1 --pretty=format:%H -- cli/ }}
      - run:
          name: Compile CLI
          command: |
            rm -rf cli/lib cli/tsconfig.tsbuildinfo
            yarn build-cli
            yarn compile-cli
      - save_cache:
          key: javascript-cli-v1-{{ git log -n 1 --pretty=format:%H -- cli/ }}
          paths:
            - ./myCliExecutable.js

This command is called in the following job:

  sonar_analysis:
    executor: jdk17-docker
    resource_class: large
    working_directory: ~/myProject
    environment:
      MVN_REPO: /home/circleci/.m2/repository
      MVN_SETTINGS: .circleci/resources/settings.xml
    steps:
      - checkout
      - restore_java_cache
      - install_cli
      - compile_project:
          parallel: -T 1C
      - run:
          name: Analyse project
          command: |
            if [ -n "$CIRCLE_PULL_REQUEST" ]
            then
              GITHUB_PULL_REQUEST_ID=${CIRCLE_PULL_REQUEST##*/}
              mvn --settings .circleci/resources/settings.xml -Dmaven.repo.local=${HOME}/.m2/repository \
                -Dsonar.pullrequest.base=$VERSION \
                -Dsonar.pullrequest.branch=$CIRCLE_BRANCH \
                -Dsonar.pullrequest.key=$GITHUB_PULL_REQUEST_ID \
                sonar:sonar
            else
              mvn --settings .circleci/resources/settings.xml -Dmaven.repo.local=${HOME}/.m2/repository \
                -Dsonar.branch.name=${CIRCLE_BRANCH} \
                sonar:sonar
            fi

With the following definition for the executor and other commands:

  jdk17-docker:
    docker:
      - image: cimg/openjdk:17.0.5-node
  install_cli:
    steps:
      - install_javascript_env
      - install_standalone_cli

Unfortunately, the caching/restoring steps always fails in the job with the following error message:

error computing cache key: template: cacheKey:1: function "git" not defined

I don’t understand why that fails, as per documentation (cimg/openjdk - CircleCI) git is contained in that image.

Thanks in advance !

I managed to find a workaround for doing so by writing into a file the hash and checking the checksum of this file:

  save_git_hash_for_cli:
    steps:
      - run:
          name: Identify last changes in CLI for caching
          command: |
            GIT_HASH_CLI_LAST_CHANGE="$(git log -n 1 --pretty=format:%H -- cli/)"
            echo "$GIT_HASH_CLI_LAST_CHANGE" | tee /tmp/javascript_cli.custom_lock


  install_standalone_cli:
    steps:
      - save_git_hash_for_cli
      - restore_cache:
          keys:
            - javascript-cli-v1-{{ checksum "/tmp/javascript_cli.custom_lock" }}
      - run:
          name: Compile CLI
          command: |
            if [ ! -e ./myCompiledCli.js ]
            then
              rm -rf cli/lib cli/tsconfig.tsbuildinfo
              yarn build-cli
              yarn compile-cli
            else
              echo "CLI restored from cache and not compiled"
            fi
      - save_cache:
          key: javascript-cli-v1-{{ checksum "/tmp/javascript_cli.custom_lock" }}
          paths:
            - ./myCompiledCli.js

When you are executing the json expression

 {{ git log -n 1 --pretty=format:%H -- cli/ }}

//are you sure that git is on the path to all it to be found/executed?//

I think I need to expand my question to - can an external command like git be used in this type of expression (I’m trying to understand how it works at the moment :slight_smile:

It turns out you are quite limited in the commands you can pass, see https://circleci.com/docs/configuration-reference/#savecache