Skip to content
shellhacks.dev
DevOps

Cache Dependencies in GitLab CI with cache:key:files

Cache dependencies in GitLab CI with cache:key:files so the key follows the lock file, and share one definition between jobs with a YAML anchor and a changed policy.

2 min read
Summarize in AI

Several jobs need the same dependency cache, and only one of them should upload it.

YAML
.node-cache: &node-cache
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/
  policy: pull

install:
  script: npm ci
  cache:
    <<: *node-cache
    policy: pull-push

test:
  script: npm test
  cache: *node-cache
Python
import yaml

doc = yaml.safe_load("""
.node-cache: &node-cache
  key:
    files:
      - package-lock.json
  paths:
    - node_modules/
  policy: pull

install:
  script: npm ci
  cache:
    <<: *node-cache
    policy: pull-push

test:
  script: npm test
  cache: *node-cache
""")
for job in ("install", "test"):
    print(job, doc[job]["cache"])
Text
install {'key': {'files': ['package-lock.json']}, 'paths': ['node_modules/'], 'policy': 'pull-push'}
test {'key': {'files': ['package-lock.json']}, 'paths': ['node_modules/'], 'policy': 'pull'}

key:files derives the cache key from the lock file, so it changes when the dependencies do. The anchor &node-cache names the block once, *node-cache reuses it, and <<: *node-cache merges it into a mapping so the job can override a field. The parsed result shows install with policy: pull-push and test with policy: pull, which means install saves the cache and test only reads it. See Caching in GitLab CI/CD.

Cache paths must be inside the project directory, and a cache is best effort: a job has to work without it. A job that can run in parallel with a failing one may still restore an older entry. GitLab also offers extends and !reference for reuse. The parser here is PyYAML, not GitLab's.

Taggedgitlab ci
Share

More snippets

Get new posts by email

One email when a new post is published. No spam.

Unsubscribe in one click. No spam, ever.