Preventing CI failures
This guide explains the validation workflow and tools designed to catch errors early and prevent CI failures.
Overview
AlignTrue uses a multi-layered validation approach:
- Pre-refactor validation - Run before large changes to ensure clean baseline
- Pre-commit hook - Incremental checks on every commit (fast, focused)
- CI validation - Full workspace validation on push (comprehensive)
Pre-refactor validation
Use before large refactors, type changes, or cross-package edits.
pnpm pre-refactorWhat it does:
- Type checks entire workspace (~30-60s)
- Lints entire workspace
- Ensures clean baseline before starting work
When to use:
- Before refactoring 3+ files
- Before changing shared types or interfaces
- Before cross-package changes
- When you see repeated CI failures
Pre-commit hook (automatic)
Runs automatically on every git commit. Optimized for speed with incremental checks.
Flow:
- Format staged files with Prettier (~5s)
- Validate protected repo files - Prevent direct edits to auto-generated files
- Quick typecheck changed packages only (~5-15s) ← Fails fast
- Build changed packages (~15-30s)
- Full typecheck changed packages (~10-20s)
Total time: 30-60s for typical commits (vs 2+ min previously)
Key improvements:
- Catches type errors BEFORE build (saves time)
- Only checks/builds changed packages (faster)
- Shows clear error messages with fix suggestions
- Suggests
pnpm pre-refactorfor large changes - Prevents direct edits to auto-generated files (new)
Protected repository files
The following files are auto-generated from documentation source and cannot be directly edited:
README.md(generated fromapps/docs/content/index.mdx)CONTRIBUTING.md(generated fromapps/docs/content/05-contributing/creating-packs.md)DEVELOPMENT.md(generated fromapps/docs/content/07-development/*)
Why: AlignTrue practices what it preaches - documentation is the IR (Intermediate Representation), and generated files are the exports. This enforces the docs-first architecture.
Correct workflow:
- Edit the canonical source in
apps/docs/content/ - Run
pnpm generate:repo-filesto regenerate root files - Commit both the doc changes AND the regenerated files
If you accidentally try to directly edit a protected file:
❌ Protected files were directly edited
📝 These files are generated from docs content:
README.md
CONTRIBUTING.md
DEVELOPMENT.md
🔄 Correct workflow:
1. Edit source files in apps/docs/content/
2. Run: pnpm generate:repo-files
3. Commit both docs changes AND generated filesTo fix: Follow the workflow above and retry your commit.
Bypassing the hook
Only use --no-verify when absolutely necessary (e.g., emergency hotfix, known CI issue):
git commit --no-verify -m "fix: Emergency hotfix"CI validation (automatic)
Runs on every push to main or develop. Comprehensive validation of entire workspace.
What CI checks:
- Lockfile sync validation
- Full workspace build
- Full workspace typecheck
- All tests (unit + integration)
- Conformance testkit
- Golden repository validation
Time: 3-5 minutes
Common type error patterns
1. Import path errors
Problem: Wrong import path or missing type export
// ❌ Wrong
import { DriftDetectionResult } from "@aligntrue/core/team/drift.js";
// ✅ Correct
import { DriftResult } from "@aligntrue/core/team/drift.js";Fix: Check the actual exports in the source file
2. Duplicate imports
Problem: Same type imported from multiple locations
// ❌ Wrong
import { AlignRule } from "@aligntrue/core";
import { AlignRule } from "@aligntrue/schema";
// ✅ Correct
import { AlignRule } from "@aligntrue/schema";Fix: Import types from their canonical source (usually @aligntrue/schema)
3. Type narrowing issues
Problem: TypeScript can’t infer type after conditional
// ❌ Wrong
if (!acc[item.category]) acc[item.category] = [];
acc[item.category].push(item); // Error: possibly undefined
// ✅ Correct
if (!acc[item.category]) acc[item.category] = [];
acc[item.category]!.push(item); // Non-null assertionFix: Use non-null assertion (!) or type guards
4. exactOptionalPropertyTypes issues
Problem: Optional property can’t be explicitly set to undefined
// ❌ Wrong
type Result = {
summary?: string;
};
// ✅ Correct
type Result = {
summary?: string | undefined;
};Fix: Explicitly allow undefined in optional properties
Import path reference
Common type locations:
-
Schema types:
@aligntrue/schemaAlignRule,AlignPack,validateAlignSchema,validateRuleId
-
Core types:
@aligntrue/coreAlignTrueConfig,SyncEngine,BackupManager
-
Team types:
@aligntrue/core/team/drift.jsDriftResult,DriftFinding,DriftCategory
-
Exporter types:
@aligntrue/exportersExporterRegistry,ExportResult
-
Source types:
@aligntrue/sourcesGitSourceConfig,CatalogSourceConfig
Troubleshooting
Next.js dev server fails with “Cannot find module” errors
Symptom: Dev server crashes with errors like:
Error: Cannot find module './vendor-chunks/nextra@4.6.0...'
Cannot find module '@aligntrue/ui'Cause: Next.js doesn’t transpile workspace packages by default. The @aligntrue/ui package exports TypeScript source directly (no build step), so Next.js needs to be configured to transpile it.
Fix:
- Check your Next.js config has
transpilePackages:
// apps/web/next.config.ts
const nextConfig: NextConfig = {
transpilePackages: ["@aligntrue/ui"],
// ... rest of config
};// apps/docs/next.config.mjs
export default withNextra({
transpilePackages: ["@aligntrue/ui"],
// ... rest of config
});- Clean stale build caches:
rm -rf apps/web/.next apps/docs/.next- Restart dev servers:
pnpm dev:web # or pnpm dev:docsPrevention:
The CI now validates transpilePackages config matches workspace dependencies:
pnpm validate:transpile-packagesThis runs automatically in CI to catch config drift. If you add a new workspace package that exports TypeScript source, add it to transpilePackages in both Next.js configs.
Pre-commit hook is slow
Cause: Checking too many packages or full workspace
Fix: The optimized hook only checks changed packages. If still slow:
- Check if you have uncommitted changes in many packages
- Run
pnpm pre-refactorfirst to catch issues early - Commit packages separately if working on multiple
Type errors only appear in CI
Cause: Local build is stale or using cached types
Fix:
# Clean and rebuild
pnpm clean
pnpm build
# Then run typecheck
pnpm typecheckPre-commit hook fails but types seem fine
Cause: Hook uses stricter checks than your IDE
Fix:
- Run
pnpm typechecklocally to see all errors - Check that your IDE is using workspace TypeScript version
- Ensure
tsconfig.jsonhasstrict: true
Best practices
- Run
pnpm pre-refactorbefore large changes - Catches issues before you start - Commit frequently - Smaller commits = faster pre-commit checks
- Fix type errors immediately - Don’t let them accumulate
- Use the right import paths - Check source files for canonical exports
- Test locally before pushing - Run
pnpm typecheck && pnpm test