Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have a "cache per package.json" file in GitLab CI?

I have a Vue web application that is built, tested and deployed using GitLab CI.

GitLab CI has a "Cache" feature where specific products of a Job can be cached so that future runs of the Job in the same Pipeline can be avoided and the cached products be used instead.

I'd like to improve my workflow's performance by caching the node_modules directory so it can be shared across Pipelines.

GitLab Docs suggests using ${CI_COMMIT_REF_SLUG} as the cache key to achieve this. However, this means "caching per-branch" and I would like to improve on that.

I would like to have a cache "per package.json". That is, only if there is a change in the contents of package.json will the cache key change and npm install will be run.

I was thinking of using a hash of the contents of the package.json file as the cache key. Is this possible with GitLab CI? If so, how?

like image 781
urig Avatar asked Nov 25 '18 20:11

urig


People also ask

What is cache in Gitlab CI?

all tiers. A cache is one or more files a job downloads and saves. Subsequent jobs that use the same cache don't have to download the files again, so they execute more quickly.

Where is Gitlab cache stored?

By default, they are stored locally in the machine where the Runner is installed and depends on the type of the executor. Locally, stored under the gitlab-runner user's home directory: /home/gitlab-runner/cache/<user>/<project>/<cache-key>/cache. zip .


2 Answers

This is now possible as of Gilab Runner v12.5

cache:
  key:
    files:
      - Gemfile.lock
      - package-lock.json // or yarn.lock
  paths:
    - vendor/ruby
    - node_modules

It means cache key will be a SHA checksum computed from the most recent commits (up to two, if two files are listed) that changed the given files. Whenever one of these files changes, a new cache key is computed and a new cache is created. Any future job runs using the same Gemfile.lock and package.json with cache:key:files will use the new cache, instead of rebuilding the dependencies.

More info: https://docs.gitlab.com/ee/ci/yaml/#cachekeyfiles

Also make sure to use always --frozen-lockfile flag in your CI jobs. (or npm ci) Regular npm install or yarn install / yarn commands generate new lock files and you wouldn't usually notice it until you install packages again. Thus makes your build artifacts and caches inconsistent.

like image 129
Shinebayar G Avatar answered Oct 31 '22 05:10

Shinebayar G


For that behavior use only:changes parameter with a static cache name.

Ex:

install:
  image: node:latest
  script:
    - npm install
  cache:
    untracked: true 
    key: npm  #static name, can use any branch, any commit, etc..
    paths:
      - node_modules
  only:  #Only execute this job when theres a change in package.json
    changes:
      - package.json

If you need read this to set cache properly in runners: https://docs.gitlab.com/runner/configuration/autoscale.html#distributed-runners-caching https://docs.gitlab.com/ee/ci/caching/

like image 20
jwillker Avatar answered Oct 31 '22 06:10

jwillker