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>
Publish pipeline:
- Add publish-npm step to .woodpecker/publish.yml — publishes all
@mosaic/* packages to Gitea npm registry on main push/tag
- Requires gitea_npm_token Woodpecker secret (package:write scope)
- publish-npm runs after build, parallel with Docker image builds
- pnpm publish resolves workspace:* to concrete versions automatically
Package configuration:
- All 20 packages versioned at 0.0.1-alpha.1
- publishConfig added to all packages (Gitea registry, public access)
- files field added to all packages (ship only dist/)
- @mosaic/forge includes pipeline/ assets in published package
Meta package (@mosaic/mosaic):
- Now depends on @mosaic/forge, @mosaic/macp, @mosaic/prdy,
@mosaic/quality-rails, @mosaic/types
- npm install @mosaic/mosaic pulls in the standalone framework
Build fixes:
- Fix forge and macp tsconfig rootDir: '.' -> 'src' so dist/index.js
resolves correctly (was dist/src/index.js)
- Exclude __tests__ and vitest.config from build includes
- Clean stale build artifacts from old rootDir config
Required Woodpecker secret:
woodpecker secret add mosaic/mosaic-stack \
--name gitea_npm_token --value '<token>' \
--event push,manual,tag
Each step was re-running pnpm install independently, and all quality
steps (typecheck, lint, format, test) ran in parallel. On merge commits
with more accumulated code this pushed the CI runner over its memory
limit (exit code 254 = OOM kill).
Fix:
- install once, share node_modules via Woodpecker workspace volume
- sequential execution: install → typecheck → lint → format → test → build
- corepack enable in each step (fresh container) but no redundant install