Skip to content

optimize turbo and parallelize ci#124

Merged
drake-nathan merged 10 commits into
mainfrom
optimize-turbo
Jan 11, 2026
Merged

optimize turbo and parallelize ci#124
drake-nathan merged 10 commits into
mainfrom
optimize-turbo

Conversation

@drake-nathan
Copy link
Copy Markdown
Owner

@drake-nathan drake-nathan commented Dec 26, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Fixed ESLint compatibility with @eslint/core 1.0.1
  • Chores

    • Updated development dependencies for improved stability and compatibility
    • Optimized CI/build workflow structure
    • Enhanced TypeScript and JSX configuration

✏️ Tip: You can customize this high-level summary in your review settings.

@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Dec 26, 2025

🦋 Changeset detected

Latest commit: 3659160

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
eslint-plugin-nextjs Patch
js-style-kit Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Dec 26, 2025

Walkthrough

CI workflow refactored into phased execution model with consolidated commands. Multiple dependency versions updated across workspace packages. ESLint plugin rule metadata simplified by removing deprecated category fields. TypeScript JSX runtime switched to "react-jsx" in test app. CLI test refactored to use spawnSync. Turbo task configuration adjusted with narrowed inputs and added build dependencies.

Changes

Cohort / File(s) Summary
CI Workflow & Orchestration
.github/workflows/ci.yaml, scripts/ci.js, turbo.json
Restructured CI into three phases: Phase 1 (build & sherif), Phase 2 (format), Phase 3 (typecheck, lint, test). Introduced concurrent phase execution with consolidated status rendering. Updated turbo task dependencies and inputs; added bun.lock to globalDependencies.
Dependency Updates - Style Kit
packages/style-kit/package.json, .changeset/update-style-kit-deps.md
Updated ESLint ecosystem and tooling: typescript-eslint (8.52.0), eslint-plugin-jest (29.12.1), eslint-plugin-jsdoc (62.0.0), eslint-plugin-perfectionist (5.3.1), eslint-plugin-storybook (10.1.11), eslint-plugin-turbo (2.7.3), globals (17.0.0), prettier-plugin-css-order (2.2.0).
Dependency Updates - Root & Apps
package.json, apps/next-test-app/package.json, apps/vite-test-app/package.json
Bumped turbo (2.7.3), @types/react (19.2.8), convex (1.31.3), vite (7.3.1).
ESLint Plugin Fixes
packages/eslint-plugin-nextjs/package.json, packages/eslint-plugin-nextjs/src/rules/*.ts, .changeset/update-eslint-plugin-nextjs.md
Updated @eslint/core (1.0.1) and eslint-plugin-eslint-plugin (7.3.0). Removed deprecated category field from rule metadata in no-head-element.ts, no-html-link-for-pages.ts, no-img-element.ts.
Configuration & Testing
apps/next-test-app/tsconfig.json, packages/style-kit/bin/cli.test.ts
Switched JSX runtime from "preserve" to "react-jsx"; extended TypeScript includes. Refactored CLI test to use spawnSync instead of execSync with 10-second timeout; removed working directory manipulation.

Possibly related PRs

  • update-deps #76: Overlapping dependency version updates across the same package.json files (packages/style-kit, root, and app packages).
  • update deps #84: Modifies CI orchestration in scripts/ci.js and turbo.json task configurations similarly.
  • Switch from pnpm to bun #39: Related pnpm-to-bun migration updates in CI workflow and turbo.json configurations.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~30 minutes

Poem

🐰 Three phases now dance in harmony,
Build, format, test in symphony,
Dependencies bloom and rules refine,
TypeScript glows with "react-jsx" shine,
CI sprints faster than a bunny's stride! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main changes: optimizing turbo configuration and parallelizing CI workflow, which are reflected across turbo.json and .github/workflows/ci.yaml modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Dec 26, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (4)
scripts/ci.js (2)

114-157: Consider adding a timeout for command execution.

The runCommand function has no timeout mechanism. If a command hangs (e.g., due to a deadlock or infinite loop), the CI script will wait indefinitely. Consider adding a timeout option to spawn or implementing manual timeout handling.

🔎 Example timeout implementation
 const runCommand = async (cmd) => {
-  const { command, name } = cmd;
+  const { command, name } = cmd;
+  const TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes

   // Update status to running
   status[name].status = "running";
   status[name].startTime = Date.now();
   commandOutputs[name] = [];
   printStatus();

   return new Promise((resolve) => {
     const proc = spawn(command, {
       shell: true,
       stdio: ["pipe", "pipe", "pipe"],
     });

+    const timeout = setTimeout(() => {
+      proc.kill("SIGTERM");
+      commandOutputs[name].push({ output: "Command timed out", type: "stderr" });
+    }, TIMEOUT_MS);

     // ... existing handlers ...

     proc.on("close", (code) => {
+      clearTimeout(timeout);
       status[name].endTime = Date.now();
       // ...
     });
   });
 };

59-67: Type safety consideration for status object.

The status object is initialized with an implicit any type via reduce. While this works, adding JSDoc type annotations would improve maintainability and IDE support.

🔎 Optional: Add JSDoc types
+/**
+ * @typedef {{ status: string; startTime: number; endTime: number; turboCache: boolean }} CommandStatus
+ * @type {Record<string, CommandStatus>}
+ */
 const status = allCommands.reduce((acc, cmd) => {
   acc[cmd.name] = {
     endTime: 0,
     startTime: 0,
     status: "pending",
     turboCache: false,
   };
   return acc;
 }, {});
.github/workflows/ci.yaml (2)

59-79: Format commit may trigger recursive CI runs.

When the format job commits and pushes changes, it will trigger a new pull_request: synchronize event, potentially causing recursive CI runs. Consider either:

  1. Using [skip ci] in the commit message
  2. Using a bot token that doesn't trigger workflows
  3. Adding a condition to skip if the last commit was from the bot
🔎 Option: Add [skip ci] to commit message
          if [[ -n "$(git status --porcelain)" ]]; then
            git add .
-           git commit -m "style: apply prettier formatting"
+           git commit -m "style: apply prettier formatting [skip ci]"

Note: [skip ci] would skip the entire workflow for the new commit. If you need partial runs, consider using a Personal Access Token that doesn't trigger workflows instead of GITHUB_TOKEN.


26-32: Consider adding dependency caching to improve job performance.

oven-sh/setup-bun@v2 only caches the Bun executable; project dependencies are not automatically cached. Each job independently runs bun install --frozen-lockfile, which downloads dependencies from scratch. Explicit caching with actions/cache will significantly improve CI times, especially as the monorepo grows.

🔎 Example: Add Bun cache
      - name: Set up Bun
        uses: oven-sh/setup-bun@v2
        with:
          bun-version-file: "package.json"

      - name: Cache Bun dependencies
        uses: actions/cache@v4
        with:
          path: ~/.bun/install/cache
          key: ${{ runner.os }}-bun-${{ hashFiles('bun.lockb') }}
          restore-keys: |
            ${{ runner.os }}-bun-

      - name: Install dependencies
        run: bun install --frozen-lockfile

Also applies to: 48-54, 88-94, 108-114, 129-135, 148-154

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 395a26f and 95468b7.

📒 Files selected for processing (3)
  • .github/workflows/ci.yaml
  • scripts/ci.js
  • turbo.json
🧰 Additional context used
📓 Path-based instructions (1)
scripts/ci.js

📄 CodeRabbit inference engine (CLAUDE.md)

Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Files:

  • scripts/ci.js
🧠 Learnings (6)
📓 Common learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching

Applied to files:

  • .github/workflows/ci.yaml
  • turbo.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Applied to files:

  • .github/workflows/ci.yaml
  • scripts/ci.js
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Bun as the package manager and test runner across the repository

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-27T20:21:53.141Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.

Applied to files:

  • .github/workflows/ci.yaml
  • scripts/ci.js
  • turbo.json
📚 Learning: 2025-09-27T20:21:27.195Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.

Applied to files:

  • .github/workflows/ci.yaml
  • turbo.json
🧬 Code graph analysis (1)
scripts/ci.js (1)
packages/style-kit/bin/lib/setup-scripts.ts (1)
  • console (6-30)
🔇 Additional comments (11)
turbo.json (3)

3-3: Good improvement: centralizing lockfile as a global dependency.

Moving bun.lock to globalDependencies correctly ensures all tasks invalidate when dependencies change, rather than duplicating this in individual task inputs.


5-7: Root-level tasks with empty configs will not be cached.

Empty configurations for //#lint, //#lint:fix, and //#sherif mean these root-level tasks won't benefit from Turborepo caching. If these tasks are executed via turbo run, consider whether caching is intentionally disabled or if you want to add inputs for cache validation.


17-21: Task dependencies correctly enforce build-first ordering.

The dependsOn: ["^build"] configuration ensures workspace builds complete before lint, test, and typecheck tasks run. This aligns with the established requirement that build generates files needed by these tasks. Based on learnings, this is the correct approach.

Also applies to: 22-26, 32-35, 37-40, 42-46

scripts/ci.js (3)

4-28: Phase structure correctly separates build from dependent tasks.

The two-phase model appropriately runs build in Phase 1, then typecheck, lint, and test in Phase 2 after build completes. This aligns with the learning that build generates files needed by lint.

One consideration: format (Prettier) running in parallel with build in Phase 1 should be fine since Prettier formats source files, not build outputs. However, if any generated files need formatting, you may want to verify this works as expected.


159-179: LGTM!

The runPhase function cleanly runs all phase commands in parallel and only displays output for failed commands, reducing noise on success. Using Promise.all ensures all commands complete before evaluating results.


181-219: LGTM!

The sequential phase execution with early termination on failure is appropriate—there's no value in running Phase 2 validation if Phase 1 (including build) fails. The summary output and exit code handling are correct.

.github/workflows/ci.yaml (5)

13-15: Good practice: Turbo remote caching at workflow level.

Setting TURBO_TOKEN and TURBO_TEAM as workflow-level environment variables enables Turborepo remote caching across all jobs, which is essential for cache sharing in the parallelized architecture.


99-117: Jobs depend on build but don't receive build artifacts.

The typecheck, lint, and test jobs declare needs: [build] for ordering, but the build job doesn't upload artifacts. These dependent jobs rely entirely on Turbo remote caching to avoid rebuilding. This works if remote caching is properly configured, but if the cache misses, each job will rebuild independently.

Consider whether this is intentional or if you want to upload/download build artifacts for guaranteed consistency.


119-138: Lint job correctly depends on format and uses dynamic ref.

The needs: [build, format] ensures lint runs after formatting is complete. The checkout with ref: ${{ github.head_ref || github.ref_name }} picks up any committed formatting changes. This is the correct approach.


140-163: LGTM!

The test job correctly depends on build, runs coverage, and uploads to Codecov with if: always() to ensure coverage reports are uploaded even on test failures.


18-35: LGTM!

The sherif job correctly runs independently as it only checks package.json consistency and doesn't require build outputs.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
scripts/ci.js (1)

120-152: Consider handling spawn errors explicitly.

If the command itself fails to spawn (e.g., command not found, permission denied), the proc.on('error') event is emitted but not handled here. This could leave the promise hanging or cause unhandled exceptions.

🔎 Optional: Add error handler for spawn failures
     proc.on("close", (code) => {
       status[name].endTime = Date.now();
       status[name].status = code === 0 ? "success" : "failed";
       printStatus();
 
       resolve(code === 0);
     });
+
+    proc.on("error", (err) => {
+      commandOutputs[name].push({
+        output: `Spawn error: ${err.message}`,
+        type: "stderr",
+      });
+      status[name].endTime = Date.now();
+      status[name].status = "failed";
+      printStatus();
+      resolve(false);
+    });
   });
.github/workflows/ci.yaml (1)

13-15: Configure Turbo remote cache secrets for optimal CI performance.

The workflow uses TURBO_TOKEN and TURBO_TEAM to enable remote caching across jobs. Without these GitHub repository secrets/variables configured, each job will lack a remote cache and perform full rebuilds, significantly increasing CI runtime. Ensure these are set up in your repository settings.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 95468b7 and 4324365.

📒 Files selected for processing (2)
  • .github/workflows/ci.yaml
  • scripts/ci.js
🧰 Additional context used
📓 Path-based instructions (1)
scripts/ci.js

📄 CodeRabbit inference engine (CLAUDE.md)

Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Files:

  • scripts/ci.js
🧠 Learnings (6)
📓 Common learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Bun as the package manager and test runner across the repository

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-27T20:21:53.141Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.

Applied to files:

  • .github/workflows/ci.yaml
  • scripts/ci.js
📚 Learning: 2025-09-27T20:21:27.195Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Applied to files:

  • .github/workflows/ci.yaml
  • scripts/ci.js
🔇 Additional comments (11)
scripts/ci.js (4)

4-24: Phase structure correctly implements build dependencies.

The two-phase design properly ensures that build completes before format, lint, typecheck, and test run—aligning with the requirement that build generates files needed by linting/formatting. Based on learnings, this dependency ordering is correct.


66-105: Status rendering is well-implemented.

The phase-aware status display with dimmed headers, per-command coloring, and turbo cache hit indicators provides clear visual feedback during CI execution.


177-215: LGTM!

The execution flow correctly runs phases sequentially, fails fast on errors, and provides a clear final summary with total duration. The fail-fast approach is appropriate for CI where early feedback is valuable.


217-221: LGTM!

The interrupt handler properly catches SIGINT and exits with a non-zero code, allowing clean termination.

.github/workflows/ci.yaml (7)

13-15: Good practice: Turbo remote caching environment variables at workflow level.

Setting TURBO_TOKEN and TURBO_TEAM at the top level ensures all jobs can leverage remote caching, which is essential for sharing build artifacts across the separate jobs.


18-35: LGTM!

The sherif job runs independently without dependencies, correctly implementing parallel Phase 1 execution alongside the build job.


85-101: LGTM!

The build job is correctly isolated and will populate the Turbo remote cache, enabling fast cache hits in dependent jobs.


123-142: Lint job correctly depends on both build and format.

The dependency chain ensures:

  1. Build completes (populating cache)
  2. Format commits any changes
  3. Lint runs on the formatted code with --max-warnings 0 for strict checking

Based on learnings, the build→lint dependency is correctly enforced.


144-167: LGTM!

The test job correctly depends on build, runs coverage, and uploads to Codecov with if: always() to capture coverage even if tests fail.


103-121: The typecheck job correctly declares build as a dependency.

The typecheck job has needs: [build] just like the format job, and additionally benefits from Turbo's dependency management via turbo.json, where typecheck declares dependsOn: ["^build"]. Both mechanisms ensure build outputs are available before typecheck runs.

Likely an incorrect or invalid review comment.


37-58: Remove the redundant build step; Turbo remote caching is not configured.

The format job re-runs bunx turbo run build expecting a cache hit, but this will not occur because:

  1. Turbo remote cache is not configured in turbo.json
  2. GitHub Actions jobs run on isolated runners with no shared filesystem
  3. The needs: [build] dependency only ensures job ordering, not artifact/cache sharing

This rebuild is wasteful. Either remove the build step if not needed for prettier, or configure Turbo remote caching properly to enable cache reuse across isolated runners.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
.github/workflows/ci.yaml (2)

31-36: Consider adding Turbo cache for faster builds.

While Turbo remote caching is configured, adding a local cache layer for the .turbo directory would significantly speed up cache restoration. Local cache is faster than fetching from remote cache.

🔎 Proposed enhancement to add Turbo cache

Add this step after the Bun dependency cache in each job:

       - name: Cache Bun dependencies
         uses: actions/cache@v4
         with:
           path: ~/.bun/install/cache
           key: bun-${{ runner.os }}-${{ hashFiles('bun.lock') }}
           restore-keys: bun-${{ runner.os }}-
+
+      - name: Cache Turbo
+        uses: actions/cache@v4
+        with:
+          path: .turbo
+          key: turbo-${{ runner.os }}-${{ github.sha }}
+          restore-keys: turbo-${{ runner.os }}-

Apply this pattern to all jobs (sherif, build, format, typecheck, lint, test) for consistent performance improvement.

Also applies to: 56-61


3-6: Consider scoping contents: write permission to format job only.

Currently, all jobs inherit contents: write, but only the format job needs it to push formatting changes. Following the principle of least privilege, you could scope this permission to just the format job.

🔎 Proposed permission scoping

Move contents: write from workflow level to the format job:

 permissions:
   checks: write
   pull-requests: write
-  contents: write

 # ... rest of workflow ...

 format:
   name: Format
   needs: [build]
   runs-on: ubuntu-latest
+  permissions:
+    contents: write
   steps:

Other jobs would inherit read-only access by default, improving security posture.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4324365 and 04dbaf4.

📒 Files selected for processing (1)
  • .github/workflows/ci.yaml
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Bun as the package manager and test runner across the repository

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-27T20:21:53.141Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-27T20:21:27.195Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Applied to files:

  • .github/workflows/ci.yaml
🔇 Additional comments (4)
.github/workflows/ci.yaml (4)

13-15: LGTM: Turbo remote caching configured correctly.

Environment variables are properly sourced from secrets and vars, enabling Turbo's remote caching across all jobs.


70-98: Format job structure is correct.

The dependency on build and the rebuild step for prettier config align with the project's established pattern where build generates files needed for formatting.

Based on learnings, the build command must run before format.


156-180: Lint dependencies correctly ordered.

The dual dependency on both build and format ensures that:

  1. ESLint config is available from the build step
  2. Linting runs on the formatted code after format pushes changes

The checkout with ref: ${{ github.head_ref || github.ref_name }} correctly fetches the potentially formatted code.


125-152: Typecheck and Test jobs properly depend on build.

Both jobs correctly:

  • Depend on the build job to ensure type definitions and test imports are available
  • Rebuild using Turbo (which should hit cache for fast execution)
  • Follow the established pattern for Phase 2 validation

Also applies to: 185-209

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 04dbaf4 and 8ecc844.

📒 Files selected for processing (1)
  • .github/workflows/ci.yaml
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Bun as the package manager and test runner across the repository

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-27T20:21:53.141Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.

Applied to files:

  • .github/workflows/ci.yaml
📚 Learning: 2025-09-27T20:21:27.195Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.

Applied to files:

  • .github/workflows/ci.yaml
🪛 actionlint (1.7.9)
.github/workflows/ci.yaml

53-53: "github.head_ref" is potentially untrusted. avoid using it directly in inline scripts. instead, pass it through an environment variable. see https://docs.github.com/en/actions/reference/security/secure-use#good-practices-for-mitigating-script-injection-attacks for more details

(expression)

🔇 Additional comments (5)
.github/workflows/ci.yaml (5)

13-15: LGTM! Workflow-level environment variables simplify configuration.

Defining TURBO_TOKEN and TURBO_TEAM at the workflow level is a good practice that eliminates duplication across jobs.


44-46: LGTM! Phase 1 parallelization is appropriate.

Combining build and sherif allows Turbo to parallelize these independent tasks, while correctly maintaining the build-before-lint/format sequence (format is Phase 2, lint is Phase 3).


48-50: LGTM! Format step is correctly sequenced.

Running format after build and before lint ensures that linting validates the formatted code, maintaining the proper build → format → lint dependency chain.


72-74: LGTM! Phase 3 consolidation is well-structured.

Combining typecheck, lint, and test:coverage allows Turbo to parallelize these independent validation tasks while maintaining proper dependencies on build and format completion.


34-39: The cache path ~/.bun/install/cache is correct according to Bun's official documentation and matches the standard location for Bun's global install cache.

Comment thread .github/workflows/ci.yaml
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Fix all issues with AI agents
In @apps/next-test-app/next-env.d.ts:
- Line 3: Remove the manual import of "./.next/dev/types/routes.d.ts" from
next-env.d.ts because it contradicts the file's "do not edit" guidance and
causes TS errors in fresh checkouts; delete the import statement (the line
containing import "./.next/dev/types/routes.d.ts";) and rely on Next.js's
automatic route type generation during next dev/build/typegen, leaving the rest
of next-env.d.ts unchanged.

In @packages/style-kit/bin/cli.test.ts:
- Around line 45-91: Replace the process.chdir/execSync pattern in the "detects
different package managers correctly" test with a child_process.spawnSync call
that sets cwd to testDir and captures stdout/stderr; specifically, stop mutating
global process.cwd(), remove the try/finally restore logic, and call spawnSync
like spawnSync("node", [CLI_PATH, "init"], { cwd: testDir, encoding: "utf8" })
(or equivalent) then assert against result.stdout || result.stderr to verify
"Using package manager: bun"; keep the existing test setup (package.json,
bun.lock), timeout, and variable names (CLI_PATH, testDir) so the change is
minimal.

In @packages/style-kit/package.json:
- Line 53: The package.json upgrade bumps for eslint-plugin-jsdoc and globals
introduce breaking changes; revert or pin "eslint-plugin-jsdoc" to the last
compatible 61.x (e.g., 61.5.0) and "globals" to 16.x (e.g., 16.5.0) in
packages/style-kit's package.json, run npm/yarn install to update the lockfile,
run the test suite and any consumer compatibility checks, and add a comment or
changelog entry noting Node engine requirements if you later decide to accept
62.0.0 (or alternatively add an "engines" field to package.json to require Node
>=20.19.0 if you intentionally move to eslint-plugin-jsdoc@62).
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ecc844 and b0d61fc.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (14)
  • .changeset/update-eslint-plugin-nextjs.md
  • .changeset/update-style-kit-deps.md
  • .github/workflows/ci.yaml
  • apps/next-test-app/next-env.d.ts
  • apps/next-test-app/package.json
  • apps/next-test-app/tsconfig.json
  • apps/vite-test-app/package.json
  • package.json
  • packages/eslint-plugin-nextjs/package.json
  • packages/eslint-plugin-nextjs/src/rules/no-head-element.ts
  • packages/eslint-plugin-nextjs/src/rules/no-html-link-for-pages.ts
  • packages/eslint-plugin-nextjs/src/rules/no-img-element.ts
  • packages/style-kit/bin/cli.test.ts
  • packages/style-kit/package.json
💤 Files with no reviewable changes (3)
  • packages/eslint-plugin-nextjs/src/rules/no-head-element.ts
  • packages/eslint-plugin-nextjs/src/rules/no-html-link-for-pages.ts
  • packages/eslint-plugin-nextjs/src/rules/no-img-element.ts
✅ Files skipped from review due to trivial changes (1)
  • .changeset/update-style-kit-deps.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • .github/workflows/ci.yaml
🧰 Additional context used
📓 Path-based instructions (1)
apps/**

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain integration test applications under the apps/ directory to validate real-world configurations

Files:

  • apps/next-test-app/package.json
  • apps/vite-test-app/package.json
  • apps/next-test-app/tsconfig.json
  • apps/next-test-app/next-env.d.ts
🧠 Learnings (16)
📓 Common learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.
📚 Learning: 2025-10-16T22:50:32.349Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 96
File: packages/style-kit/src/eslint/convex/config.ts:0-0
Timestamp: 2025-10-16T22:50:32.349Z
Learning: For Convex ESLint configuration in packages/style-kit/src/eslint/convex/config.ts, the file pattern should only include `.js` and `.ts` files (not `.jsx` or `.tsx`), as Convex directories contain backend/server-side code and should not have React component files.

Applied to files:

  • apps/next-test-app/package.json
  • apps/next-test-app/tsconfig.json
  • packages/style-kit/package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/eslint-plugin-nextjs/test/** : Keep comprehensive tests for the Next.js ESLint plugin under packages/eslint-plugin-nextjs/test/

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • packages/style-kit/bin/cli.test.ts
  • apps/next-test-app/tsconfig.json
  • packages/style-kit/package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/eslint-plugin-nextjs/src/rules/** : Place individual ESLint rule implementations for the Next.js plugin in packages/eslint-plugin-nextjs/src/rules/

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • .changeset/update-eslint-plugin-nextjs.md
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/eslint-plugin-nextjs/src/utils/** : Store shared utilities for ESLint rules under packages/eslint-plugin-nextjs/src/utils/

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • .changeset/update-eslint-plugin-nextjs.md
📚 Learning: 2025-03-15T03:32:01.610Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 39
File: packages/style-kit/package.json:65-65
Timestamp: 2025-03-15T03:32:01.610Z
Learning: The js-style-kit package continues to ship and support the Vitest ESLint plugin (`eslint-plugin-vitest`) as a dependency, even though the package itself has migrated from using Vitest to Bun for its internal testing.

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • apps/vite-test-app/package.json
  • packages/style-kit/bin/cli.test.ts
  • packages/style-kit/package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/style-kit/src/eslint/index.ts : Implement the main ESLint configuration factory at packages/style-kit/src/eslint/index.ts

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • packages/style-kit/package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use tsup as the TypeScript bundler for packages

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • package.json
  • apps/next-test-app/tsconfig.json
📚 Learning: 2025-09-27T20:21:27.195Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.

Applied to files:

  • packages/eslint-plugin-nextjs/package.json
  • package.json
  • apps/next-test-app/tsconfig.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Bun as the package manager and test runner across the repository

Applied to files:

  • package.json
  • packages/style-kit/bin/cli.test.ts
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching

Applied to files:

  • package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/style-kit/bin/index.ts : Provide the CLI entry point at packages/style-kit/bin/index.ts

Applied to files:

  • packages/style-kit/bin/cli.test.ts
  • packages/style-kit/package.json
📚 Learning: 2025-09-27T20:21:53.141Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.

Applied to files:

  • packages/style-kit/bin/cli.test.ts
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/style-kit/src/index.ts : Expose the main style-kit entry point from packages/style-kit/src/index.ts

Applied to files:

  • packages/style-kit/bin/cli.test.ts
  • packages/style-kit/package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/style-kit/src/eslint/** : Organize ESLint configuration modules under packages/style-kit/src/eslint/, with plugin-specific subfolders (e.g., base/, import/, react/)

Applied to files:

  • packages/style-kit/package.json
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/style-kit/src/prettier/** : Keep Prettier configuration (and its plugin support) under packages/style-kit/src/prettier/

Applied to files:

  • packages/style-kit/package.json
🧬 Code graph analysis (1)
packages/style-kit/bin/cli.test.ts (1)
packages/style-kit/bin/lib/detect-package-manager.test.ts (7)
  • mockFs (35-45)
  • mockFs (47-55)
  • mockFs (139-148)
  • mockFs (25-33)
  • mockFs (100-109)
  • beforeEach (11-173)
  • mockFs (111-122)
🔇 Additional comments (7)
.changeset/update-eslint-plugin-nextjs.md (1)

1-5: Changeset entry is properly formatted, but verify alignment with PR objectives.

The .changeset file is syntactically correct and the patch bump is appropriate for a compatibility fix. However, the PR objectives describe "optimize turbo and parallelize ci," while this file documents an ESLint plugin compatibility update—these appear misaligned. The AI-generated summary mentions related updates to rule metadata, but those implementation files are not included in this review.

Please confirm that all relevant files from this PR have been provided for review (e.g., workflow files, turbo.json, scripts/ci.js, or ESLint rule files mentioned in the summary).

apps/next-test-app/tsconfig.json (2)

26-32: The .next directory includes in tsconfig.json are valid in this context.

While .next/types/**/*.ts and .next/dev/types/**/*.ts are generated files that don't exist until the build runs, the CI workflow ensures this is not a problem: the build step (Phase 1) completes before the typecheck step (Phase 3). Additionally, next-env.d.ts explicitly imports from ./.next/dev/types/routes.d.ts, so the tsconfig includes are consistent with Next.js's own type references. This configuration is appropriate for the integration test app.


7-7: Clarify why "react-jsx" is used instead of Next.js-recommended "preserve".

Next.js officially recommends setting "jsx": "preserve" to let the Next.js compiler (SWC) handle JSX transformation. This test app uses "react-jsx" instead, which is a valid alternative but non-standard. If this is intentional for testing alternative configurations, document the reason.

⛔ Skipped due to learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 96
File: packages/style-kit/src/eslint/convex/config.ts:0-0
Timestamp: 2025-10-16T22:50:32.349Z
Learning: For Convex ESLint configuration in packages/style-kit/src/eslint/convex/config.ts, the file pattern should only include `.js` and `.ts` files (not `.jsx` or `.tsx`), as Convex directories contain backend/server-side code and should not have React component files.
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 88
File: apps/vite-test-app/src/rule-tests/ReactHooks.tsx:45-53
Timestamp: 2025-10-10T00:25:39.030Z
Learning: Files in paths like `rule-tests/`, `lint-tests/`, or similar directories that contain React components are typically used to verify ESLint rule configurations and are never mounted or executed. In these test files, intentional violations of React rules (like calling setState during render) are expected and should not be flagged as issues, as they exist specifically to test that the linting rules catch those patterns.
packages/eslint-plugin-nextjs/package.json (1)

55-55: LGTM. The devDependency updates (@eslint/core to 1.0.1 and eslint-plugin-eslint-plugin to 7.3.0) are patch and minor versions with low risk to the published package.

Also applies to: 60-60

apps/vite-test-app/package.json (1)

17-17: Routine patch updates for test application dependencies.

Both @types/react@19.2.8 and vite@7.3.1 are valid patch versions. These updates are appropriate for the integration test application.

apps/next-test-app/package.json (1)

12-12: LGTM! Routine patch updates for test application.

Patch version updates to convex (1.31.3) and @types/react (19.2.8) are appropriate for this Next.js test application.

package.json (1)

30-30: Turbo upgrade to 2.7.3 is valid and safe.

turbo@2.7.3 is a valid patch release with no breaking changes. The changelog includes bug fixes (GitHub/git packages support for Bun), internal refactoring, and example improvements.

Comment thread apps/next-test-app/next-env.d.ts Outdated
Comment thread packages/style-kit/bin/cli.test.ts
Comment thread packages/style-kit/package.json
Comment thread packages/style-kit/package.json
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In @scripts/ci.js:
- Line 17: The CI entry currently runs the destructive formatter command; update
the CI job that defines the object with name "format" (the array element {
color: "\x1b[36m", command: "bun run format", name: "format" }) to use the
non-destructive check variant by changing the command to "bun run format:check"
so CI verifies formatting with Prettier --check instead of modifying files.
🧹 Nitpick comments (1)
scripts/ci.js (1)

111-153: Consider adding timeout handling for commands.

The runCommand function spawns processes without timeout mechanisms. If a command hangs indefinitely (due to deadlock, waiting for input, or network issues), the CI pipeline will block indefinitely rather than failing fast.

⏱️ Example timeout implementation
 const runCommand = async (cmd) => {
   const { command, name } = cmd;
 
   // Update status to running
   status[name].status = "running";
   status[name].startTime = Date.now();
   commandOutputs[name] = [];
   printStatus();
 
   return new Promise((resolve) => {
+    const TIMEOUT_MS = 600000; // 10 minutes
+    let timeoutId;
+
     const proc = spawn(command, {
       shell: true,
       stdio: ["pipe", "pipe", "pipe"],
     });
+
+    timeoutId = setTimeout(() => {
+      proc.kill('SIGTERM');
+      commandOutputs[name].push({
+        output: `Command timed out after ${TIMEOUT_MS / 1000}s`,
+        type: "stderr",
+      });
+    }, TIMEOUT_MS);
 
     // Collect stdout
     proc.stdout.on("data", (data) => {
       const output = data.toString().trim();
       commandOutputs[name].push({ output, type: "stdout" });
 
       // Check for Turbo cache hits
       if (output.includes("cache hit") || output.includes("FULL TURBO")) {
         status[name].turboCache = true;
       }
     });
 
     // Collect stderr
     proc.stderr.on("data", (data) => {
       commandOutputs[name].push({
         output: data.toString().trim(),
         type: "stderr",
       });
     });
 
     proc.on("close", (code) => {
+      clearTimeout(timeoutId);
       status[name].endTime = Date.now();
       status[name].status = code === 0 ? "success" : "failed";
       printStatus();
 
       resolve(code === 0);
     });
   });
 };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b0d61fc and 3659160.

📒 Files selected for processing (2)
  • packages/style-kit/bin/cli.test.ts
  • scripts/ci.js
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/style-kit/bin/cli.test.ts
🧰 Additional context used
📓 Path-based instructions (1)
scripts/ci.js

📄 CodeRabbit inference engine (CLAUDE.md)

Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Files:

  • scripts/ci.js
🧠 Learnings (3)
📓 Common learnings
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: package.json:19-20
Timestamp: 2025-09-27T20:21:27.195Z
Learning: In the js-style-kit monorepo, the root lint script uses --ignore-pattern to exclude packages, apps, and docs because Turborepo runs individual lint scripts for each workspace. The root lint script is only meant to lint root-level files like scripts and config files, while `turbo run lint` handles workspace linting through the dependsOn: ["^lint"] configuration.
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Use Turborepo to manage the monorepo build pipeline and caching
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to packages/style-kit/bin/index.ts : Provide the CLI entry point at packages/style-kit/bin/index.ts
📚 Learning: 2025-09-27T20:21:53.141Z
Learnt from: drake-nathan
Repo: drake-nathan/js-style-kit PR: 84
File: scripts/ci.js:5-10
Timestamp: 2025-09-27T20:21:53.141Z
Learning: In scripts/ci.js for drake-nathan/js-style-kit: The build command must run before lint/format because the build process generates or modifies files that need to be linted/formatted. This script runs locally only and has specific build->lint dependencies.

Applied to files:

  • scripts/ci.js
📚 Learning: 2025-09-12T02:53:12.206Z
Learnt from: CR
Repo: drake-nathan/js-style-kit PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-09-12T02:53:12.206Z
Learning: Applies to scripts/ci.js : Use scripts/ci.js as the comprehensive CI entry script (format, lint, test, dependency checks, build)

Applied to files:

  • scripts/ci.js
🔇 Additional comments (2)
scripts/ci.js (2)

184-191: Early exit on phase failure is appropriate for this workflow.

The sequential phase execution with early exit (break on first failure) is a good pattern here because Phase 2 depends on Phase 1 completing successfully. This provides fast feedback and avoids running dependent tasks when prerequisites fail.

The trade-off is that developers won't get comprehensive feedback about all issues in a single CI run if Phase 1 fails, but this is acceptable given the build dependencies between phases.


9-11: Phase 1 parallel execution is correct.

Sherif only reads package.json files (inputs: ["**/package.json"]) and produces no outputs, so it safely runs in parallel with build without race conditions. The phase structure is sound: Phase 1 runs independent checks (sherif + build), then Phase 2 validates after build completes.

Comment thread scripts/ci.js
@drake-nathan drake-nathan merged commit e2875d1 into main Jan 11, 2026
4 checks passed
@drake-nathan drake-nathan deleted the optimize-turbo branch January 11, 2026 04:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant