enhancement: set up monorepo build tooling and CI/CD pipeline - #14
ViewFromTheBox merged 2 commits into
Conversation
Configure ESLint 9 flat config with TypeScript and React support, Prettier for consistent formatting, Changesets for version management, and rewrite the CI/CD workflow from PHP/Pest to Node.js with lint, type-check, test, build, and automated npm publishing via Changesets. Closes #1 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughAdds project-wide developer tooling and CI/CD: Prettier, ESLint, TypeScript config, Vitest adjustments, Changesets for releases, repo package.json script updates, module boundary markers, and a revamped GitHub Actions workflow that uses Node/npm and Changesets to publish from main. Changes
Sequence Diagram(s)mermaid Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
packages/tokens/vitest.config.ts (1)
6-6: Consider adding a test coverage gate in CI as packages mature beyond bootstrap.
passWithNoTests: trueis appropriate during initial setup, but it can hide accidental test deletion over time. Aspackages/tokensdevelops, add a CI check that fails the build if the package still has zero test files after the bootstrap phase (e.g., on releases or after a certain date). This ensures tests become a required part of the package lifecycle.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/tokens/vitest.config.ts` at line 6, The vitest config currently sets passWithNoTests: true which hides missing tests; update CI to enforce a test presence/coverage gate for packages/tokens by (1) adding a workflow step that checks for the existence of test files (e.g., glob like **/packages/tokens/**/__tests__/**/* or **/*.test.{ts,tsx,js,jsx}) and fails if none are found, or (2) run Vitest in CI with passWithNoTests disabled for packages/tokens (set passWithNoTests to false in the CI run) and/or enforce a minimum coverage threshold so the build fails when coverage is zero; locate the setting named passWithNoTests in vitest.config.ts and adjust the CI workflow or job to run the stricter check only after bootstrap/maturation (e.g., gated by branch, tag, or date).packages/react-laravel/package.json (1)
18-18: Consider removing unused vitest devDependency.The test scripts were removed, but
vitestremains indevDependencies(line 29). If this package has no tests and won't have tests in the near term, consider removing thevitestdevDependency to keep the dependency tree clean.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/react-laravel/package.json` at line 18, The devDependency "vitest" is unused after removing test scripts; remove the "vitest" entry from package.json's devDependencies and any related configuration (e.g., vitest config or scripts referencing vitest) to keep the dependency tree clean—locate the "vitest" string in package.json and delete that entry, then run npm/yarn/pnpm install to update lockfile and ensure no build scripts (e.g., "build": "tsup") or CI steps reference vitest..github/workflows/ci.yml (1)
33-34: Use the defined npm script for consistency.Line 34 runs Prettier directly via
npx, butpackage.jsonalready defines aformat:checkscript. Using the script ensures the CI and local development stay in sync.♻️ Proposed fix
- name: Check formatting - run: npx prettier --check "packages/*/src/**/*.{ts,tsx}" + run: npm run format:check🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/ci.yml around lines 33 - 34, The CI step named "Check formatting" currently invokes Prettier directly; replace that run command to use the project's npm script (format:check) instead so CI uses the same entrypoint as local dev. Locate the "Check formatting" job/step and change its run invocation from the direct npx call to running the npm script (e.g., npm run format:check) so formatting checks remain consistent.package.json (1)
22-30: Consider removing redundant@typescript-eslint/*packages.Lines 23-24 declare
@typescript-eslint/eslint-pluginand@typescript-eslint/parseras separate dependencies, buttypescript-eslint(line 30) re-exports both. Sinceeslint.config.jsonly imports fromtypescript-eslint, the separate packages appear unused.♻️ Proposed cleanup
"devDependencies": { "@changesets/cli": "^2.27.0", "@eslint/js": "^9.39.4", - "@typescript-eslint/eslint-plugin": "^8.0.0", - "@typescript-eslint/parser": "^8.0.0", "eslint": "^9.0.0", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^7.0.1", "prettier": "^3.4.0", "typescript": "^5.7.0", "typescript-eslint": "^8.57.2" }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@package.json` around lines 22 - 30, package.json declares "@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser" separately but you already depend on "typescript-eslint" which re-exports them and eslint.config.js imports only from "typescript-eslint"; remove the two redundant packages ("@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser") from package.json, run your package manager to update lockfile, and scan for any direct imports/usages of those two package names (e.g., in eslint configs or scripts) to replace with imports from "typescript-eslint" if found before committing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/react/package.json`:
- Around line 52-53: The package.json currently uses "@vitejs/plugin-react":
"^4.3.0" which requires Vite 6+ and conflicts with Vitest 2.1's Vite ^5.x; fix
by either downgrading "@vitejs/plugin-react" to a Vite-5-compatible release (pin
"@vitejs/plugin-react" to a 4.x range known to support Vite 5) or upgrading
"vitest" to a 3.x release that supports Vite 6+, and also bump "jsdom" to
"^29.0.1"; update the dependencies entries for "@vitejs/plugin-react", "vitest",
and "jsdom" in package.json accordingly and run a reinstall and type-check to
verify the conflict is resolved.
---
Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 33-34: The CI step named "Check formatting" currently invokes
Prettier directly; replace that run command to use the project's npm script
(format:check) instead so CI uses the same entrypoint as local dev. Locate the
"Check formatting" job/step and change its run invocation from the direct npx
call to running the npm script (e.g., npm run format:check) so formatting checks
remain consistent.
In `@package.json`:
- Around line 22-30: package.json declares "@typescript-eslint/eslint-plugin"
and "@typescript-eslint/parser" separately but you already depend on
"typescript-eslint" which re-exports them and eslint.config.js imports only from
"typescript-eslint"; remove the two redundant packages
("@typescript-eslint/eslint-plugin" and "@typescript-eslint/parser") from
package.json, run your package manager to update lockfile, and scan for any
direct imports/usages of those two package names (e.g., in eslint configs or
scripts) to replace with imports from "typescript-eslint" if found before
committing.
In `@packages/react-laravel/package.json`:
- Line 18: The devDependency "vitest" is unused after removing test scripts;
remove the "vitest" entry from package.json's devDependencies and any related
configuration (e.g., vitest config or scripts referencing vitest) to keep the
dependency tree clean—locate the "vitest" string in package.json and delete that
entry, then run npm/yarn/pnpm install to update lockfile and ensure no build
scripts (e.g., "build": "tsup") or CI steps reference vitest.
In `@packages/tokens/vitest.config.ts`:
- Line 6: The vitest config currently sets passWithNoTests: true which hides
missing tests; update CI to enforce a test presence/coverage gate for
packages/tokens by (1) adding a workflow step that checks for the existence of
test files (e.g., glob like **/packages/tokens/**/__tests__/**/* or
**/*.test.{ts,tsx,js,jsx}) and fails if none are found, or (2) run Vitest in CI
with passWithNoTests disabled for packages/tokens (set passWithNoTests to false
in the CI run) and/or enforce a minimum coverage threshold so the build fails
when coverage is zero; locate the setting named passWithNoTests in
vitest.config.ts and adjust the CI workflow or job to run the stricter check
only after bootstrap/maturation (e.g., gated by branch, tag, or date).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 97db07fe-0ac8-40fa-8d5c-67b0b24feb69
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (19)
.changeset/README.md.changeset/config.json.github/workflows/ci.yml.prettierignore.prettierrceslint.config.jspackage.jsonpackages/react-laravel/package.jsonpackages/react-laravel/src/index.tspackages/react/package.jsonpackages/react/src/components/data/index.tspackages/react/src/components/display/index.tspackages/react/src/components/form/index.tspackages/react/src/components/layout/index.tspackages/react/src/components/navigation/index.tspackages/react/src/components/utility/index.tspackages/react/vitest.config.tspackages/tokens/vitest.config.tstsconfig.json
| "@vitejs/plugin-react": "^4.3.0", | ||
| "jsdom": "^27.0.1", |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Is @vitejs/plugin-react version 4.3.0 compatible with React 19 and Vitest 2.1?
💡 Result:
No, @vitejs/plugin-react version 4.3.0 is not fully compatible with both React 19 and Vitest 2.1. It is compatible with React 19: The plugin's changelog and development dependencies explicitly support React Compiler for React 19 (target: '19'), with fixes in 4.3.0 and later for React compiler support. PRs update @types/react and react to ^19.x versions. However, it has compatibility issues with Vitest 2.1: Vitest 2.1 does not fully support Vite 6, which is added to the plugin's peerDependencies in 4.3.4. Users report TypeScript errors like "Type 'PluginOption[]' is not assignable to type 'PluginOption'" when using the React plugin in Vitest config, due to Vite version mismatches. Vitest 2.x requires Vite ^5.x, while plugin 4.3.0 targets Vite 6+.
Citations:
- 1: fix(deps): update react monorepo to v19 (major) vitejs/vite-plugin-react#393
- 2: https://github.com/vitejs/vite-plugin-react/releases
- 3: https://www.npmjs.com/package/@vitejs/plugin-react
- 4: https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/CHANGELOG.md
- 5: fix(deps): update all non-major dependencies vitejs/vite-plugin-react#392
- 6: Vite 6 + React Router 7 - Type PluginOption[] is not assignable to type PluginOption vitest-dev/vitest#7075
- 7: Update vitest 2.0.5 → 2.1.8 (minor) tailwindlabs/tailwindcss#15372
- 8: Should vite be a peerDependency instead of a full dependency? vitest-dev/vitest#4142
- 9:
@vitest/pretty-formatis not compatible with React 19 snapshots vitest-dev/vitest#6908 - 10: Plugins: [react()] in defineConfig cause error Type 'PluginOption[]' is not assignable to type 'PluginOption'. vitest-dev/vitest#4048
- 11: https://www.npmjs.com/package/vitest?activeTab=dependencies
🌐 Web query:
What is the latest stable version of jsdom and is version 27.0.1 appropriate for testing with React 19?
💡 Result:
The latest stable version of jsdom is 29.0.1. Version 27.0.1 is a stable release from October 2025 but is outdated compared to the current latest. It can be used for testing with React 19, as React 19 works with jsdom versions supported by Jest (which added v27 support), and no specific incompatibilities are noted for v27.0.1 with React 19; issues in testing environments are typically resolved via dependency overrides like for pretty-format/react-is.
Citations:
- 1: https://github.com/jsdom/jsdom/releases
- 2: https://www.npmjs.com/package/jsdom
- 3: https://github.com/jsdom/jsdom/tags
- 4: https://github.com/jsdom/jsdom/blob/main/Changelog.md
- 5: [Bug]: Snapshot tests failing for React 19 jestjs/jest#15402
- 6: Support jsdom v27 and upgrade dependency jestjs/jest#15828
Resolve Vite version conflict between @vitejs/plugin-react and Vitest 2.1.
@vitejs/plugin-react@^4.3.0 is compatible with React 19, but it targets Vite 6+, which conflicts with Vitest 2.1's requirement for Vite ^5.x. This causes TypeScript errors when using the React plugin in Vitest configuration. Either downgrade the React plugin to a version compatible with Vite 5, or upgrade Vitest to 3.x which supports Vite 6.
Additionally, upgrade jsdom to ^29.0.1 (latest stable), as version 27.0.1 is outdated though still functional with React 19.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/react/package.json` around lines 52 - 53, The package.json currently
uses "@vitejs/plugin-react": "^4.3.0" which requires Vite 6+ and conflicts with
Vitest 2.1's Vite ^5.x; fix by either downgrading "@vitejs/plugin-react" to a
Vite-5-compatible release (pin "@vitejs/plugin-react" to a 4.x range known to
support Vite 5) or upgrading "vitest" to a 3.x release that supports Vite 6+,
and also bump "jsdom" to "^29.0.1"; update the dependencies entries for
"@vitejs/plugin-react", "vitest", and "jsdom" in package.json accordingly and
run a reinstall and type-check to verify the conflict is resolved.
- Use npm run format:check in CI instead of direct npx prettier call - Remove redundant @typescript-eslint/eslint-plugin and @typescript-eslint/parser (already provided by typescript-eslint) - Remove unused vitest from react-laravel devDependencies Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
🧹 Nitpick comments (1)
.github/workflows/ci.yml (1)
94-128: EnsureNPM_TOKENsecret is configured; consider build artifact optimization.Two observations:
Required secret: The
NPM_TOKENsecret must be configured in repository settings (Settings → Secrets and variables → Actions) for npm publishing to work. Verify this is set up.Optional optimization: The build step (lines 117-118) duplicates work already done in the
buildjob. You could upload thedistartifacts from thebuildjob and download them here to save ~1-2 minutes of CI time. This is optional since the current approach is correct and simpler.♻️ Optional: Share build artifacts between jobs
In the
buildjob, add after the build step:- name: Upload build artifacts uses: actions/upload-artifact@v4 with: name: dist path: packages/*/distIn the
releasejob, replace the build step with:- name: Download build artifacts uses: actions/download-artifact@v4 with: name: dist path: packages🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/workflows/ci.yml around lines 94 - 128, The release job currently requires the NPM_TOKEN secret and rebuilds artifacts; ensure the NPM_TOKEN repository secret is configured (Settings → Secrets and variables → Actions) so the changesets/action publish step can authenticate, and optionally optimize CI by uploading the build artifacts from the build job and downloading them in the release job: in the build job add an "Upload build artifacts" step that uploads packages/*/dist (used by the Build all packages step), and in the release job replace the "Build all packages" step with a "Download build artifacts" step to restore the dist artifacts before running changesets/action (refer to the release job name "release", the "Build all packages" step, and the changesets/action step).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 94-128: The release job currently requires the NPM_TOKEN secret
and rebuilds artifacts; ensure the NPM_TOKEN repository secret is configured
(Settings → Secrets and variables → Actions) so the changesets/action publish
step can authenticate, and optionally optimize CI by uploading the build
artifacts from the build job and downloading them in the release job: in the
build job add an "Upload build artifacts" step that uploads packages/*/dist
(used by the Build all packages step), and in the release job replace the "Build
all packages" step with a "Download build artifacts" step to restore the dist
artifacts before running changesets/action (refer to the release job name
"release", the "Build all packages" step, and the changesets/action step).
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 747c053b-4a03-41a5-b39f-6ce14267afef
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (3)
.github/workflows/ci.ymlpackage.jsonpackages/react-laravel/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/react-laravel/package.json
- package.json
Description
Set up the complete monorepo development infrastructure including ESLint, Prettier, Changesets, and a fully rewritten CI/CD pipeline for Node.js.
Closes: #1
Type of Change
Related Issue
Issue: #1
Motivation and Context
The React monorepo had no linting, formatting, or CI/CD configuration. The existing CI workflow was a copy-pasted PHP/Pest pipeline from another package. All other component work is blocked until this tooling foundation is in place.
Changes Made
eslint.config.jswith ESLint 9 flat config, TypeScript, React, and React Hooks support.prettierrcand.prettierignorefor consistent code formatting.changeset/config.json) with public access and linked versioning across all three packages.github/workflows/ci.ymlfrom PHP/Pest to Node.js with lint, type-check, test, build, and Changesets release jobs"type": "module"to rootpackage.json--extflag)type-checkandformat:checkscripts to rootpackage.json--if-presentflag to workspace test scriptincludepatterns to roottsconfig.jsonpassWithNoTests: trueto vitest configs for tokens and react packagesjsdomdev dependency for react package testsexport {}to empty component index files to make them valid TypeScript modules@eslint/js,typescript-eslint,eslint-plugin-react,eslint-plugin-react-hooksHow Has This Been Tested?
Testing Environment:
Tests Performed:
npm run lint— ESLint passes with no errorsnpm run type-check— TypeScript type checking passesnpm test— Vitest runs across workspaces (passes with no test files)npm run build— All three packages build successfully via tsupnpm run format:check— Prettier formatting check passesAccessibility Tests Run
Tests Added
Test details: No new test files — this PR sets up the infrastructure for testing. Existing vitest configs now handle the "no test files" case gracefully.
Documentation
Documentation details: N/A — tooling configuration, self-documenting via config files.
Pre-Submission Checklist
Summary by CodeRabbit
New Features
Chores