GitLab runner not carrying node_modules and cache to next job?

Viewed 3544

I have an issue where my e2e tests are failing in GitLab but pass normally. I narrowed down the issue to node_modules and cypress cache are not carrying over to the next job. This is why the WARN Local package.json exists, but node_modules missing, did you mean to install error appears because node_modules isn't there.

I think the reason the cache isn't carrying over is because it's being saved on one runner, but if the next job is on another runner the cache won't be there and will end up failing. I could put everything in one job but if I were to add another job for deploying then I would still have the same issue.

Here is my gitlab-ci.yml file:

image: cypress/base:12.18.4

variables:
  NPM_REGISTRY: https://registry.npmjs.org/
  npm_config_cache: $CI_PROJECT_DIR/.npm
  CYPRESS_CACHE_FOLDER: $CI_PROJECT_DIR/cache/Cypress

stages:
  - build
  - test:unit
  - test:e2e
  - lint

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - cache/Cypress
    - node_modules/

build:
  stage: build
  script:
    # set the npm registry if different from the default
    - npm config set registry $NPM_REGISTRY
    - npm i
    - npx cypress verify

test:unit:
  stage: test:unit
  script:
    - npm run test:unit:coverage
  artifacts:
    paths:
      - tests/unit/out/coverage
    when: always
    expire_in: 1 hour

test:e2e:
  stage: test:e2e
  script:
    - npm run test:e2e:headless
  artifacts:
    paths:
      - tests/e2e/out/reports
      - tests/e2e/out/coverage
    when: always
    expire_in: 1 hour

lint:
  stage: lint
  script:
    - npm run lint

This is the error log in GitLab:

Restoring cache
00:01
Updating CA certificates...
Checking cache for fix-gitlab-pipeline...
No URL provided, cache will not be downloaded from shared cache server. Instead a local version of cache will be extracted. 
Successfully extracted cache
Executing "step_script" stage of the job script
00:01
$ npm run test:e2e:headless
> start-test serve:e2e 8089 'cypress run'
sh: 1: start-test: not found
npm ERR! code ELIFECYCLE
npm ERR! syscall spawn
npm ERR! file sh
npm ERR! errno ENOENT
npm ERR! rds@0.1.0 test:e2e:headless: `start-test serve:e2e 8089 'cypress run'`
npm ERR! spawn ENOENT
npm ERR! 
npm ERR! Failed at the test@0.1.0 test:e2e:headless script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?
npm ERR! A complete log of this run can be found in:
npm ERR!     /builds/test/.npm/_logs/2021-01-05T17_16_55_957Z-debug.log
Uploading artifacts for failed job
00:00
Updating CA certificates...
WARNING: ca-certificates.crt does not contain exactly one certificate or CRL: skipping
WARNING: ca-cert-ca.pem does not contain exactly one certificate or CRL: skipping
Uploading artifacts...
WARNING: tests/e2e/out/reports: no matching files  
WARNING: tests/e2e/out/coverage: no matching files 
ERROR: No files to upload                          
ERROR: Job failed: exit code 1
1 Answers

I answered a similar issue here: https://stackoverflow.com/a/65798418/2307873

The gist is that by default, each runner stores cached items on that runner's filesystem, so other runners won't be able to access it. You can configure the path it's stored in, if your runners can connect to a shared filesystem, or you can use S3 (or equivalent for GC or Azure) or anything that implements those API's. We use Minio (https://min.io) which implements the S3 API.

Docs for gitlab and Minio are in the linked answer.

Related