6.5 KiB
6.5 KiB
Monorepo Governance
Last Updated: 2025-01-27 Purpose: Guidelines for managing monorepositories in the workspace
Overview
This document establishes governance guidelines for creating, managing, and maintaining monorepositories in the workspace.
Decision Criteria
When to Create a Monorepo
Create a monorepo when you have:
- ✅ Multiple Related Projects: Projects that share code, dependencies, or infrastructure
- ✅ Shared Code Dependencies: Common utilities, types, or libraries used across projects
- ✅ Coordinated Releases: Projects that need to be released together
- ✅ Common Infrastructure: Shared infrastructure, tooling, or configuration
- ✅ Unified Development Workflow: Team working across multiple related projects
Do NOT create a monorepo for:
- ❌ Unrelated projects with no shared code
- ❌ Projects with independent release cycles
- ❌ Projects with different technology stacks (unless using workspaces)
- ❌ Projects that will be open-sourced independently
Monorepo Structure
Standard Structure
monorepo-name/
├── .gitmodules # Git submodules (if using submodules)
├── packages/ # Shared packages
│ ├── shared/ # Common utilities
│ ├── types/ # TypeScript types
│ └── config/ # Configuration
├── apps/ # Applications
│ └── [app-name]/
├── tools/ # Development tools
│ └── [tool-name]/
├── docs/ # Monorepo documentation
├── infrastructure/ # Infrastructure as Code
├── scripts/ # Monorepo scripts
├── package.json # Root package.json
├── pnpm-workspace.yaml # pnpm workspace config
└── turbo.json # Turborepo config
Submodules vs Packages
Use Git Submodules When:
- ✅ External repositories need to be included
- ✅ Independent versioning is required
- ✅ Projects are maintained separately
- ✅ External contributors need access to individual repos
Use Packages (Workspaces) When:
- ✅ Internal code that should be versioned together
- ✅ Unified versioning and releases
- ✅ Shared code that changes frequently
- ✅ Simplified dependency management
Hybrid Approach
- Use submodules for external/existing projects
- Use packages for new shared code
- Migrate from submodules to packages over time
Versioning Strategy
Option 1: Independent Versioning
- Each package/submodule has its own version
- Useful for submodules
- Allows independent releases
Option 2: Unified Versioning
- Single version for entire monorepo
- All packages versioned together
- Easier for coordinated releases
Recommendation: Start with independent, move to unified if needed.
Package Manager & Tooling
Standard Stack
- Package Manager: pnpm workspaces (recommended) or npm/yarn
- Build Tool: Turborepo (recommended) or Nx
- Testing: Vitest (TS/JS), Foundry (Solidity)
- Linting: ESLint + Prettier
Configuration Files
pnpm-workspace.yaml- Workspace configurationturbo.json- Turborepo pipeline configurationpackage.json- Root package.json with workspace scripts
Release Process
Release Workflow
- Plan: Identify packages to release
- Version: Update version numbers
- Test: Run all tests
- Build: Build all packages
- Release: Publish packages
- Tag: Create git tags
- Document: Update changelogs
Release Frequency
- Major Releases: Quarterly or as needed
- Minor Releases: Monthly or as needed
- Patch Releases: As needed for bug fixes
Code Sharing Guidelines
Shared Packages
- Create packages for code used by 2+ projects
- Keep packages focused and single-purpose
- Document package APIs
- Version packages independently (if using independent versioning)
Package Dependencies
- Use workspace protocol (
workspace:*) for internal dependencies - Hoist common dependencies to root
- Document dependency graph
- Avoid circular dependencies
CI/CD Guidelines
Pipeline Stages
- Lint & Format: Code quality checks
- Type Check: TypeScript/Solidity type checking
- Test: Unit and integration tests
- Build: Compile and build artifacts
- Security Scan: Dependency and code scanning
- Deploy: Deployment to environments
Caching Strategy
- Use Turborepo caching for builds
- Cache test results
- Cache dependency installation
Documentation Requirements
Monorepo-Level Documentation
- README.md with overview
- Architecture documentation
- Development setup guide
- Contribution guidelines
- Release process documentation
Package-Level Documentation
- Each package should have README.md
- API documentation
- Usage examples
- Changelog
Best Practices
Development Workflow
- Create feature branch
- Work on affected packages
- Run tests for all packages
- Update documentation
- Submit PR
Dependency Management
- Add dependencies at package level when possible
- Hoist common dependencies to root
- Keep dependencies up-to-date
- Audit dependencies regularly
Testing
- Test affected packages
- Run integration tests
- Check test coverage
- Ensure all tests pass before merge
Code Quality
- Follow code style guidelines
- Use pre-commit hooks
- Review code changes
- Maintain test coverage
Migration Strategy
Migrating Existing Projects
- Create monorepo structure
- Add projects as submodules initially
- Extract shared code to packages
- Migrate projects to packages (optional)
- Update documentation
Adding New Projects
- Evaluate if project belongs in existing monorepo
- Create new monorepo if needed
- Follow standard structure
- Update documentation
Troubleshooting
Common Issues
Issue: Build failures
- Solution: Check dependency graph, ensure all dependencies are installed
Issue: Test failures
- Solution: Run tests in affected packages, check for dependency issues
Issue: Version conflicts
- Solution: Use workspace protocol, hoist common dependencies
Issue: Circular dependencies
- Solution: Refactor to break circular dependency, use dependency injection
Review and Updates
This governance document should be reviewed:
- Quarterly
- When adding new monorepos
- When changing monorepo structure
- Based on team feedback
Last Updated: 2025-01-27 Next Review: Q2 2025