Skip to content

feat: add CI pipeline, pre-commit hooks, Biome config, and test suite#654

Open
neuron-tech-ai wants to merge 2 commits into
jamiepine:mainfrom
neuron-tech-ai:feat/ci-and-tooling
Open

feat: add CI pipeline, pre-commit hooks, Biome config, and test suite#654
neuron-tech-ai wants to merge 2 commits into
jamiepine:mainfrom
neuron-tech-ai:feat/ci-and-tooling

Conversation

@neuron-tech-ai
Copy link
Copy Markdown

@neuron-tech-ai neuron-tech-ai commented May 14, 2026

Sets up the foundational development infrastructure that was missing:

  • GitHub Actions CI — runs on every PR: Python lint (ruff), type check (pyright), frontend lint (biome), Rust clippy, and the test suite
  • Pre-commit hooks — enforces the same checks locally before commit so CI doesn't catch things that could have been caught earlier
  • Biome config — consistent JS/TS formatting and linting rules
  • Unit + integration test structure — establishes the test layout with working examples; gives future contributors a clear pattern to follow

The goal is to make it hard to accidentally merge broken or inconsistently formatted code.

Summary by CodeRabbit

  • New Features

    • Added frontend test automation using Vitest with coverage support and watch mode.
    • Introduced comprehensive test suites for history search, upload limits, and audio formatting.
  • Documentation

    • Updated contributing guide with clearer setup instructions, OS-specific tooling commands, and expanded testing guidance.
  • Chores

    • Expanded CI/CD pipeline into separate frontend, backend, and Rust jobs with optimized caching.
    • Added Makefile and pre-commit hooks for streamlined development workflows.
    • Updated project configuration files (Biome, package.json, Vitest) to support testing infrastructure.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

Warning

Rate limit exceeded

@neuron-tech-ai has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 3 minutes and 45 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a8830b2-e38f-4417-9574-e9dd1b82e980

📥 Commits

Reviewing files that changed from the base of the PR and between 3344f03 and 594f17a.

📒 Files selected for processing (3)
  • .github/workflows/ci.yml
  • Makefile
  • app/src/__tests__/audio.test.ts
📝 Walkthrough

Walkthrough

This PR establishes comprehensive testing infrastructure for the voicebox project by adding Vitest for frontend tests, expanding backend test coverage with fixtures and multiple test modules, implementing automated CI/CD workflows, and providing cross-platform developer environment setup tools—enabling consistent testing, code quality gates, and reproducible development across the team.

Changes

Testing Infrastructure and Development Workflows

Layer / File(s) Summary
Frontend testing infrastructure with Vitest
vitest.config.ts, app/src/__tests__/audio.test.ts, app/src/__tests__/format.test.ts, package.json, biome.json
Vitest configuration with @ path alias, test discovery for app/src and web/src workspaces, and new utility test suites for audio and formatting functions; package.json adds test, test:ci, test:watch scripts and @vitest/coverage-v8 dependency; Biome rules tuned for test contexts.
Backend test fixtures and pytest configuration
backend/tests/conftest.py, backend/tests/integration/conftest.py, backend/pyproject.toml
Pytest fixtures provide in-memory SQLite engines with seeded data (voice profiles, generations), per-test session management with rollback cleanup, and async test helpers; explicit unit and integration marker declarations avoid pytest warnings; expanded per-file linting rules.
Backend unit and integration test modules
backend/tests/test_history.py, backend/tests/integration/test_history_api.py, backend/tests/unit/test_history_search.py, backend/tests/test_uploads.py, backend/tests/unit/test_upload_limits.py, backend/tests/test_generation_download.py, backend/tests/test_whisper_download.py, backend/tests/test_qwen_download.py, backend/tests/test_refinement_collapse.py, backend/tests/test_refinement_samples.py, backend/tests/test_*_*.py (various cleanup updates)
Comprehensive test coverage for history service (listing, pagination, search with LIKE-metacharacter escaping), upload size enforcement across capture/profile/history, refinement collapse word/character-level detection, and download monitoring via SSE progress tracking; includes type hint and import cleanup throughout.
CI/CD workflows and pre-commit gates
.github/workflows/ci.yml, .pre-commit-config.yaml
GitHub Actions split into three parallel jobs: frontend-ci (Biome lint/format, TypeScript check, Vitest), backend-ci (Ruff lint/format, pytest unit tests), and rust-check (cargo check/clippy); pre-commit hooks enforce Ruff, Biome, pytest gates, and general repo hygiene (whitespace, merge conflicts, large files).
Developer environment and setup tools
Makefile, Brewfile, justfile, CONTRIBUTING.md
New Makefile provides cross-platform system setup (Homebrew/apt/dnf/pacman), Python venv + Node + Rust installation, parallel dev workflows (dev, dev-backend, dev-web), build/test/lint aggregation, pre-commit hook management, and cleanup tasks; Brewfile documents macOS dependencies; Justfile updated with platform-aware MLX/Linux deps and test-frontend/test-all targets; CONTRIBUTING.md expanded with setup steps and testing guidance for multiple OS.
Type hint modernization and code cleanup
backend/tests/test_all_models_e2e.py, backend/tests/test_personality_samples.py, backend/tests/test_refinement_samples.py, backend/tests/test_progress.py, and related files
Systematic update across test files replacing Optional[X] with PEP 604 union syntax (`X

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • jamiepine/voicebox#530: Edits the same test file (backend/tests/test_offline_patch.py) to cover HuggingFace offline mode behavior.

Suggested reviewers

  • rhmod09-dev

Poem

🐰 Testing the voicebox with vigor and grace,
CI gates now run at a brisk, steady pace,
From frontend to backend, the fixtures align,
With Vitest and pytest, the coverage will shine!
~ 🐇✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 46.04% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely summarizes the main changes: adding CI pipeline, pre-commit hooks, Biome config, and test suite infrastructure.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
backend/tests/test_all_models_e2e.py (1)

180-205: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Avoid returning before cleanup in ServerProcess.stop().

At Line 183-Line 184, stop() returns immediately if the child already exited, which skips reader-thread join and log-file close. That can truncate logs and leak file handles.

Suggested fix
 def stop(self) -> None:
     if self.proc is None:
         return
-    if self.proc.poll() is not None:
-        return
-    try:
-        if platform.system() == "Windows":
-            subprocess.run(
-                ["taskkill", "/F", "/T", "/PID", str(self.proc.pid)],
-                capture_output=True,
-            )
-        else:
-            self.proc.send_signal(signal.SIGTERM)
-    except Exception as e:
-        print(f"[shutdown] signal failed: {e}", flush=True)
-    try:
-        self.proc.wait(timeout=10)
-    except subprocess.TimeoutExpired:
-        print("[shutdown] server didn't exit cleanly, killing", flush=True)
-        self.proc.kill()
-        with contextlib.suppress(subprocess.TimeoutExpired):
-            self.proc.wait(timeout=5)
+    if self.proc.poll() is None:
+        try:
+            if platform.system() == "Windows":
+                subprocess.run(
+                    ["taskkill", "/F", "/T", "/PID", str(self.proc.pid)],
+                    capture_output=True,
+                )
+            else:
+                self.proc.send_signal(signal.SIGTERM)
+        except Exception as e:
+            print(f"[shutdown] signal failed: {e}", flush=True)
+        try:
+            self.proc.wait(timeout=10)
+        except subprocess.TimeoutExpired:
+            print("[shutdown] server didn't exit cleanly, killing", flush=True)
+            self.proc.kill()
+            with contextlib.suppress(subprocess.TimeoutExpired):
+                self.proc.wait(timeout=5)
     if self._reader_thread is not None:
         self._reader_thread.join(timeout=2)
     with contextlib.suppress(Exception):
         self._log_fh.close()
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_all_models_e2e.py` around lines 180 - 205, The stop method
in ServerProcess.stop currently returns early when self.proc.poll() is not None,
skipping reader-thread join and log-file close; change the flow so you only
return immediately if self.proc is None, but if self.proc has already exited
(self.proc.poll() is not None) proceed to join self._reader_thread (if set) and
close self._log_fh (with contextlib.suppress) instead of returning; only run the
shutdown/kill logic (taskkill/send_signal/wait/kill) when the process is still
running. Ensure references to self.proc, self._reader_thread, and self._log_fh
in the method are preserved and reused in the revised control flow.
CONTRIBUTING.md (1)

274-280: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Python formatter guidance is outdated.

Line 279 still points to Black, but this tooling setup enforces Ruff formatting. Aligning this avoids contributor confusion.

Suggested patch
 - Follow PEP 8 style guide
 - Use type hints
 - Use async/await for I/O operations
-- Format with Black (if configured)
+- Format with Ruff (`ruff format`)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CONTRIBUTING.md` around lines 274 - 280, Update the Python formatter guidance
in the "Python" section to remove the outdated reference to Black and replace it
with the current enforced formatter (Ruff), i.e., edit the bullet that says
"Format with Black (if configured)" to mention Ruff (and any config/tooling
notes) so contributors know to use Ruff for formatting and linting; update
nearby wording if needed to reflect Ruff's usage alongside Black's predecessor.
.pre-commit-config.yaml (1)

30-73: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Pre-commit is missing Python typecheck parity.

If local gates are meant to mirror CI quality checks, add a Pyright hook; otherwise Python type regressions can pass local hooks.

Suggested hook addition
   - repo: local
     hooks:
+      - id: pyright
+        name: Python typecheck (pyright)
+        language: system
+        entry: bash -c 'cd backend && pyright'
+        pass_filenames: false
+        types: [python]
+
       - id: biome-check
         name: Biome lint + format
         language: system
         entry: bun run check:fix
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.pre-commit-config.yaml around lines 30 - 73, Add a Pyright local hook to
the existing "Tests" local repo hooks to enforce Python typechecks locally:
create a new hook with id "pyright" (name like "Python typecheck (pyright)"),
language "system", entry that runs pyright in the backend (e.g., change
directory to backend and run the pyright CLI), set pass_filenames: false, types
or files to target Python files (e.g., types: [python] or files: \.py$), and
include it alongside the existing pytest-unit/pytest-integration hooks
(optionally as a pre-commit stage) so local pre-commit mirrors the CI typecheck.
🧹 Nitpick comments (4)
backend/tests/test_history.py (2)

30-30: ⚡ Quick win

Remove unused tmp_path parameter.

The fixture uses an in-memory SQLite database and does not write to tmp_path. Remove the parameter to clarify the fixture's requirements.

♻️ Proposed fix
 `@pytest.fixture`
-def db(tmp_path):
+def db():
     """In-memory SQLite session pre-loaded with a profile and some generations."""
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_history.py` at line 30, The fixture function db in
backend/tests/test_history.py currently declares an unused tmp_path parameter;
remove tmp_path from the db fixture signature (def db(...)) so the fixture uses
only the in-memory SQLite setup it needs, and adjust any references if they
explicitly pass tmp_path (none expected) so tests continue to request the db
fixture without the unused parameter.

86-90: ⚡ Quick win

Strengthen the assertion to be deterministic.

The test knows exactly which row matches: only "Hello world" (g1) contains "hello" case-insensitively. Use assert result.total == 1 instead of >= 1 for a more precise test.

♻️ Proposed fix
     def test_case_insensitive_via_like(self, db):
         # SQLite LIKE is case-insensitive for ASCII by default.
         result = _list_generations(HistoryQuery(search="hello"), db)
-        assert result.total >= 1
+        assert result.total == 1
+        assert result.items[0].id == "g1"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/test_history.py` around lines 86 - 90, Update the
test_case_insensitive_via_like test to make the assertion deterministic: replace
the loose assertion "assert result.total >= 1" with a strict equality "assert
result.total == 1" so the test verifies that only the known row (the "Hello
world" generation returned by _list_generations invoked with
HistoryQuery(search=\"hello\")) matches; locate the assertion in
test_case_insensitive_via_like and change the comparator accordingly.
backend/tests/integration/test_history_api.py (1)

156-165: Clarify what the test actually verifies.

The docstring states "this test additionally confirms that adding GenerationVersion rows doesn't change the total query count" but the test doesn't actually measure query count. It only verifies that version fields are populated correctly. Consider updating the docstring to accurately reflect what is tested:

📝 Suggested clarification
     def test_batch_version_load_no_queries_per_item(self, seeded_db):
-        """Versions for all items are loaded in one query, not N queries.
+        """Versions are populated for all items without N+1 behavior.
 
-        We test this indirectly: if the N+1 is re-introduced the JOIN would
-        fail for items whose versions are loaded one-by-one and the profile_name
-        field would be empty or None.  The profile_name assertion in
-        test_profile_name_populated_for_every_item already catches that;
-        this test additionally confirms that adding GenerationVersion rows
-        doesn't change the total query count from the caller's perspective.
+        If N+1 queries were re-introduced, version data might not be populated
+        correctly. This test verifies that after adding GenerationVersion rows,
+        the versions are correctly loaded and attached to their parent generations.
         """
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/integration/test_history_api.py` around lines 156 - 165, Update
the docstring for test_batch_version_load_no_queries_per_item to accurately
describe its assertions: state that the test verifies that version-related
fields (e.g., profile_name) are populated for every item even when
GenerationVersion rows exist and that adding those rows does not break the JOIN
behavior, rather than claiming it measures or confirms the total SQL query
count; reference the test name test_profile_name_populated_for_every_item and
the GenerationVersion rows in the description so readers understand the
relationship between these tests.
backend/tests/unit/test_history_search.py (1)

30-30: ⚡ Quick win

Remove unused tmp_path parameter.

The fixture creates an in-memory SQLite database ("sqlite:///:memory:") and never uses tmp_path. Remove the parameter to keep the signature clean.

♻️ Proposed fix
 `@pytest.fixture`
-def db(tmp_path):
+def db():
     """In-memory SQLite session pre-loaded with a profile and test rows."""
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/tests/unit/test_history_search.py` at line 30, The fixture function
db currently accepts an unused tmp_path parameter; update the fixture signature
by removing the tmp_path parameter from the db fixture definition (the function
named db) and any corresponding references in its usage so it only creates the
in-memory SQLite engine ("sqlite:///:memory:") and returns the session/engine as
before; ensure any tests or conftest references that call db as a fixture do not
expect tmp_path to be provided.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 73-108: The backend CI job lacks a Python typecheck step; add a
new step named "Typecheck (pyright)" in the backend-ci job (near the existing
"Lint (ruff)" and "Run tests (pytest)" steps) that installs pyright (e.g., npm
install -g pyright or pip install pyright) and runs the type checker in the
backend working-directory (run: pyright --project . or simply pyright) so static
typing is enforced as part of CI.

In `@app/src/__tests__/audio.test.ts`:
- Around line 19-24: The test title and assertion disagree: the test calls
createAudioUrl('xyz', 'http://localhost:17493/') and expects a double slash, so
rename the test description to match that asserted behavior (e.g., "does
double-slash when serverUrl has a trailing slash") or alternatively change the
expectation to the non-double-slash URL; locate the test in
app/src/__tests__/audio.test.ts around the it(...) that references
createAudioUrl and update the string title to reflect the actual expectation.

In `@Makefile`:
- Around line 63-66: The `install-system-linux` Makefile target may call `cargo`
immediately after running rustup, but the new cargo bin directory (~/.cargo/bin)
isn't in PATH until the current shell sources the environment, so the `cargo
install just` line can fail; update the target so that after running rustup you
source the cargo env (e.g. . "$HOME/.cargo/env" or source "$HOME/.cargo/env") in
the same shell session before invoking `cargo install just` (or prepend
PATH="$HOME/.cargo/bin:$PATH" for that command), ensuring the `cargo install
just` invocation in the Makefile uses the environment change in the same shell.

---

Outside diff comments:
In @.pre-commit-config.yaml:
- Around line 30-73: Add a Pyright local hook to the existing "Tests" local repo
hooks to enforce Python typechecks locally: create a new hook with id "pyright"
(name like "Python typecheck (pyright)"), language "system", entry that runs
pyright in the backend (e.g., change directory to backend and run the pyright
CLI), set pass_filenames: false, types or files to target Python files (e.g.,
types: [python] or files: \.py$), and include it alongside the existing
pytest-unit/pytest-integration hooks (optionally as a pre-commit stage) so local
pre-commit mirrors the CI typecheck.

In `@backend/tests/test_all_models_e2e.py`:
- Around line 180-205: The stop method in ServerProcess.stop currently returns
early when self.proc.poll() is not None, skipping reader-thread join and
log-file close; change the flow so you only return immediately if self.proc is
None, but if self.proc has already exited (self.proc.poll() is not None) proceed
to join self._reader_thread (if set) and close self._log_fh (with
contextlib.suppress) instead of returning; only run the shutdown/kill logic
(taskkill/send_signal/wait/kill) when the process is still running. Ensure
references to self.proc, self._reader_thread, and self._log_fh in the method are
preserved and reused in the revised control flow.

In `@CONTRIBUTING.md`:
- Around line 274-280: Update the Python formatter guidance in the "Python"
section to remove the outdated reference to Black and replace it with the
current enforced formatter (Ruff), i.e., edit the bullet that says "Format with
Black (if configured)" to mention Ruff (and any config/tooling notes) so
contributors know to use Ruff for formatting and linting; update nearby wording
if needed to reflect Ruff's usage alongside Black's predecessor.

---

Nitpick comments:
In `@backend/tests/integration/test_history_api.py`:
- Around line 156-165: Update the docstring for
test_batch_version_load_no_queries_per_item to accurately describe its
assertions: state that the test verifies that version-related fields (e.g.,
profile_name) are populated for every item even when GenerationVersion rows
exist and that adding those rows does not break the JOIN behavior, rather than
claiming it measures or confirms the total SQL query count; reference the test
name test_profile_name_populated_for_every_item and the GenerationVersion rows
in the description so readers understand the relationship between these tests.

In `@backend/tests/test_history.py`:
- Line 30: The fixture function db in backend/tests/test_history.py currently
declares an unused tmp_path parameter; remove tmp_path from the db fixture
signature (def db(...)) so the fixture uses only the in-memory SQLite setup it
needs, and adjust any references if they explicitly pass tmp_path (none
expected) so tests continue to request the db fixture without the unused
parameter.
- Around line 86-90: Update the test_case_insensitive_via_like test to make the
assertion deterministic: replace the loose assertion "assert result.total >= 1"
with a strict equality "assert result.total == 1" so the test verifies that only
the known row (the "Hello world" generation returned by _list_generations
invoked with HistoryQuery(search=\"hello\")) matches; locate the assertion in
test_case_insensitive_via_like and change the comparator accordingly.

In `@backend/tests/unit/test_history_search.py`:
- Line 30: The fixture function db currently accepts an unused tmp_path
parameter; update the fixture signature by removing the tmp_path parameter from
the db fixture definition (the function named db) and any corresponding
references in its usage so it only creates the in-memory SQLite engine
("sqlite:///:memory:") and returns the session/engine as before; ensure any
tests or conftest references that call db as a fixture do not expect tmp_path to
be provided.
🪄 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: 3db625be-0c04-4229-addf-8b996b3433f6

📥 Commits

Reviewing files that changed from the base of the PR and between b35b909 and 3344f03.

📒 Files selected for processing (34)
  • .github/workflows/ci.yml
  • .pre-commit-config.yaml
  • Brewfile
  • CONTRIBUTING.md
  • Makefile
  • app/src/__tests__/audio.test.ts
  • app/src/__tests__/format.test.ts
  • backend/pyproject.toml
  • backend/tests/conftest.py
  • backend/tests/integration/__init__.py
  • backend/tests/integration/conftest.py
  • backend/tests/integration/test_history_api.py
  • backend/tests/test_all_models_e2e.py
  • backend/tests/test_audio_preprocess.py
  • backend/tests/test_cors.py
  • backend/tests/test_generation_download.py
  • backend/tests/test_history.py
  • backend/tests/test_offline_guard.py
  • backend/tests/test_offline_patch.py
  • backend/tests/test_personality_samples.py
  • backend/tests/test_profile_duplicate_names.py
  • backend/tests/test_progress.py
  • backend/tests/test_qwen_download.py
  • backend/tests/test_refinement_collapse.py
  • backend/tests/test_refinement_samples.py
  • backend/tests/test_uploads.py
  • backend/tests/test_whisper_download.py
  • backend/tests/unit/__init__.py
  • backend/tests/unit/test_history_search.py
  • backend/tests/unit/test_upload_limits.py
  • biome.json
  • justfile
  • package.json
  • vitest.config.ts
💤 Files with no reviewable changes (1)
  • backend/tests/test_refinement_collapse.py

Comment thread .github/workflows/ci.yml
Comment thread app/src/__tests__/audio.test.ts Outdated
Comment thread Makefile
- Add pyright typecheck step to backend-ci job
- Ensure $HOME/.cargo/bin is on PATH before invoking cargo after rustup install
- Rename misleading test case description to match asserted double-slash behavior
@neuron-tech-ai
Copy link
Copy Markdown
Author

Addressed all three CodeRabbit review comments:

  1. Missing pyright typecheck gate: Added pyright to the pip install step and a new "Typecheck (pyright)" step in backend-ci after the ruff lint/format checks.

  2. Cargo unavailable after rustup install: Updated install-system-linux Makefile target to export $HOME/.cargo/bin to PATH and verify cargo is accessible before invoking cargo install just.

  3. Misleading test case name: Renamed the test to 'double-slashes when serverUrl has a trailing slash (documents current behavior)' to match the actual assertion.

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