Skip to content

Instantly share code, notes, and snippets.

@GromNaN
Last active April 27, 2022 17:26
Show Gist options
  • Save GromNaN/cf61e0c65fe8358d6a8f4516c0d3fcbd to your computer and use it in GitHub Desktop.
Save GromNaN/cf61e0c65fe8358d6a8f4516c0d3fcbd to your computer and use it in GitHub Desktop.
Gitlab CI cache key based on multiple files
build:
image: node:alpine
script:
# Skip build if files are already in cache
- .gitlab-ci/git-tree-changed.sh .gitlab-cache-key '\.(css|js|json)$' ./frontend ./other-frontend-dir ./public/yet-another || (cd ./frontend && npm ci && npm run build)
variables:
# $CACHE_KEY_INDEX is set in project variable, and must be updated each time the CI cache is clear
# Waiting for the issue to be fixed: https://gitlab.com/gitlab-org/gitlab/-/issues/360438#note_923272903
CACHE_FALLBACK_KEY: ${CI_DEFAULT_BRANCH}-build-${CACHE_KEY_INDEX}
cache:
key: ${CI_COMMIT_REF_SLUG}-build
paths:
- .gitlab-cache-key
- frontend/node_modules
- frontend/build
#!/usr/bin/env sh
set -euo pipefail
# Detect changes in a git tree to generate a cache key
# Hash of the updated files is stored into a file that must be keep in cache
# Install git (for alpine). Should be in the machine for perfs.
command -v git > /dev/null || (apk update && apk add git)
if [ "$3" == "" ]
then
echo "Missing arguments."
echo "Exemple:"
echo " git-tree-changed.sh .cache-git-hash '\.(js|css|json)$' ./"
exit 255
fi
cache_file="$1"
grep_pattern="$2"
# Compute a hash from the hash of all versioned files, filtered.
treehash=$(for arg; do git ls-tree -r HEAD --full-name $arg; done|grep -E $grep_pattern|md5sum|cut -d' ' -f1)
if [ ! -f "$cache_file" ]
then
echo "No cache"
echo "$treehash" > "$cache_file"
exit 2
fi
cachedhash=$(cat "$cache_file")
if [ "$cachedhash" == "$treehash" ]
then
echo "No change detected"
exit 0
else
echo "Change detected"
echo "$treehash" > "$cache_file"
exit 3
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment