ci: eliminate cold pnpm install via pre-baked CI base image (Phase 1)
Every pipeline ran a cold pnpm install (network fetch + musl native rebuilds + apk add python3 make g++), median ~731s, paid twice per push. Phase 1 (no cluster access, repo commits only): - Dockerfile.ci: node:22-alpine + python3/make/g++/postgresql-client + pnpm@10.6.2 + pnpm fetch to warm the store and compile natives once. - .woodpecker/ci-image.yml: kaniko build/push of ci-base:latest + a lockfile-hash tag, triggered only when pnpm-lock.yaml or Dockerfile.ci change. Reuses the publish.yml kaniko/auth pattern. - ci.yml + publish.yml: install from the baked ci-base:latest, drop the per-run apk add, use pnpm install --frozen-lockfile --prefer-offline. - Framework monorepo template: single cached install other steps depend on instead of re-running npm ci across 6 steps. Node 22->24 bump is a separate follow-up PR. Phase 2 (RWX Longhorn PVC) is out of scope. Expected install ~731s -> ~30-60s. Refs #634 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -2,12 +2,20 @@
|
||||
when:
|
||||
- event: [push, pull_request, manual]
|
||||
|
||||
# Dependencies are installed ONCE in the `install` step and every downstream
|
||||
# step depends on it, reusing the populated node_modules from the shared
|
||||
# workspace volume. Do NOT re-run `npm ci` per step — that pays the full cold
|
||||
# install (network fetch + native rebuilds) N times and is the dominant cost
|
||||
# in a pipeline.
|
||||
#
|
||||
# For best results, replace `&node_image` with a pre-baked CI base image that
|
||||
# ships your toolchain (python3/make/g++ for native modules) and a warm npm
|
||||
# cache, then keep `--prefer-offline` so installs resolve from the cache. See
|
||||
# the Mosaic Stack repo's Dockerfile.ci + .woodpecker/ci-image.yml for the
|
||||
# baked-image pattern.
|
||||
variables:
|
||||
- &node_image 'node:20-alpine'
|
||||
- &gitleaks_image 'ghcr.io/gitleaks/gitleaks:v8.24.0'
|
||||
- &install_deps |
|
||||
corepack enable
|
||||
npm ci --ignore-scripts
|
||||
|
||||
steps:
|
||||
# Secret scanning (runs in parallel with install, no deps)
|
||||
@@ -17,15 +25,18 @@ steps:
|
||||
- gitleaks git --redact --verbose --log-opts="HEAD~1..HEAD"
|
||||
depends_on: []
|
||||
|
||||
# Single cached install. Every other step depends on this and reuses the
|
||||
# node_modules it produces in the shared workspace.
|
||||
install:
|
||||
image: *node_image
|
||||
commands:
|
||||
- *install_deps
|
||||
- corepack enable
|
||||
- npm ci --ignore-scripts --prefer-offline
|
||||
depends_on: []
|
||||
|
||||
security-audit:
|
||||
image: *node_image
|
||||
commands:
|
||||
- *install_deps
|
||||
- npm audit --audit-level=high
|
||||
depends_on:
|
||||
- install
|
||||
@@ -35,7 +46,6 @@ steps:
|
||||
environment:
|
||||
SKIP_ENV_VALIDATION: 'true'
|
||||
commands:
|
||||
- *install_deps
|
||||
- npm run lint
|
||||
depends_on:
|
||||
- install
|
||||
@@ -45,7 +55,6 @@ steps:
|
||||
environment:
|
||||
SKIP_ENV_VALIDATION: 'true'
|
||||
commands:
|
||||
- *install_deps
|
||||
- npm run type-check
|
||||
depends_on:
|
||||
- install
|
||||
@@ -55,7 +64,6 @@ steps:
|
||||
environment:
|
||||
SKIP_ENV_VALIDATION: 'true'
|
||||
commands:
|
||||
- *install_deps
|
||||
- npm run test -- --coverage --coverageThreshold='{"global":{"branches":80,"functions":80,"lines":80,"statements":80}}'
|
||||
depends_on:
|
||||
- install
|
||||
@@ -66,7 +74,6 @@ steps:
|
||||
SKIP_ENV_VALIDATION: 'true'
|
||||
NODE_ENV: 'production'
|
||||
commands:
|
||||
- *install_deps
|
||||
- npm run build
|
||||
depends_on:
|
||||
- lint
|
||||
|
||||
Reference in New Issue
Block a user