Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
pnpm 10.x reference skill covering workspaces, catalogs, patches, peer deps, overrides, and CI/CD caching strategies.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
references/best-practices-ci.md
1---2name: pnpm-ci-cd-setup3description: Optimizing pnpm for continuous integration and deployment workflows4---56# pnpm CI/CD Setup78Best practices for using pnpm in CI/CD environments for fast, reliable builds.910## GitHub Actions1112### Basic Setup1314```yaml15name: CI1617on: [push, pull_request]1819jobs:20build:21runs-on: ubuntu-latest22steps:23- uses: actions/checkout@v42425- uses: pnpm/action-setup@v426with:27version: 92829- uses: actions/setup-node@v430with:31node-version: 2032cache: 'pnpm'3334- run: pnpm install --frozen-lockfile35- run: pnpm test36- run: pnpm build37```3839### With Store Caching4041For larger projects, cache the pnpm store:4243```yaml44- uses: pnpm/action-setup@v445with:46version: 94748- name: Get pnpm store directory49shell: bash50run: |51echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV5253- uses: actions/cache@v454name: Setup pnpm cache55with:56path: ${{ env.STORE_PATH }}57key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}58restore-keys: |59${{ runner.os }}-pnpm-store-6061- run: pnpm install --frozen-lockfile62```6364### Matrix Testing6566```yaml67jobs:68test:69runs-on: ${{ matrix.os }}70strategy:71matrix:72os: [ubuntu-latest, windows-latest, macos-latest]73node: [18, 20, 22]74steps:75- uses: actions/checkout@v476- uses: pnpm/action-setup@v477- uses: actions/setup-node@v478with:79node-version: ${{ matrix.node }}80cache: 'pnpm'81- run: pnpm install --frozen-lockfile82- run: pnpm test83```8485## GitLab CI8687```yaml88image: node:208990stages:91- install92- test93- build9495variables:96PNPM_HOME: /root/.local/share/pnpm97PATH: $PNPM_HOME:$PATH9899before_script:100- corepack enable101- corepack prepare pnpm@latest --activate102103cache:104key: ${CI_COMMIT_REF_SLUG}105paths:106- .pnpm-store107108install:109stage: install110script:111- pnpm config set store-dir .pnpm-store112- pnpm install --frozen-lockfile113114test:115stage: test116script:117- pnpm test118119build:120stage: build121script:122- pnpm build123```124125## Docker126127### Multi-Stage Build128129```dockerfile130# Build stage131FROM node:20-slim AS builder132133# Enable corepack for pnpm134RUN corepack enable135136WORKDIR /app137138# Copy package files first for layer caching139COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./140COPY packages/*/package.json ./packages/141142# Install dependencies143RUN pnpm install --frozen-lockfile144145# Copy source and build146COPY . .147RUN pnpm build148149# Production stage150FROM node:20-slim AS runner151152RUN corepack enable153WORKDIR /app154155COPY --from=builder /app/dist ./dist156COPY --from=builder /app/package.json ./157COPY --from=builder /app/pnpm-lock.yaml ./158159# Production install160RUN pnpm install --frozen-lockfile --prod161162CMD ["node", "dist/index.js"]163```164165### Optimized for Monorepos166167```dockerfile168FROM node:20-slim AS builder169RUN corepack enable170WORKDIR /app171172# Copy workspace config173COPY pnpm-lock.yaml pnpm-workspace.yaml ./174175# Copy all package.json files maintaining structure176COPY packages/core/package.json ./packages/core/177COPY packages/api/package.json ./packages/api/178179# Install all dependencies180RUN pnpm install --frozen-lockfile181182# Copy source183COPY . .184185# Build specific package186RUN pnpm --filter @myorg/api build187```188189## Key CI Flags190191### --frozen-lockfile192193**Always use in CI.** Fails if `pnpm-lock.yaml` needs updates:194195```bash196pnpm install --frozen-lockfile197```198199### --prefer-offline200201Use cached packages when available:202203```bash204pnpm install --frozen-lockfile --prefer-offline205```206207### --ignore-scripts208209Skip lifecycle scripts for faster installs (use cautiously):210211```bash212pnpm install --frozen-lockfile --ignore-scripts213```214215## Corepack Integration216217Use Corepack to manage pnpm version:218219```json220// package.json221{222"packageManager": "[email protected]"223}224```225226```yaml227# GitHub Actions228- run: corepack enable229- run: pnpm install --frozen-lockfile230```231232## Monorepo CI Strategies233234### Build Changed Packages Only235236```yaml237- name: Build changed packages238run: |239pnpm --filter "...[origin/main]" build240```241242### Parallel Jobs per Package243244```yaml245jobs:246detect-changes:247runs-on: ubuntu-latest248outputs:249packages: ${{ steps.changes.outputs.packages }}250steps:251- uses: actions/checkout@v4252with:253fetch-depth: 0254- id: changes255run: |256echo "packages=$(pnpm --filter '...[origin/main]' list --json | jq -c '[.[].name]')" >> $GITHUB_OUTPUT257258test:259needs: detect-changes260if: needs.detect-changes.outputs.packages != '[]'261runs-on: ubuntu-latest262strategy:263matrix:264package: ${{ fromJson(needs.detect-changes.outputs.packages) }}265steps:266- uses: actions/checkout@v4267- uses: pnpm/action-setup@v4268- run: pnpm install --frozen-lockfile269- run: pnpm --filter ${{ matrix.package }} test270```271272## Best Practices Summary2732741. **Always use `--frozen-lockfile`** in CI2752. **Cache the pnpm store** for faster installs2763. **Use Corepack** for consistent pnpm versions2774. **Specify `packageManager`** in package.json2785. **Use `--filter`** in monorepos to build only what changed2796. **Multi-stage Docker builds** for smaller images280281<!--282Source references:283- https://pnpm.io/continuous-integration284- https://github.com/pnpm/action-setup285-->286