diff --git a/.github/CODEOWNERS.example b/.github/CODEOWNERS.example new file mode 100644 index 0000000..2c52f3d --- /dev/null +++ b/.github/CODEOWNERS.example @@ -0,0 +1,128 @@ +# CODEOWNERS.example +# +# This is a template for the CODEOWNERS file that defines code ownership for the UI Kit repository. +# To activate this file, rename it to "CODEOWNERS" and create the GitHub teams referenced below. +# +# Code owners are automatically requested for review when someone opens a pull request that modifies code that they own. +# +# More info: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners +# +# NOTE: The GitHub teams referenced in this file (@ui-kit-maintainers, @devops-team, etc.) +# need to be created in the GitHub organization before this file can be activated. + +# Global Owners +# These users are the default owners for everything in the repo unless a later match takes precedence. +* @ui-kit-maintainers + +# Root Configuration Files +# Critical configuration files that affect the entire project +/.github/ @ui-kit-maintainers @devops-team +/package.json @ui-kit-maintainers +/pnpm-lock.yaml @ui-kit-maintainers +/pnpm-workspace.yaml @ui-kit-maintainers +/tsconfig*.json @ui-kit-maintainers +/vite.config.ts @ui-kit-maintainers +/.eslintrc.cjs @ui-kit-maintainers +/.prettierrc @ui-kit-maintainers +/tailwind.config.js @ui-kit-maintainers + +# DevContainer and Docker +/.devcontainer/ @devops-team +/Dockerfile* @devops-team +/docker-compose*.yml @devops-team + +# CI/CD and Automation +/.github/workflows/ @devops-team @ui-kit-maintainers +/.github/actions/ @devops-team +/.changeset/ @ui-kit-maintainers +/scripts/ @devops-team @ui-kit-maintainers + +# Documentation +/README.md @docs-team @ui-kit-maintainers +/CONTRIBUTING.md @docs-team @ui-kit-maintainers +/CHANGELOG.md @docs-team @ui-kit-maintainers +/docs/ @docs-team +/.github/pull_request_template.md @docs-team @ui-kit-maintainers +/.github/CODEOWNERS @ui-kit-maintainers + +# UI Kit Package +/packages/ui-kit/ @ui-kit-maintainers + +# Core Components +/packages/ui-kit/src/components/primitives/ @component-team @ui-kit-maintainers +/packages/ui-kit/src/components/layout/ @layout-team @ui-kit-maintainers +/packages/ui-kit/src/components/form/ @form-team @ui-kit-maintainers + +# Providers and Context +/packages/ui-kit/src/providers/ @architecture-team @ui-kit-maintainers + +# Utilities and Hooks +/packages/ui-kit/src/utils/ @utils-team @ui-kit-maintainers +/packages/ui-kit/src/hooks/ @hooks-team @ui-kit-maintainers + +# Styling and Theming +/packages/ui-kit/src/styles/ @design-system-team @ui-kit-maintainers +/packages/ui-kit/src/theme/ @design-system-team @ui-kit-maintainers +/packages/ui-kit/src/tokens/ @design-system-team @ui-kit-maintainers + +# Testing Infrastructure +/packages/ui-kit/src/**/*.test.* @testing-team @ui-kit-maintainers +/packages/ui-kit/src/**/*.spec.* @testing-team @ui-kit-maintainers +/packages/ui-kit/cypress/ @testing-team @ui-kit-maintainers +/packages/ui-kit/playwright/ @testing-team @ui-kit-maintainers +/packages/ui-kit/vitest.config.ts @testing-team @ui-kit-maintainers +/packages/ui-kit/cypress.config.ts @testing-team @ui-kit-maintainers +/packages/ui-kit/playwright.config.ts @testing-team @ui-kit-maintainers + +# Storybook +/packages/ui-kit/.storybook/ @storybook-team @ui-kit-maintainers +/packages/ui-kit/src/**/*.stories.* @storybook-team @component-team + +# Build and Bundle Configuration +/packages/ui-kit/vite.config.ts @build-team @ui-kit-maintainers +/packages/ui-kit/tsconfig*.json @build-team @ui-kit-maintainers +/packages/ui-kit/package.json @ui-kit-maintainers + +# Security and Dependencies +/packages/ui-kit/pnpm-lock.yaml @security-team @ui-kit-maintainers +/.nvmrc @devops-team +/.node-version @devops-team + +# Specific Component Ownership Examples +# Uncomment and modify these as teams are assigned to specific components + +# /packages/ui-kit/src/components/primitives/Button/ @button-specialist +# /packages/ui-kit/src/components/primitives/Input/ @form-specialist +# /packages/ui-kit/src/components/layout/Grid/ @layout-specialist +# /packages/ui-kit/src/components/form/DataTable/ @datatable-specialist + +# Performance and Bundle Size +/packages/ui-kit/size-limit.config.js @performance-team @ui-kit-maintainers + +# Error Handling and Monitoring +/packages/ui-kit/src/providers/ErrorBoundary/ @monitoring-team @ui-kit-maintainers +/packages/ui-kit/src/utils/logger/ @monitoring-team @ui-kit-maintainers + +# Accessibility +/packages/ui-kit/src/**/*a11y* @accessibility-team @ui-kit-maintainers +/packages/ui-kit/src/**/*accessibility* @accessibility-team @ui-kit-maintainers + +# Team Definitions (GitHub teams that should be created) +# +# @ui-kit-maintainers - Core maintainers with full repository access +# @devops-team - DevOps and infrastructure specialists +# @docs-team - Documentation specialists +# @component-team - UI component specialists +# @layout-team - Layout and responsive design specialists +# @form-team - Form component specialists +# @architecture-team - System architecture specialists +# @utils-team - Utility function specialists +# @hooks-team - React hooks specialists +# @design-system-team - Design system and theming specialists +# @testing-team - Testing infrastructure specialists +# @storybook-team - Storybook and documentation specialists +# @build-team - Build and bundling specialists +# @security-team - Security and dependency management specialists +# @performance-team - Performance and optimization specialists +# @monitoring-team - Error handling and monitoring specialists +# @accessibility-team - Accessibility specialists \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..439b513 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,258 @@ +## Description + +### Summary + + + +### Motivation and Context + + + + +### Type of Change + + + +- [ ] πŸ› Bug fix (non-breaking change which fixes an issue) +- [ ] ✨ New feature (non-breaking change which adds functionality) +- [ ] πŸ’₯ Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] πŸ“š Documentation update +- [ ] πŸ”§ Refactoring (no functional changes, no api changes) +- [ ] 🎨 Style changes (formatting, missing semi colons, etc; no code changes) +- [ ] πŸ§ͺ Test changes (adding missing tests, refactoring tests; no production code changes) +- [ ] πŸ”¨ Build/CI changes (changes to build process or CI configuration) + +## Changes Made + +### Components/Features Added or Modified + + + +- +- +- + +### Files Changed + + + +- +- +- + +## Testing + +### Test Coverage + + + +- [ ] Unit tests added/updated +- [ ] Integration tests added/updated +- [ ] Storybook stories added/updated +- [ ] Accessibility tests pass +- [ ] Visual regression tests pass +- [ ] Manual testing completed + +### Test Instructions + + + +1. +2. +3. + +### Screenshots/Videos + + + +## Bundle Size Impact + +### Size Analysis + + + +- [ ] Bundle size increase is within acceptable limits (< 10KB gzipped) +- [ ] No bundle size increase +- [ ] Bundle size decreased + +### Size Report + +``` + +``` + +## Breaking Changes + +### API Changes + + + +- [ ] No breaking changes +- [ ] Breaking changes documented below + +### Migration Guide + + + +### Deprecation Notices + + + +## Documentation + +### Documentation Updates + +- [ ] README updated (if needed) +- [ ] CONTRIBUTING.md updated (if needed) +- [ ] Storybook documentation updated +- [ ] TypeScript types documented +- [ ] Changelog entry added (via changeset) + +### Storybook + +- [ ] New stories added for new components +- [ ] Existing stories updated for modified components +- [ ] All stories render without errors +- [ ] Interactive examples work correctly + +## Accessibility + +### A11y Compliance + +- [ ] Components are keyboard navigable +- [ ] Proper ARIA labels and roles added +- [ ] Color contrast meets WCAG standards +- [ ] Screen reader testing completed +- [ ] axe-core tests pass + +### A11y Testing Results + + + +## Code Quality + +### Code Review Checklist + +- [ ] Code follows project style guidelines +- [ ] Self-review of code completed +- [ ] Code is well-commented, particularly in hard-to-understand areas +- [ ] No console.log statements left in production code +- [ ] No TODO comments without associated issues +- [ ] TypeScript types are properly defined +- [ ] Error handling is appropriate + +### Linting and Formatting + +- [ ] ESLint passes without errors +- [ ] Prettier formatting applied +- [ ] TypeScript compilation successful +- [ ] No new TypeScript errors introduced + +## Dependencies + +### Dependency Changes + +- [ ] No new dependencies added +- [ ] New dependencies justified and documented +- [ ] Dependencies updated to latest secure versions +- [ ] No unused dependencies + +### Security + +- [ ] No security vulnerabilities introduced +- [ ] Sensitive data properly handled +- [ ] Input validation implemented where needed + +## Deployment + +### Environment Impact + +- [ ] Changes work in development environment +- [ ] Changes work in production-like environment +- [ ] No environment-specific configurations needed + +### Rollback Plan + + + +## Related Issues + +### Closes + + + +- Closes # +- Fixes # +- Resolves # + +### Related + + + +- Related to # +- Depends on # +- Blocks # + +## Reviewer Notes + +### Focus Areas + + + +- +- +- + +### Questions for Reviewers + + + +- +- +- + +### Additional Context + + + +--- + +## Reviewer Checklist + +### Code Review + +- [ ] Code is readable and well-structured +- [ ] Logic is sound and efficient +- [ ] Error handling is appropriate +- [ ] Security considerations addressed +- [ ] Performance impact considered + +### Testing Review + +- [ ] Test coverage is adequate +- [ ] Tests are meaningful and test the right things +- [ ] Edge cases are covered +- [ ] Tests pass consistently + +### Documentation Review + +- [ ] Documentation is accurate and complete +- [ ] Examples are clear and helpful +- [ ] API documentation is up to date + +### Design Review + +- [ ] UI/UX follows design system guidelines +- [ ] Responsive design works correctly +- [ ] Accessibility requirements met +- [ ] Visual design is consistent + +### Final Approval + +- [ ] All automated checks pass +- [ ] Manual testing completed +- [ ] Ready for merge + +--- + +**Note for Reviewers**: Please ensure all checklist items are completed before approving. If any items are not applicable, mark them as complete and note why in your review comments. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..e93ad89 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,451 @@ +# Contributing to UI Kit + +Thank you for your interest in contributing to the UI Kit! This document provides guidelines and instructions for contributing to this project. + +## Table of Contents + +- [Getting Started](#getting-started) +- [Development Environment](#development-environment) +- [Development Workflow](#development-workflow) +- [Code Style and Standards](#code-style-and-standards) +- [Testing Requirements](#testing-requirements) +- [Pull Request Process](#pull-request-process) +- [Release Process](#release-process) +- [Issue Reporting](#issue-reporting) +- [Code of Conduct](#code-of-conduct) + +## Getting Started + +### Prerequisites + +- Node.js 20.x or later +- pnpm 8.x or later +- Git +- Docker (optional, for DevContainer) + +### Quick Setup + +1. **Fork and clone the repository** + + ```bash + git clone https://github.com/your-username/ui-kit.git + cd ui-kit + ``` + +2. **Install dependencies** + + ```bash + pnpm install + ``` + +3. **Start development** + ```bash + pnpm dev # Start Vite dev server + pnpm storybook # Start Storybook + ``` + +## Development Environment + +### Option 1: DevContainer (Recommended) + +The project includes a complete DevContainer setup for consistent development environments: + +1. Install [VS Code](https://code.visualstudio.com/) and the [Dev Containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) +2. Open the project in VS Code +3. When prompted, click "Reopen in Container" or use `Ctrl+Shift+P` β†’ "Dev Containers: Reopen in Container" +4. The container will build automatically with all dependencies and tools pre-configured + +See [.devcontainer/README.md](.devcontainer/README.md) for detailed DevContainer documentation. + +### Option 2: Local Setup + +If you prefer local development: + +1. **Install Node.js 20.x** using [nvm](https://github.com/nvm-sh/nvm) or [fnm](https://github.com/Schniz/fnm) +2. **Install pnpm**: `npm install -g pnpm@8` +3. **Install dependencies**: `pnpm install` +4. **Set up Git hooks**: `pnpm prepare` (runs automatically after install) + +### Available Scripts + +```bash +# Development +pnpm dev # Start Vite dev server +pnpm storybook # Start Storybook development server +pnpm build # Build the library +pnpm build-storybook # Build Storybook for production + +# Testing +pnpm test # Run unit tests with Vitest +pnpm test:coverage # Run tests with coverage report +pnpm test-storybook # Run Storybook interaction tests +pnpm test-storybook:ci # Run Storybook tests in CI mode +pnpm cy:open # Open Cypress for E2E testing +pnpm cy:run # Run Cypress tests headlessly +pnpm playwright:test # Run Playwright tests + +# Quality Assurance +pnpm lint # Run ESLint +pnpm lint:fix # Fix auto-fixable ESLint issues +pnpm type-check # Run TypeScript type checking +pnpm size-limit # Check bundle size limits + +# Utilities +pnpm tokens-check # Verify design tokens +pnpm theme-screenshots # Generate theme screenshots +``` + +## Development Workflow + +### Branch Strategy + +We follow GitFlow with these branch types: + +- `main` - Production-ready code +- `develop` - Integration branch for features +- `feature/*` - Feature development branches +- `release/*` - Release preparation branches +- `hotfix/*` - Critical bug fixes + +### Feature Development + +1. **Create a feature branch from `develop`** + + ```bash + git checkout develop + git pull origin develop + git checkout -b feature/your-feature-name + ``` + +2. **Make your changes following our coding standards** + +3. **Test your changes thoroughly** + + ```bash + pnpm test + pnpm lint + pnpm build + ``` + +4. **Commit using conventional commits** + + ```bash + git add . + git commit -m "feat: add new component feature" + ``` + +5. **Push and create a pull request** + ```bash + git push -u origin feature/your-feature-name + ``` + +### Commit Message Format + +We use [Conventional Commits](https://www.conventionalcommits.org/): + +``` +[optional scope]: + +[optional body] + +[optional footer(s)] +``` + +**Types:** + +- `feat`: New features +- `fix`: Bug fixes +- `docs`: Documentation changes +- `style`: Code style changes (formatting, etc.) +- `refactor`: Code refactoring +- `test`: Adding or updating tests +- `chore`: Maintenance tasks + +**Examples:** + +``` +feat(button): add loading state with spinner +fix(input): resolve accessibility issue with label association +docs: update contributing guidelines +test(datatable): add pagination tests +``` + +## Code Style and Standards + +### TypeScript + +- Use strict TypeScript configuration +- Prefer type aliases over interfaces for simple types +- Use generics appropriately +- Avoid `any` type (use `unknown` if necessary) +- Export types alongside components + +### React + +- Use functional components with hooks +- Prefer composition over inheritance +- Use proper prop types and default values +- Follow React hooks rules +- Clean up side effects in `useEffect` + +### Styling + +- Use Tailwind CSS classes within the UI kit only +- Follow DaisyUI theming conventions +- Use CSS custom properties for design tokens +- Avoid inline styles +- Use `@apply` sparingly in CSS files + +### File Organization + +``` +src/ +β”œβ”€β”€ components/ +β”‚ β”œβ”€β”€ primitives/ # Basic UI components +β”‚ β”œβ”€β”€ layout/ # Layout components +β”‚ └── form/ # Form-specific components +β”œβ”€β”€ hooks/ # Custom React hooks +β”œβ”€β”€ providers/ # Context providers +β”œβ”€β”€ utils/ # Utility functions +└── types/ # TypeScript type definitions +``` + +### Naming Conventions + +- **Components**: PascalCase (`Button`, `TextInput`) +- **Files**: PascalCase for components, camelCase for utilities +- **Props**: camelCase with descriptive names +- **CSS Classes**: Follow Tailwind/DaisyUI conventions +- **Test Files**: `*.test.tsx` or `*.spec.tsx` + +## Testing Requirements + +### Unit Tests + +- Write tests for all components using Vitest +- Aim for >90% code coverage +- Test component behavior, not implementation details +- Use React Testing Library best practices + +```typescript +// Example test structure +describe('Button', () => { + it('renders with correct text', () => { + render(); + expect(screen.getByRole('button')).toHaveTextContent('Click me'); + }); + + it('calls onClick handler when clicked', () => { + const handleClick = vi.fn(); + render(); + fireEvent.click(screen.getByRole('button')); + expect(handleClick).toHaveBeenCalledTimes(1); + }); +}); +``` + +### Storybook Stories + +- Create stories for all components +- Include all component variants and states +- Use Storybook controls for interactive props +- Write interaction tests for complex behaviors + +```typescript +// Example story structure +export default { + title: "Components/Button", + component: Button, + parameters: { + docs: { + description: { + component: "A versatile button component with multiple variants.", + }, + }, + }, +} as Meta; + +export const Default: Story = { + args: { + children: "Button", + }, +}; + +export const Loading: Story = { + args: { + children: "Loading...", + loading: true, + }, +}; +``` + +### Accessibility Testing + +- All components must pass axe-core accessibility tests +- Use semantic HTML elements +- Provide proper ARIA labels and descriptions +- Ensure keyboard navigation works correctly +- Test with screen readers when possible + +### Visual Testing + +- Playwright snapshots for layout components +- Cypress visual regression tests for themes +- Storybook visual testing for component variants + +## Pull Request Process + +### Before Submitting + +1. **Ensure all tests pass** + + ```bash + pnpm test + pnpm test-storybook + pnpm lint + ``` + +2. **Check bundle size impact** + + ```bash + pnpm build + pnpm size-limit + ``` + +3. **Update documentation if needed** + + - Component documentation in Storybook + - README updates for new features + - CHANGELOG entries for breaking changes + +4. **Rebase on latest develop** + ```bash + git fetch origin + git rebase origin/develop + ``` + +### PR Requirements + +- **Title**: Use conventional commit format +- **Description**: Use the provided PR template +- **Tests**: Include tests for new functionality +- **Documentation**: Update relevant documentation +- **Breaking Changes**: Clearly document any breaking changes +- **Size Impact**: Keep bundle size increases minimal + +### Review Process + +1. **Automated Checks**: All CI checks must pass +2. **Code Review**: At least one maintainer approval required +3. **Testing**: Manual testing of new features +4. **Documentation Review**: Ensure docs are accurate and complete + +### Merging + +- Use "Squash and merge" for feature branches +- Ensure commit message follows conventional format +- Delete feature branch after merging + +## Release Process + +### Versioning + +We use [Semantic Versioning](https://semver.org/): + +- **MAJOR**: Breaking changes +- **MINOR**: New features (backward compatible) +- **PATCH**: Bug fixes (backward compatible) + +### Changesets + +We use [Changesets](https://github.com/changesets/changesets) for version management: + +1. **Add changeset for your changes** + + ```bash + pnpm changeset + ``` + +2. **Follow the prompts to describe your changes** + +3. **Commit the changeset file** + ```bash + git add .changeset/ + git commit -m "chore: add changeset for feature" + ``` + +### Release Workflow + +1. Changesets bot creates release PR +2. Review and merge release PR +3. Automated release to npm and GitHub +4. Storybook deployment to GitHub Pages + +## Issue Reporting + +### Bug Reports + +When reporting bugs, please include: + +- **Environment**: OS, Node.js version, browser +- **Steps to reproduce**: Clear, numbered steps +- **Expected behavior**: What should happen +- **Actual behavior**: What actually happens +- **Screenshots**: If applicable +- **Code samples**: Minimal reproduction case + +### Feature Requests + +For feature requests, please include: + +- **Use case**: Why is this feature needed? +- **Proposed solution**: How should it work? +- **Alternatives**: Other solutions considered +- **Examples**: Similar implementations in other libraries + +### Security Issues + +For security vulnerabilities: + +- **Do not** create public issues +- Email security concerns to the maintainers +- Include detailed reproduction steps +- Allow time for fix before disclosure + +## Code of Conduct + +### Our Standards + +- **Be respectful**: Treat everyone with respect and kindness +- **Be inclusive**: Welcome people of all backgrounds and experience levels +- **Be collaborative**: Work together constructively +- **Be patient**: Help others learn and grow + +### Unacceptable Behavior + +- Harassment, discrimination, or offensive comments +- Personal attacks or trolling +- Spam or off-topic discussions +- Sharing private information without permission + +### Enforcement + +Violations of the code of conduct should be reported to the project maintainers. All reports will be reviewed and investigated promptly and fairly. + +## Getting Help + +- **Documentation**: Check the README and Storybook docs first +- **Issues**: Search existing issues before creating new ones +- **Discussions**: Use GitHub Discussions for questions and ideas +- **Discord**: Join our community Discord for real-time help + +## Recognition + +Contributors are recognized in: + +- CHANGELOG.md for significant contributions +- README.md contributors section +- GitHub contributor graphs +- Release notes for major features + +Thank you for contributing to the UI Kit! πŸŽ‰ diff --git a/README.md b/README.md index 0814058..c1d8932 100644 --- a/README.md +++ b/README.md @@ -55,3 +55,28 @@ pnpm build && pnpm run size-limit - **UMD Bundle**: 250 KB gzipped The CI pipeline automatically checks bundle sizes on every PR and will fail if the limits are exceeded. This helps prevent bundle bloat and maintains fast loading times for applications using the UI kit. + +## Contributing + +We welcome contributions to the UI Kit! Please read our [Contributing Guidelines](CONTRIBUTING.md) for detailed information about: + +- πŸš€ **Getting Started**: Development environment setup and quick start guide +- πŸ”§ **Development Workflow**: Branch strategy, commit conventions, and PR process +- πŸ“‹ **Code Standards**: TypeScript, React, and styling guidelines +- πŸ§ͺ **Testing**: Unit tests, Storybook stories, and accessibility requirements +- πŸ“š **Documentation**: How to document components and update guides + +### Quick Contributing Steps + +1. **Fork and clone** the repository +2. **Set up development environment** (DevContainer recommended) +3. **Create a feature branch** from `develop` +4. **Make your changes** following our coding standards +5. **Test thoroughly** with `pnpm test && pnpm lint` +6. **Submit a pull request** using our PR template + +For bug reports and feature requests, please use our [GitHub Issues](https://github.com/your-org/ui-kit/issues). + +### Code of Conduct + +This project follows a [Code of Conduct](CONTRIBUTING.md#code-of-conduct) to ensure a welcoming environment for all contributors. diff --git a/docs/project_plan.md b/docs/project_plan.md index 3e1cb85..90f9215 100644 --- a/docs/project_plan.md +++ b/docs/project_plan.md @@ -70,8 +70,8 @@ A pragmatic breakdown into **four one‑week sprints** plus a preparatory **Spri | --- | ------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ------ | | 4.1 | Implement CSP & DOMPurify wrapper in MarkdownEditor. | Security unit test feeds XSS payload; output sanitised. | βœ“ | | 4.2 | Add Sentry ErrorBoundary + tslog logger. | Fake error in story captured by mocked Sentry client in test. | βœ“ | -| 4.3 | Size‑limit CI check (< 250 KB gz for core bundle). | `npm run size-limit` passes. | PR | -| 4.4 | Prepare **CONTRIBUTING.md**, PR template, CODEOWNERS. | Presence verified by doc‑lint script. | | +| 4.3 | Size‑limit CI check (< 250 KB gz for core bundle). | `npm run size-limit` passes. | βœ“ | +| 4.4 | Prepare **CONTRIBUTING.md**, PR template, CODEOWNERS. | Presence verified by doc‑lint script. | PR | | 4.5 | Publish first `v0.1.0-beta` to GitHub Packages; deploy Storybook demo to Pages. | Tag `v0.1.0-beta` exists; npm info returns package; Pages URL accessible & shows build hash. | | --- diff --git a/docs/task-planning/task-4.3-size-limit-ci-check.md b/docs/task-planning/task-4.3-size-limit-ci-check.md deleted file mode 100644 index 9de2198..0000000 --- a/docs/task-planning/task-4.3-size-limit-ci-check.md +++ /dev/null @@ -1,30 +0,0 @@ -# Task 4.3: Size‑limit CI check (< 250 KB gz for core bundle) - -## Overview - -Implement bundle size monitoring to ensure the core UI kit bundle stays under 250 KB gzipped. This involves setting up size-limit tooling and CI integration to prevent bundle bloat. - -## Task Breakdown - -| Task Description | DoD (Definition of Done) | Status | -| ------------------------------------------------ | ---------------------------------------------------------------------------- | -------- | -| Install and configure size-limit package | Package installed with appropriate configuration for bundle size checking | Complete | -| Configure size-limit for core bundle measurement | Configuration targets the main bundle output and measures gzipped size | Complete | -| Set up size-limit CI integration | CI pipeline includes size-limit check that fails if bundle exceeds 250 KB gz | Complete | -| Add npm script for local size checking | `pnpm run size-limit` command available for local development | Complete | -| Verify current bundle size is under limit | Current build passes size-limit check with margin for growth | Complete | -| Document size-limit usage in README/docs | Documentation explains how to check bundle size and what the limits are | Complete | - -## Definition of Done - -- `npm run size-limit` passes -- CI pipeline includes size-limit check -- Bundle size is under 250 KB gzipped -- Documentation updated with size monitoring information - -## Technical Notes - -- Will use `size-limit` package for bundle analysis -- Need to configure for Vite build output -- Should measure the main entry point bundle -- Consider excluding dev dependencies and test files from measurement diff --git a/docs/task-planning/task-4.4-contributing-docs.md b/docs/task-planning/task-4.4-contributing-docs.md new file mode 100644 index 0000000..e6377c7 --- /dev/null +++ b/docs/task-planning/task-4.4-contributing-docs.md @@ -0,0 +1,47 @@ +# Task 4.4: Prepare CONTRIBUTING.md, PR template, CODEOWNERS + +## Overview + +Create comprehensive documentation and templates to guide contributors and establish project governance. This includes contribution guidelines, pull request templates, and code ownership definitions. + +## Task Breakdown + +| Task Description | DoD (Definition of Done) | Status | +| -------------------------------------------------------- | --------------------------------------------------------------------------------------------- | -------- | +| Create CONTRIBUTING.md with development guidelines | Comprehensive guide covering setup, development workflow, coding standards, and PR process | Complete | +| Add GitHub PR template with checklist | Template includes sections for description, testing, breaking changes, and reviewer checklist | Complete | +| Create CODEOWNERS file for code review assignments | File defines ownership patterns for different parts of the codebase (as .example template) | Complete | +| Add doc-lint script to verify presence of required files | Script checks for existence of CONTRIBUTING.md, PR template, and CODEOWNERS | Complete | +| Update README with links to contribution docs | README references CONTRIBUTING.md and development setup instructions | Complete | + +## Implementation Notes + +### CONTRIBUTING.md Structure + +- Development environment setup (DevContainer, local setup) +- Code style and linting rules +- Testing requirements +- PR submission process +- Release process +- Issue reporting guidelines + +### PR Template Requirements + +- Description template with sections for changes, motivation, testing +- Checklist for common requirements (tests, docs, breaking changes) +- Links to relevant issues +- Reviewer guidelines + +### CODEOWNERS Patterns + +- Core maintainers for root files and CI +- Component owners for specific UI components +- Documentation owners for docs and README files +- DevOps owners for Docker and deployment files + +### Doc-lint Script + +- Verify presence of required documentation files +- Check for basic structure/sections in CONTRIBUTING.md +- Validate CODEOWNERS syntax +- Integrate into CI pipeline diff --git a/packages/ui-kit/package.json b/packages/ui-kit/package.json index 482ff83..16833cc 100644 --- a/packages/ui-kit/package.json +++ b/packages/ui-kit/package.json @@ -37,7 +37,8 @@ "playwright:test": "playwright test", "playwright:update-snapshots": "playwright test --update-snapshots", "tokens-check": "node scripts/tokens-check.js", - "size-limit": "size-limit" + "size-limit": "size-limit", + "doc-lint": "node scripts/doc-lint.js" }, "dependencies": { "@hookform/resolvers": "^5.0.1", diff --git a/packages/ui-kit/scripts/doc-lint.js b/packages/ui-kit/scripts/doc-lint.js new file mode 100644 index 0000000..c792201 --- /dev/null +++ b/packages/ui-kit/scripts/doc-lint.js @@ -0,0 +1,295 @@ +#!/usr/bin/env node + +/** + * Documentation Linter + * + * This script verifies the presence and basic structure of required documentation files. + * It checks for CONTRIBUTING.md, PR template, and CODEOWNERS files. + */ + +/* eslint-env node */ +/* eslint-disable no-undef */ + +import { readFileSync, existsSync } from "fs"; +import { join, dirname } from "path"; +import { fileURLToPath } from "url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = dirname(__filename); + +// Get the workspace root (3 levels up from packages/ui-kit/scripts) +const workspaceRoot = join(__dirname, "../../.."); + +// Required files configuration +const requiredFiles = [ + { + path: "CONTRIBUTING.md", + name: "Contributing Guidelines", + requiredSections: [ + "Getting Started", + "Development Environment", + "Development Workflow", + "Code Style and Standards", + "Testing Requirements", + "Pull Request Process", + ], + }, + { + path: ".github/pull_request_template.md", + name: "Pull Request Template", + requiredSections: [ + "Description", + "Testing", + "Documentation", + "Code Quality", + ], + }, + { + path: ".github/CODEOWNERS.example", + name: "Code Owners Example", + requiredPatterns: [ + "* @", // Global ownership pattern + "/.github/", // GitHub directory ownership + "/packages/ui-kit/", // UI Kit package ownership + ], + }, +]; + +// Colors for console output +const colors = { + reset: "\x1b[0m", + red: "\x1b[31m", + green: "\x1b[32m", + yellow: "\x1b[33m", + blue: "\x1b[34m", + bold: "\x1b[1m", +}; + +function log(message, color = colors.reset) { + console.log(`${color}${message}${colors.reset}`); +} + +function logError(message) { + log(`❌ ${message}`, colors.red); +} + +function logSuccess(message) { + log(`βœ… ${message}`, colors.green); +} + +function logWarning(message) { + log(`⚠️ ${message}`, colors.yellow); +} + +function logInfo(message) { + log(`ℹ️ ${message}`, colors.blue); +} + +function checkFileExists(filePath, fileName) { + const fullPath = join(workspaceRoot, filePath); + + if (!existsSync(fullPath)) { + logError(`${fileName} not found at ${filePath}`); + return false; + } + + logSuccess(`${fileName} found at ${filePath}`); + return true; +} + +function checkFileContent( + filePath, + fileName, + requiredSections = [], + requiredPatterns = [], +) { + const fullPath = join(workspaceRoot, filePath); + + try { + const content = readFileSync(fullPath, "utf-8"); + + // Check for required sections (for markdown files) + if (requiredSections.length > 0) { + const missingSections = []; + + for (const section of requiredSections) { + // Look for section headers (# ## ### etc.) + const sectionRegex = new RegExp(`^#+\\s*${section}`, "mi"); + if (!sectionRegex.test(content)) { + missingSections.push(section); + } + } + + if (missingSections.length > 0) { + logWarning( + `${fileName} is missing sections: ${missingSections.join(", ")}`, + ); + return false; + } else { + logSuccess(`${fileName} contains all required sections`); + } + } + + // Check for required patterns (for CODEOWNERS) + if (requiredPatterns.length > 0) { + const missingPatterns = []; + + for (const pattern of requiredPatterns) { + if (!content.includes(pattern)) { + missingPatterns.push(pattern); + } + } + + if (missingPatterns.length > 0) { + logWarning( + `${fileName} is missing patterns: ${missingPatterns.join(", ")}`, + ); + return false; + } else { + logSuccess(`${fileName} contains all required patterns`); + } + } + + return true; + } catch (error) { + logError(`Error reading ${fileName}: ${error.message}`); + return false; + } +} + +function validateCodeownersFile(filePath) { + const fullPath = join(workspaceRoot, filePath); + + try { + const content = readFileSync(fullPath, "utf-8"); + const lines = content.split("\n"); + let hasErrors = false; + + for (let i = 0; i < lines.length; i++) { + const line = lines[i].trim(); + + // Skip empty lines and comments + if (!line || line.startsWith("#")) { + continue; + } + + // Basic validation: line should have at least a path pattern and an owner + const parts = line.split(/\s+/); + if (parts.length < 2) { + logWarning( + `CODEOWNERS line ${i + 1}: "${line}" appears to be malformed`, + ); + hasErrors = true; + continue; + } + + const [, ...owners] = parts; + + // Check if owners start with @ + const invalidOwners = owners.filter((owner) => !owner.startsWith("@")); + if (invalidOwners.length > 0) { + logWarning( + `CODEOWNERS line ${i + 1}: Invalid owners (should start with @): ${invalidOwners.join(", ")}`, + ); + hasErrors = true; + } + } + + if (!hasErrors) { + logSuccess("CODEOWNERS file syntax is valid"); + } + + return !hasErrors; + } catch (error) { + logError(`Error validating CODEOWNERS: ${error.message}`); + return false; + } +} + +function checkDocumentationCompleteness() { + logInfo("Checking documentation completeness..."); + + // Check if README mentions CONTRIBUTING.md + const readmePath = join(workspaceRoot, "README.md"); + if (existsSync(readmePath)) { + const readmeContent = readFileSync(readmePath, "utf-8"); + if ( + readmeContent.includes("CONTRIBUTING.md") || + readmeContent.toLowerCase().includes("contributing") + ) { + logSuccess("README.md references contributing guidelines"); + } else { + logWarning("README.md should reference CONTRIBUTING.md"); + } + } + + // Check if package.json has repository field + const packageJsonPath = join(workspaceRoot, "package.json"); + if (existsSync(packageJsonPath)) { + const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8")); + if (packageJson.repository) { + logSuccess("package.json has repository field"); + } else { + logWarning( + "package.json should have repository field for proper GitHub integration", + ); + } + } +} + +function main() { + log(`${colors.bold}πŸ” Documentation Linter${colors.reset}\n`); + + let allPassed = true; + + // Check each required file + for (const file of requiredFiles) { + log(`\n${colors.bold}Checking ${file.name}...${colors.reset}`); + + // Check if file exists + if (!checkFileExists(file.path, file.name)) { + allPassed = false; + continue; + } + + // Check file content + if (file.requiredSections || file.requiredPatterns) { + if ( + !checkFileContent( + file.path, + file.name, + file.requiredSections, + file.requiredPatterns, + ) + ) { + allPassed = false; + } + } + + // Special validation for CODEOWNERS + if (file.path === ".github/CODEOWNERS.example") { + if (!validateCodeownersFile(file.path)) { + allPassed = false; + } + } + } + + // Additional completeness checks + log(`\n${colors.bold}Checking documentation completeness...${colors.reset}`); + checkDocumentationCompleteness(); + + // Final result + log(`\n${colors.bold}Results:${colors.reset}`); + if (allPassed) { + logSuccess("All documentation requirements are met! πŸŽ‰"); + process.exit(0); + } else { + logError( + "Some documentation requirements are not met. Please address the issues above.", + ); + process.exit(1); + } +} + +// Run the linter +main();