Right now on an NPM-based Preact project, I'm using gitlab-ci.yml's only
feature to run an install job if there was any change to package-lock.json (and to skip install if not). Then my build job picks up the node_modules cache from the install job:
install:
stage: setup # gitlab.com shared runners are slow; don't run unless there's a reason to install
cache: # even a "echo 'hello world'" script would be about a 30s job, worse if queued
key:
files: [package-lock.json] # the key is a hash of package-lock; branches with it will use this cache :D
paths: [node_modules] # we're not caching npm (ie `npm ci --prefer-offline --cache`) because it's slow
policy: push # override the default behavior of wasting time downloading and unpacking node_modules
script: [npm ci] # I believe in package-lock/npm ci's mission
only:
changes: [package-lock.json] # our forementioned reason to install
refs:
- master
- develop
- merge_requests
build: # uses the default behavior, which runs even if install is skipped; but not if install failed
stage: build
cache:
key:
files: [package-lock.json]
paths: [node_modules]
policy: pull # override the default behavior of wasting time packing and uploading node_modules
script:
- npm run build
artifacts:
paths: [build]
only:
changes:
- src/**/*
- tsconfig.json
- preact.config.js
- package-lock.json
refs:
- master
- develop
- merge_requests
For Yarn you would simply replace any package-lock.json
you see here with yarn.lock
, and replace npm ci
with yarn install --frozen-lockfile
.
Previously, I was doing it all in the build job like this (similar to one of the other answers here):
build:
stage: build
cache:
key:
files: [package-lock.json]
paths: [node_modules]
script:
- test -d node_modules || npm ci
- npm run build
artifacts:
paths: [build]
only:
changes:
- src/**/*
- tsconfig.json
- preact.config.js
- package-lock.json
refs:
- master
- develop
- merge_requests
I changed to the more complicated approach because I thought I was also going to implement caching for npm cache, but I couldn't seem to get that to improve any actual install times -- things actually got worse. I stuck with it though simply because it allowed me to squeeze another 20 seconds out of the lockfile-wasn't-changed scenario. I find both approaches to be valid and effective. In my specific case, caching node_modules has cut about a minute and a half off of deployments.
.yarn
directory, per e.g. classic.yarnpkg.com/en/docs/install-ci; you still need to do the install, but then most (if not all) of the files are already local.yarn install
step which I'd like to skip :/changes
keyword of gitlab-ci.yml to run the job only if the specified field has changed: docs.gitlab.com/ee/ci/yaml/#ruleschanges