Files
nextcraft/.pre-commit-config.yaml
T
CIAgent 1a88ab3199
Release / release (push) Successful in 3m45s
CI / python (push) Successful in 1m52s
CI / node (push) Successful in 1m0s
merge: milestone/v0.8-ship-anywhere -> main (v0.8 complete — Ship Anywhere)
The v0.8 milestone: installable on any Debian-based server via docker
(Gitea registry image, honest sandbox degrade), deb (amd64+arm64,
advisory postinst), and arch-aware binary — with release consistency
enforced by pre-commit hooks + Gitea Actions (3-runner fleet on CT 113,
machine-made releases with the full 8-asset matrix + registry image), the
CLI carrying the full suite (guide, channel-aware doctor), and the admin
runbook (deploy/README.md, evidence-backed recipes).

---ci---
phase: 6
milestone: v0.8
status: complete
requirements:
  covered: [REQ-8-001, REQ-8-002, REQ-8-003, REQ-8-004, REQ-8-005]
  partial: []
---/ci---
2026-09-29 16:04:40 +00:00

85 lines
3.8 KiB
YAML

# Pre-commit hooks (D-070) — local hygiene mirroring the CI lanes.
#
# Design contract (G-209): every hook is LOCAL-ONLY (no network at hook
# time — the mirror-style hooks below are fetched once at `pre-commit
# install`/`pre-commit run` time from github.com, which this LAN reaches;
# the language:system hooks run zero network). Hooks FAIL LOUD when the
# toolchain is missing (D-070: a contributor without the toolbox gets an
# explicit pointer, not a silent skip) — the no-toolbox escape is
# `git commit --no-verify` (or `SKIP=...`), documented in README.md with
# the loud note that CI still gates every push.
#
# Scope discipline mirrors .gitea/workflows/ci.yaml: ruff only touches
# ai-service python; eslint/tsc only touch the TS workspaces; hygiene is
# repo-wide.
repos:
# ---- basic hygiene (repo-wide, zero toolchain required)
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
- id: check-merge-conflict
- id: check-added-large-files
# ---- ruff (ai-service python, D-063 lane parity)
# Runs the venv-relative binary exactly like apps/ai-service/scripts/lint.sh
# (venv is the repo's authority for the python toolchain). FAILS LOUD with
# a bootstrap hint if the venv is missing — never a silent skip.
- repo: local
hooks:
- id: ruff
name: ruff check (ai-service)
entry: apps/ai-service/scripts/lint.sh
language: system
types: [python]
files: ^apps/ai-service/
pass_filenames: false
# ---- eslint (TS workspaces, ONE root flat config at eslint.config.mjs)
# Each workspace's `lint` script is `eslint .` resolving that config
# upward, so a single root invocation is exact parity with the node
# lane's per-workspace runs. `pnpm` resolves via PATH or corepack
# (same discovery as nextcraft doctor); FAILS LOUD if neither exists.
- id: eslint
name: eslint (TS workspaces)
entry: bash -c 'PNPM="$(command -v pnpm || echo "corepack pnpm")"; $PNPM exec eslint apps/web apps/cli packages/ui packages/types packages/mock-data'
language: system
files: ^(apps/web|apps/cli|packages/ui|packages/types|packages/mock-data)/.*\.(ts|tsx|mjs|cjs)$
pass_filenames: false
# ---- tsc --noEmit per TS workspace (node-lane parity: pnpm --filter
# over the same five workspaces; the tsconfig graph stays per-project)
# (the shared PCMD discovery is repeated per hook because pre-commit
# hooks run isolated entries)
- id: tsc-web
name: tsc --noEmit (web)
entry: bash -c 'PNPM="$(command -v pnpm || echo "corepack pnpm")"; $PNPM --filter web typecheck'
language: system
files: ^apps/web/.*\.tsx?$
pass_filenames: false
- id: tsc-cli
name: tsc --noEmit (cli)
entry: bash -c 'PNPM="$(command -v pnpm || echo "corepack pnpm")"; $PNPM --filter @nextcraft/cli typecheck'
language: system
files: ^apps/cli/.*\.tsx?$
pass_filenames: false
- id: tsc-ui
name: tsc --noEmit (ui)
entry: bash -c 'PNPM="$(command -v pnpm || echo "corepack pnpm")"; $PNPM --filter @nextcraft/ui typecheck'
language: system
files: ^packages/ui/.*\.tsx?$
pass_filenames: false
- id: tsc-types
name: tsc --noEmit (types)
entry: bash -c 'PNPM="$(command -v pnpm || echo "corepack pnpm")"; $PNPM --filter @nextcraft/types typecheck'
language: system
files: ^packages/types/.*\.tsx?$
pass_filenames: false
- id: tsc-mock-data
name: tsc --noEmit (mock-data)
entry: bash -c 'PNPM="$(command -v pnpm || echo "corepack pnpm")"; $PNPM --filter @nextcraft/mock-data typecheck'
language: system
files: ^packages/mock-data/.*\.tsx?$
pass_filenames: false