Skip to content

ADR-0009: CI Quality Gates

Date: 2026-07-28 Status: Accepted

Context

The monorepo has 3 apps and 4 packages. Pre-merge validation needs to catch type errors, lint violations, and regressions before they reach production.

Current state:

  • simple-git-hooks: pre-commit runs lint-staged, pre-push runs pnpm types:check
  • turbo.json has test task but only @walnut/server has vitest configured
  • @walnut/utils, @walnut/contract, @walnut/client have vitest config but no tests yet
  • No CI workflow running tests on push/PR

Decision

Three-tier quality gate:

GateWhenWhatBlocks
Pre-commitgit commitlint-staged (ESLint auto-fix on staged files)Commit
Pre-pushgit pushpnpm types:check (all packages)Push
CIPush to main / PRpnpm types:check + pnpm lint + pnpm testMerge

Test requirements by package:

PackageTest requirement
@walnut/utilsRequired — pure functions, easy to test
@walnut/contractRequired — snapshot tests for constants, no-duplicate-code validation
@walnut/clientEventually — complex browser/Vue code, needs jsdom setup
@walnut/axiosEventually — adapter tests need mock server
@walnut/adminEventually — complex SPA, needs component/E2E tests
@walnut/serverExisting — vitest + playwright already configured

turbo.json test task: dependsOn: ["build"] ensures the current package is built before its tests run. build itself has dependsOn: ["^build"], so upstream dependencies are transitively satisfied. Vitest uses esbuild for test compilation (not the CJS build output), so ["build"] is the correct dependency chain per industry standard (see docs/reference/04-testing-strategy.md).

Consequences

  • Pre-push remains fast (types only, no test execution)
  • CI catches test failures without blocking local development flow
  • Shared packages (utils, contract) get test coverage first — highest blast radius
  • turbo test runs affected packages only (via --filter=[HEAD^1] or similar)

基于 MIT 许可发布