I'm struggling with Gitlab CI
and pnpm
. I have a simple pipeline with npm
, two stages, install and test, using cache:
stages:
- install
- test
install:
stage: install
tags:
- node:LTS
script:
- npm install
cache:
key: node_modules
paths:
- node_modules
only:
- develop
test:
stage: test
tags:
- node:LTS
cache:
key: node_modules
paths:
- node_modules
policy: pull
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
dependencies:
- install
script:
- npm run test:ci
only:
- develop
artifacts:
when: always
reports:
junit: coverage/junit-report.xml
coverage_report:
coverage_format: cobertura
path: coverage/coverage-final.json
This works perfectly fine, and I want to take advantage of pnpm
and start using it. According to the docs, I modified my code as follows:
install:
stage: install
tags:
- node:LTS
before_script:
- corepack enable
- corepack prepare pnpm@latest-7 --activate
- pnpm config set store-dir .pnpm-store
script:
- pnpm install # install dependencies
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store
only:
- develop
- /\d+\.\d+\.\d+$/
test:
stage: test
tags:
- node:LTS
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
dependencies:
- install
script:
- pnpm test:ci
only:
- develop
artifacts:
when: always
reports:
junit: coverage/junit-report.xml
coverage_report:
coverage_format: cobertura
path: coverage/coverage-final.json
As you can imagine, it doens't work. In test stage, I get this error:
$ pnpm test:ci
/bin/bash: line 140: pnpm: command not found
Do I have to add the before_script
in every stage whereI want to use pnpm
? I saw many examples on the internet, one of them Here, but I don't know if I have to add this
default:
image: node:lts-alpine
cache: &cache
key: "$CI_COMMIT_REF_SLUG"
paths:
- .pnpm-store
- ./node_modules
- apps/web/node_modules
policy: pull
before_script:
- npm i -g pnpm
- pnpm config set store-dir .pnpm-store
Any help would be appreciated
We have pnpm running in our Gitlab CI pipelines. What we do is run before_script
and add pnpm to every task. I'm not sure if it's the best way to go about it, but it works. My guess is that since each job/task runs in isolation, it doesn't know aobut the previous task's installation of pnpm. It can access the cache though because you instruct it to, but that doesn't mean that the pnpm CLI is installed.
Taking our configuration and applying it to your example would be as below.
Two things to add:
before_script
to install pnpm CLI to this runner instancecache
to utilize the cache you have populated in install
stepinstall:
stage: install
tags:
- node:LTS
before_script:
- corepack enable
- corepack prepare pnpm@latest-7 --activate
- pnpm config set store-dir .pnpm-store
script:
- pnpm install # install dependencies
cache:
key:
files:
- pnpm-lock.yaml
paths:
- .pnpm-store
only:
- develop
- /\d+\.\d+\.\d+$/
test:
stage: test
tags:
- node:LTS
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
dependencies: # this one we don't have, not sure if you need to keep it?
- install
before_script: # add this
- corepack enable
- corepack prepare pnpm@latest-7 --activate
- pnpm config set store-dir .pnpm-store
cache: # tell Gitlab to pull from cache
- key:
files:
- pnpm-lock.yaml
prefix: pnpm-cache
paths:
- .pnpm-cache
policy: pull
script:
- pnpm test:ci
only:
- develop
artifacts:
when: always
reports:
junit: coverage/junit-report.xml
coverage_report:
coverage_format: cobertura
path: coverage/coverage-final.json