ci: cache node_modules + run fast gates first; enable lint-staged hook
CI (.gitea/workflows/ci.yml): - Cache node_modules keyed on package-lock + .node-version (actions/cache restore/save). An unchanged lockfile now skips `npm ci` (extraction + postinstall folds patch) and just restores the tree. Save runs only on a cache miss and only when install succeeded (`success()`), so a failed `npm ci` can't poison the cache. setup-node's existing `cache: npm` still warms the download cache on the miss path. - Run prettier/eslint/typecheck/tests BEFORE the ~minutes-long build so a format/lint/type/test error fails in seconds instead of after the build. DX (.husky/pre-commit): - Enable the pre-commit hook (`npx lint-staged`). husky + lint-staged were already installed with a config (eslint + `prettier --write` on staged files), just commented out — so formatting kept reaching CI. It's now auto-applied on commit. (typecheck left out of the hook — too slow per commit.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+45
-25
@@ -32,7 +32,21 @@ jobs:
|
|||||||
node-version-file: '.node-version'
|
node-version-file: '.node-version'
|
||||||
cache: npm
|
cache: npm
|
||||||
|
|
||||||
|
# Cache the installed tree keyed on the lockfile + Node version. On a hit
|
||||||
|
# (lockfile unchanged) `npm ci` — extraction + the postinstall folds patch —
|
||||||
|
# is skipped entirely and node_modules is just restored (the patch is baked
|
||||||
|
# into the cached tree). setup-node's `cache: npm` still warms the download
|
||||||
|
# cache for the miss path. Save runs only on a miss AND only if install
|
||||||
|
# succeeded (`success()`), so a failed `npm ci` can never poison the cache.
|
||||||
|
- name: Restore node_modules
|
||||||
|
id: node-modules
|
||||||
|
uses: actions/cache/restore@v4
|
||||||
|
with:
|
||||||
|
path: node_modules
|
||||||
|
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json', '.node-version') }}
|
||||||
|
|
||||||
- name: Install dependencies
|
- name: Install dependencies
|
||||||
|
if: steps.node-modules.outputs.cache-hit != 'true'
|
||||||
# Harden against transient registry network failures (ECONNRESET etc.):
|
# Harden against transient registry network failures (ECONNRESET etc.):
|
||||||
# raise npm's built-in fetch retries/timeouts and retry `npm ci` up to
|
# raise npm's built-in fetch retries/timeouts and retry `npm ci` up to
|
||||||
# 3 times with backoff before failing the build.
|
# 3 times with backoff before failing the build.
|
||||||
@@ -52,37 +66,43 @@ jobs:
|
|||||||
sleep $((attempt * 15))
|
sleep $((attempt * 15))
|
||||||
done
|
done
|
||||||
|
|
||||||
# ── Critical gate — if this fails, nothing deploys ──────────────────
|
- name: Save node_modules
|
||||||
|
if: steps.node-modules.outputs.cache-hit != 'true' && success()
|
||||||
|
uses: actions/cache/save@v4
|
||||||
|
with:
|
||||||
|
path: node_modules
|
||||||
|
key: node-modules-${{ runner.os }}-${{ hashFiles('package-lock.json', '.node-version') }}
|
||||||
|
|
||||||
|
# ── Quality gates run BEFORE the slow build so a format/lint/type/test
|
||||||
|
# error fails in seconds instead of after the ~minutes-long build. All are
|
||||||
|
# hard gates — any failure fails the job and blocks the deploy. The tree is
|
||||||
|
# held clean (prettier formatted, eslint 0 errors, typecheck 0), so these
|
||||||
|
# gate real regressions. NOTE: the lotus-build.sh upstream-merge path can
|
||||||
|
# deploy without CI; a later normal push surfaces any introduced issue here
|
||||||
|
# — fix forward (or briefly re-soften a gate) rather than deploy broken.
|
||||||
|
# eslint gates on errors only (existing no-explicit-any warnings stay
|
||||||
|
# informational — check:eslint has no --max-warnings).
|
||||||
|
- name: Prettier
|
||||||
|
run: npm run check:prettier
|
||||||
|
|
||||||
|
- name: ESLint
|
||||||
|
run: npm run check:eslint
|
||||||
|
|
||||||
|
- name: TypeScript
|
||||||
|
run: npm run typecheck
|
||||||
|
|
||||||
|
# Deterministic pure-logic tests on Node's built-in runner via tsx (no
|
||||||
|
# vitest — Vite 8 is ahead of vitest's range). A failure blocks the deploy.
|
||||||
|
- name: Unit tests
|
||||||
|
run: npm test
|
||||||
|
|
||||||
|
# ── Critical gate — if this fails, nothing deploys. Produces dist/. ──
|
||||||
- name: Build
|
- name: Build
|
||||||
run: npm run build
|
run: npm run build
|
||||||
env:
|
env:
|
||||||
NODE_OPTIONS: '--max_old_space_size=4096'
|
NODE_OPTIONS: '--max_old_space_size=4096'
|
||||||
VITE_APP_VERSION: ${{ github.sha }}
|
VITE_APP_VERSION: ${{ github.sha }}
|
||||||
|
|
||||||
# Unit tests are a hard gate too — deterministic pure-logic tests on Node's
|
|
||||||
# built-in runner via tsx (no vitest — Vite 8 is ahead of vitest's range).
|
|
||||||
# A failure blocks the deploy.
|
|
||||||
- name: Unit tests
|
|
||||||
run: npm test
|
|
||||||
|
|
||||||
# ── Quality gates (hard — a failure fails the job and blocks deploy) ──
|
|
||||||
# The tree is held clean (typecheck 0, eslint 0 errors, prettier
|
|
||||||
# formatted), so these gate real regressions instead of relying on local
|
|
||||||
# runs. NOTE: an upstream-stable merge (the lotus-build.sh path) could
|
|
||||||
# introduce upstream type/lint/format issues; that path deploys without
|
|
||||||
# CI, but a subsequent normal push would surface the failure here — fix
|
|
||||||
# forward (or briefly re-soften a gate) rather than let it deploy broken.
|
|
||||||
# eslint gates on errors only (existing `no-explicit-any` warnings stay
|
|
||||||
# informational — `check:eslint` has no --max-warnings).
|
|
||||||
- name: TypeScript
|
|
||||||
run: npm run typecheck
|
|
||||||
|
|
||||||
- name: ESLint
|
|
||||||
run: npm run check:eslint
|
|
||||||
|
|
||||||
- name: Prettier
|
|
||||||
run: npm run check:prettier
|
|
||||||
|
|
||||||
# ── Security (informational — findings shouldn't block a deploy) ─────
|
# ── Security (informational — findings shouldn't block a deploy) ─────
|
||||||
- name: Audit (high/critical)
|
- name: Audit (high/critical)
|
||||||
run: npm audit --audit-level=high --omit=dev
|
run: npm audit --audit-level=high --omit=dev
|
||||||
|
|||||||
+1
-3
@@ -1,3 +1 @@
|
|||||||
# These are commented until we enable lint and typecheck
|
npx lint-staged
|
||||||
# npx tsc -p tsconfig.json --noEmit
|
|
||||||
# npx lint-staged
|
|
||||||
|
|||||||
Reference in New Issue
Block a user