Artifacts and cache

GitLab CI/CD · Practical · 12 min

Jobs share nothing by default, so artifacts and caches are how pipelines move files and save minutes.

Artifacts are files a job produces that GitLab stores: artifacts: paths: lists them and expire_in sets how long they're kept. By default, jobs in later stages download the artifacts of all jobs in earlier stages; dependencies: or needs: restrict that. Artifacts can be browsed and downloaded in the UI.

artifacts:reports are special artifacts GitLab understands: junit test results show in merge requests, and there are report types for coverage, code quality and security scanners. Use when: always so reports upload even when tests fail.

A cache stores dependencies between pipelines to avoid re-downloading them. It lives on the runner (or in shared object storage), is best-effort, and is never guaranteed to exist. Configure cache: key: and paths:; key: files: [package-lock.json] changes the key whenever the lockfile changes. policy: pull on jobs that only read the cache avoids slow uploads.

The rule: artifacts are for passing results between jobs and to people; cache is for speeding things up. Never rely on a cache for correctness. Package managers should point their download directory inside the project (for example PIP_CACHE_DIR: $CI_PROJECT_DIR/.cache/pip), because only paths inside $CI_PROJECT_DIR can be cached or archived.

Example

variables:
  PIP_CACHE_DIR: $CI_PROJECT_DIR/.cache/pip

test:
  image: python:3.13
  cache:
    key:
      files: [requirements.txt]      # new cache when deps change
    paths: [.cache/pip]
  script:
    - pip install -r requirements.txt
    - pytest --junitxml=report.xml
  artifacts:
    when: always                     # upload even if tests fail
    reports:
      junit: report.xml              # shown in the merge request

build:
  stage: build
  script: [make dist]
  artifacts:
    paths: [dist/]
    expire_in: 1 week

Remember

  • Artifacts = outputs for later jobs and humans; cache = speed-up only
  • Key caches on lockfiles with cache:key:files
  • Only paths inside $CI_PROJECT_DIR can be cached or archived

Watch out for

  • Using cache to pass build output to a deploy job; the cache may be missing on another runner.

Check yourself

  1. A deploy job must receive the dist/ folder built two stages earlier. What should the build job use?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.gitlab.com/ci/jobs/job_artifacts/