Cache: Calculate key based on multiple locations

Created on 8 Jan 2020  路  7Comments  路  Source: actions/cache

It would be great to have the ability to calculate cache key based on multiple locations. Have a look at my example project: https://github.com/railsconfig/config

- uses: actions/cache@v1
  with:
    path: vendor/bundle
    key: ${{ runner.os }}-gem-${{ hashFiles('**/gemfiles/**') }}-${{ hashFiles('*.gemspec') }}

would be better expressed as:

- uses: actions/cache@v1
  with:
    path: vendor/bundle
    key: ${{ runner.os }}-gem-${{ hashFiles(['**/gemfiles/**', '*.gemspec']) }}

Unfortunately, there is no way to pass an array of files to the hashFiles function.

documentation

Most helpful comment

馃憢 Hi all, this is supported by hashFiles but not documented.

To specify multiple patterns, you can pass a comma separated list:

hashFiles('.config/dotnet-tools.json', '**/packages.lock.json')

I will make sure this is documented.

All 7 comments

Just ran into this myself - for Gradle a recommended config is to have dependency versions declared in gradle.properties but in our build there are also version numbers in another build.gradle.kts file which in our case doesn't make sense to include in gradle.properties.

For cache purposes both files should be treated as a single unit.

It is possible if you generate the checksum yourself.

Example here: https://github.com/chrisbanes/tivi/blob/master/.github/workflows/build.yml

     - name: Generate cache key
        run: ./checksum.sh checksum.txt

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - uses: actions/[email protected]
        with:
          path: ~/.gradle/caches
          key: ${{ runner.os }}-gradle-${{ hashFiles('checksum.txt') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

where checksum.sh is

#!/bin/bash
RESULT_FILE=$1

if [ -f $RESULT_FILE ]; then
  rm $RESULT_FILE
fi
touch $RESULT_FILE

checksum_file() {
  echo $(openssl md5 $1 | awk '{print $2}')
}

FILES=()
while read -r -d ''; do
    FILES+=("$REPLY")
done < <(find . -type f \( -name "build.gradle*" -o -name "dependencies.kt" -o -name "gradle-wrapper.properties" \) -print0)

# Loop through files and append MD5 to result file
for FILE in ${FILES[@]}; do
    echo $(checksum_file $FILE) >> $RESULT_FILE
done
# Now sort the file so that it is 
sort $RESULT_FILE -o $RESULT_FILE

Now that cache@v2 is out with support for multiple paths, it would be really nice to add this next. Example usage for dotnet:

- name: Cache packages
  uses: actions/cache@v2
  with:
    path: ${{ github.workspace }}/.nuget/packages
    key: ${{ runner.os }}-nuget-${{ hashFiles(['.config/dotnet-tools.json', '**/packages.lock.json']) }}
    restore-keys: ${{ runner.os }}-nuget-

i.e. I want to include the dotnet-tools.json file in the hash as well (without workarounds).

馃憢 Hi all, this is supported by hashFiles but not documented.

To specify multiple patterns, you can pass a comma separated list:

hashFiles('.config/dotnet-tools.json', '**/packages.lock.json')

I will make sure this is documented.

@joshmgross awesome, thanks! 馃榿

I'm curious, do you guys also own the Azure Pipelines cache task, and if so will this eventually be implemented there too?

do you guys also own the Azure Pipelines cache task, and if so will this eventually be implemented there too?

I, unfortunately, do not work on that task. I'd recommend filing an issue in their repository.

Was this page helpful?
0 / 5 - 0 ratings