Skip to content

ci: add cross-platform install matrix and API smoke checks#32

Merged
Mehdi-Bl merged 6 commits intomainfrom
feature/os-matrix-install-smoke
Feb 15, 2026
Merged

ci: add cross-platform install matrix and API smoke checks#32
Mehdi-Bl merged 6 commits intomainfrom
feature/os-matrix-install-smoke

Conversation

@Mehdi-Bl
Copy link
Contributor

@Mehdi-Bl Mehdi-Bl commented Feb 15, 2026

Summary

  • add a new cross-platform workflow .github/workflows/install-matrix.yml
  • validate install paths on Linux/macOS/Windows across Python 3.11 and 3.12 (--use-pep517 + fallback pip install -e .)
  • add deterministic API validation in matrix (pytest -m "not e2e" + targeted /health and /v1/models smoke tests)
  • add optional manual live validation job for Claude + Haiku (non-blocking, gated by run_live_claude and ANTHROPIC_API_KEY)
  • replace bash-only mock Claude test binary with a cross-platform launcher in tests/conftest.py
  • remove local deprecation warnings from test runs (declarative_base import and HTTP 422 constant fallback)
  • document matrix/live workflow usage in docs/dev.md

Why

PR #27 highlighted a platform-specific install/runtime regression. This adds a CI guardrail to catch install/API regressions early across supported operating systems.

Validation

  • make lint
  • pytest -q -m "not e2e"
  • make test-no-cov
  • make test
  • make sonar
  • make sonar-cloud (fails locally: missing SONAR_CLOUD_TOKEN in Vault/environment)
  • python -m pip install -e . --use-pep517 && python -m pip check && python -c "import claude_code_api, greenlet, sqlalchemy"
  • python -m pip uninstall -y claude-code-api && python -m pip install -e . && python -m pip check && python -c "import claude_code_api, greenlet, sqlalchemy"

Summary by Sourcery

Add cross-platform CI workflow to validate package installation and API health across OS, Python versions, and install modes, while improving test portability and tightening dependency and validation behavior.

New Features:

  • Introduce an install and API smoke test matrix workflow covering Linux, macOS, Windows, Python 3.11/3.12, and multiple install modes.
  • Add an optional manual live validation job that runs end-to-end tests against a real Claude/Haiku deployment.

Enhancements:

  • Replace the bash-only mock Claude CLI test binary with a cross-platform Python-based launcher for fixtures.
  • Adjust path validation tests to assert normalized real paths instead of hard-coded strings.
  • Relax HTTP 422 status resolution to avoid dependency-specific deprecation warnings while preserving error semantics.
  • Declare greenlet as a runtime dependency and requests as a test dependency to align with actual usage.

CI:

  • Add a GitHub Actions workflow to run cross-platform install checks, deterministic tests, API smoke tests, and optional live live-API validation.

Documentation:

  • Document the new CI install matrix and optional live validation workflow in the developer guide.

@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@sourcery-ai
Copy link

sourcery-ai bot commented Feb 15, 2026

Reviewer's Guide

Adds a cross-platform GitHub Actions workflow to validate installation and API behavior across OSes and Python versions, introduces an optional live Claude/Haiku validation job, replaces the bash-only mock Claude binary with a cross-platform Python-based launcher, fixes validation error status-code handling, adjusts path validation tests, and updates dependencies and developer docs to support the new CI matrix.

Sequence diagram for optional live Claude + Haiku validation job

sequenceDiagram
  actor Dev as Developer
  participant GH as GitHub
  participant WF as Workflow_install_matrix
  participant J1 as Job_install_check
  participant J2 as Job_api_smoke
  participant J3 as Job_live_claude_haiku
  participant API as Claude_Code_API_Server
  participant ClaudeCLI as Claude_CLI
  participant Anth as Anthropic_API

  Dev->>GH: Trigger workflow_dispatch\nrun_live_claude=true\nlive_model=haiku_id
  GH->>WF: Start Install Matrix + API Smoke

  WF->>J1: Run install-check matrix
  J1->>J1: pip install -e . (pep517 or fallback)
  J1->>J1: pip check and import claude_code_api, greenlet, sqlalchemy
  J1-->>WF: Install matrix complete

  WF->>J2: Run api-smoke matrix
  J2->>J2: pip install -e .[test] --use-pep517
  J2->>J2: pytest -m not e2e
  J2->>API: Start FastAPI app for tests
  J2->>API: GET /health and GET /v1/models
  API-->>J2: 200 OK responses
  J2-->>WF: API smoke complete

  WF->>J3: Run live-claude-haiku (manual, continue-on-error)
  J3->>J3: Verify ANTHROPIC_API_KEY secret
  J3->>ClaudeCLI: Install and configure CLI with API key
  J3->>API: Start python -m claude_code_api.main
  J3->>API: Poll GET /health until 200 or timeout
  J3->>ClaudeCLI: Run pytest tests against live model
  ClaudeCLI->>Anth: Call Anthropic model API
  Anth-->>ClaudeCLI: Streaming/completed responses
  ClaudeCLI-->>J3: Exit status for live tests
  J3-->>WF: Job result (non-blocking)
  WF-->>GH: Overall workflow status
Loading

File-Level Changes

Change Details Files
Introduce cross-platform install and API smoke-test workflow in CI, including optional manual live Claude+Haiku validation.
  • Add install-matrix GitHub Actions workflow with OS/Python/install-mode matrix to validate editable installs and imports.
  • Add API smoke-test job running pytest (excluding e2e) plus focused /health and /v1/models tests on all OS/Python combinations.
  • Add manual-only live validation job that runs real Claude CLI against a locally started API using ANTHROPIC_API_KEY, marking failures as non-blocking and uploading logs.
.github/workflows/install-matrix.yml
Make the mock Claude CLI used in tests cross-platform by generating a Python-based launcher with OS-specific wrappers.
  • Extract fixture-rule serialization into a helper for reuse when building the launcher script.
  • Generate a Python runner script that selects a fixture file based on CLI -p prompt content and prints it to stdout, with a --version fast path.
  • Create platform-specific entrypoints: a .cmd wrapper on Windows and a POSIX shell wrapper elsewhere, wiring settings.claude_binary_path to the generated launcher.
tests/conftest.py
Harden validation error handling to always return a stable 422 status code when appropriate, even if newer FastAPI constants are absent.
  • Change the RequestValidationError handler to fall back directly to numeric 422 instead of HTTP_422_UNPROCESSABLE_ENTITY when HTTP_422_UNPROCESSABLE_CONTENT is unavailable.
claude_code_api/main.py
Align path validation tests with realpath behavior to avoid assumptions about exact string paths.
  • Update tests to compare validate_path results to os.path.realpath-constructed expectations for both relative and absolute valid paths.
tests/test_security.py
Ensure required runtime and test dependencies for the new CI matrix are installed explicitly.
  • Add greenlet as a runtime dependency so import checks in the matrix are reliable.
  • Add requests as a test dependency to match usage in the test suite and CI.
pyproject.toml
setup.py
Document the new CI matrix workflow and optional live validation usage for developers.
  • Add a 'CI Matrix Testing' section describing the install/API smoke-test workflow, matrix dimensions, and how to trigger optional live Claude validation.
docs/dev.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist
Copy link

Summary of Changes

Hello @Mehdi-Bl, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances the project's continuous integration by introducing robust cross-platform installation and API smoke tests. The primary goal is to proactively catch platform-specific regressions and ensure consistent behavior across supported operating systems and Python versions, thereby improving the overall stability and reliability of the application.

Highlights

  • New CI Workflow: A new cross-platform workflow, .github/workflows/install-matrix.yml, has been added to the CI pipeline.
  • Cross-Platform Install Validation: The new workflow validates installation paths on Linux, macOS, and Windows across Python versions 3.11 and 3.12, covering both --use-pep517 and fallback pip install -e . methods.
  • API Smoke Checks: Deterministic API validation has been integrated into the matrix, running pytest -m "not e2e" and targeted smoke tests for /health and /v1/models endpoints.
  • Optional Live Validation: An optional, manual live validation job for Claude + Haiku has been added, which is non-blocking and gated by specific inputs and an API key.
  • Cross-Platform Mock Binary: The bash-only mock Claude test binary has been replaced with a cross-platform launcher implemented in tests/conftest.py.
  • Deprecation Warning Removal: Local deprecation warnings related to declarative_base import and HTTP 422 constant fallback have been removed from test runs.
  • Documentation Update: The usage of the new matrix and live validation workflows has been documented in docs/dev.md.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • claude_code_api/core/database.py
    • Refactored declarative_base import to align with SQLAlchemy's updated structure.
  • claude_code_api/main.py
    • Adjusted the fallback constant for HTTP 422 errors to use an integer value.
  • docs/dev.md
    • Documented the new CI matrix testing workflow and its capabilities.
  • tests/conftest.py
    • Added sys import for cross-platform compatibility.
    • Implemented _serialize_fixture_rules to process fixture rules for the mock binary.
    • Developed _create_mock_claude_binary to generate a cross-platform mock Claude CLI launcher.
    • Replaced the bash-only mock Claude binary creation with a Python-based, cross-platform solution.
Ignored Files
  • Ignored by pattern: .github/workflows/** (1)
    • .github/workflows/install-matrix.yml
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@qodo-free-for-open-source-projects

Review Summary by Qodo

Add cross-platform install matrix and API smoke checks

✨ Enhancement 🧪 Tests

Grey Divider

Walkthroughs

Description
• Add cross-platform CI matrix for install validation across Linux/macOS/Windows
• Support Python 3.11 and 3.12 with PEP 517 and fallback install modes
• Implement deterministic API smoke tests for /health and /v1/models endpoints
• Replace bash-only mock Claude binary with cross-platform Python launcher
• Clean up deprecated SQLAlchemy imports and HTTP status code fallbacks
• Document matrix workflow and optional live Claude validation in dev guide
Diagram
flowchart LR
  A["CI Workflow<br/>install-matrix.yml"] --> B["Install Check<br/>3 OS × 2 Python × 2 modes"]
  B --> C["API Smoke Tests<br/>health + models endpoints"]
  C --> D["Optional Live<br/>Claude + Haiku"]
  E["Mock Claude Binary<br/>conftest.py"] --> C
  F["Code Cleanup<br/>database.py + main.py"] --> C
Loading

Grey Divider

File Changes

1. .github/workflows/install-matrix.yml ⚙️ Configuration changes +208/-0

Add comprehensive cross-platform CI matrix workflow

• New workflow file with three jobs: install-check, api-smoke, and live-claude-haiku
• Install-check job validates package installation across 3 OS × 2 Python versions × 2 install modes
• API-smoke job runs deterministic tests and targeted health/models endpoint checks
• Live-claude-haiku job provides optional manual validation with Claude CLI and Anthropic API

.github/workflows/install-matrix.yml


2. tests/conftest.py ✨ Enhancement +92/-37

Replace bash mock binary with cross-platform Python launcher

• Extract mock Claude binary creation into _create_mock_claude_binary() function
• Add _serialize_fixture_rules() helper for fixture rule serialization
• Replace bash-only shell script with cross-platform Python launcher
• Generate platform-specific launchers: .cmd batch file for Windows, shell script for POSIX
• Embed Python runner code directly in launcher for portability

tests/conftest.py


3. claude_code_api/core/database.py 🐞 Bug fix +1/-2

Update SQLAlchemy declarative_base import path

• Move declarative_base import from sqlalchemy.ext.declarative to sqlalchemy.orm
• Consolidate imports on single line with relationship
• Removes deprecated import path that triggers warnings in newer SQLAlchemy versions

claude_code_api/core/database.py


View more (2)
4. claude_code_api/main.py 🐞 Bug fix +1/-5

Simplify HTTP 422 status code handling

• Simplify HTTP 422 status code fallback in validation_exception_handler()
• Replace conditional attribute lookup with direct integer fallback value 422
• Removes reliance on HTTP_422_UNPROCESSABLE_CONTENT constant availability

claude_code_api/main.py


5. docs/dev.md 📝 Documentation +17/-0

Document CI matrix and live validation workflow

• Add new "CI Matrix Testing" section documenting cross-platform workflow
• Document matrix coverage: 3 OS, 2 Python versions, 2 install modes
• Explain deterministic test execution and API smoke checks
• Document optional live validation workflow with manual trigger and configuration

docs/dev.md


Grey Divider

Qodo Logo

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a cross-platform CI testing matrix to validate installation and basic API functionality on Linux, macOS, and Windows. To support this, the test suite's mock claude binary has been refactored from a bash script into a cross-platform Python script. The changes also include minor fixes for deprecation warnings and documentation updates for the new CI workflow. My review focuses on improving the readability and maintainability of the new test helper script. The changes are solid and the move to a cross-platform test mock is a great improvement.

Comment on lines +48 to +85
runner_code = "\n".join(
[
"#!/usr/bin/env python3",
"import sys",
"",
f"DEFAULT_FIXTURE = {str(default_fixture)!r}",
f"FIXTURE_RULES = {serialized_rules!r}",
"",
"def _extract_prompt(args):",
" for idx, value in enumerate(args):",
" if value == '-p' and idx + 1 < len(args):",
" return args[idx + 1]",
" return ''",
"",
"def _resolve_fixture(prompt):",
" prompt_lower = prompt.lower()",
" fixture_path = DEFAULT_FIXTURE",
" for rule in FIXTURE_RULES:",
" if any(match in prompt_lower for match in rule['matches']):",
" fixture_path = rule['fixture_path']",
" return fixture_path",
"",
"def main():",
" args = sys.argv[1:]",
" if args and args[0] == '--version':",
" print('Claude Code 1.0.0')",
" return 0",
" prompt = _extract_prompt(args)",
" fixture_path = _resolve_fixture(prompt)",
" with open(fixture_path, 'r', encoding='utf-8') as handle:",
" sys.stdout.write(handle.read())",
" return 0",
"",
"if __name__ == '__main__':",
" raise SystemExit(main())",
"",
]
)

Choose a reason for hiding this comment

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

medium

For better readability and maintainability, consider using a multiline f-string with textwrap.dedent to define the runner_code. This avoids the need for a list of strings and "\n".join(), making the embedded script look more like a regular Python script. You'll need to add import textwrap at the top of the file for this suggestion to work.

    runner_code = textwrap.dedent(f"""
        #!/usr/bin/env python3
        import sys

        DEFAULT_FIXTURE = {str(default_fixture)!r}
        FIXTURE_RULES = {serialized_rules!r}

        def _extract_prompt(args):
            for idx, value in enumerate(args):
                if value == '-p' and idx + 1 < len(args):
                    return args[idx + 1]
            return ''

        def _resolve_fixture(prompt):
            prompt_lower = prompt.lower()
            fixture_path = DEFAULT_FIXTURE
            for rule in FIXTURE_RULES:
                if any(match in prompt_lower for match in rule['matches']):
                    fixture_path = rule['fixture_path']
            return fixture_path

        def main():
            args = sys.argv[1:]
            if args and args[0] == '--version':
                print('Claude Code 1.0.0')
                return 0
            prompt = _extract_prompt(args)
            fixture_path = _resolve_fixture(prompt)
            with open(fixture_path, 'r', encoding='utf-8') as handle:
                sys.stdout.write(handle.read())
            return 0

        if __name__ == '__main__':
            raise SystemExit(main())
    """)

Comment on lines +96 to +102
launcher_code = "\n".join(
[
"#!/usr/bin/env sh",
f'exec "{sys.executable}" "{runner_path}" "$@"',
"",
]
)

Choose a reason for hiding this comment

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

medium

For improved readability, you can use a multiline f-string to define the POSIX launcher script. This is more concise than joining a list of strings.

    launcher_code = f"""#!/usr/bin/env sh
exec \"{sys.executable}\" \"{runner_path}\" \"$@\"
"""

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 2 issues

Prompt for AI Agents
Please address the comments from this code review:

## Individual Comments

### Comment 1
<location> `.github/workflows/install-matrix.yml:118` </location>
<code_context>
+
+  live-claude-haiku:
+    name: Live Claude + Haiku validation (manual)
+    if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_live_claude && secrets.ANTHROPIC_API_KEY != '' }}
+    runs-on: ubuntu-latest
+    needs: api-smoke
</code_context>

<issue_to_address>
**issue (bug_risk):** The workflow_dispatch input reference is likely incorrect and will prevent this job from running.

For `workflow_dispatch` events, inputs are exposed as `github.event.inputs.<name>`, not `inputs.<name>`. As a result, `inputs.run_live_claude` will always be falsey and this job will never run. You likely want something like:

```yaml
if: >-
  ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.run_live_claude == 'true' && secrets.ANTHROPIC_API_KEY != '' }}
```

(adjust the string comparison if the input is passed differently).
</issue_to_address>

### Comment 2
<location> `.github/workflows/install-matrix.yml:137-138` </location>
<code_context>
+      - name: Install project with test extras
+        run: python -m pip install -e ".[test]" --use-pep517
+
+      - name: Install Claude CLI
+        run: curl -fsSL https://claude.ai/install.sh | bash
+
+      - name: Add Claude CLI path
</code_context>

<issue_to_address>
**🚨 suggestion (security):** Piping curl directly to bash introduces a supply-chain risk.

Using `curl -fsSL … | bash` makes the workflow dependent on executing whatever that endpoint serves at runtime. Where possible, prefer a more controlled install path (e.g., versioned release or package manager) and/or pin via checksum or signature verification so a compromised install endpoint can’t silently impact CI runs.

Suggested implementation:

```
      - name: Install Claude CLI
        env:
          CLAUDE_INSTALL_URL: https://claude.ai/install.sh
          # TODO: Replace this placeholder with the official SHA256 for the installer at CLAUDE_INSTALL_URL
          CLAUDE_INSTALL_SHA256: "<expected-sha256-of-install.sh>"
        run: |
          set -euo pipefail
          curl -fsSL "$CLAUDE_INSTALL_URL" -o /tmp/claude-install.sh

          echo "$CLAUDE_INSTALL_SHA256  /tmp/claude-install.sh" | sha256sum -c -

          bash /tmp/claude-install.sh

```

1. Determine the official SHA256 checksum for the `https://claude.ai/install.sh` script (e.g., from release notes or by downloading the script once in a controlled environment and computing `sha256sum install.sh`).
2. Replace the `"<expected-sha256-of-install.sh>"` placeholder with that exact checksum value so the workflow will fail if the installer content changes unexpectedly.
3. Optionally, you may want to pin `CLAUDE_INSTALL_URL` to a specific versioned installer URL if the project provides one, further reducing the risk of unexpected changes.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +137 to +138
- name: Install Claude CLI
run: curl -fsSL https://claude.ai/install.sh | bash
Copy link

Choose a reason for hiding this comment

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

🚨 suggestion (security): Piping curl directly to bash introduces a supply-chain risk.

Using curl -fsSL … | bash makes the workflow dependent on executing whatever that endpoint serves at runtime. Where possible, prefer a more controlled install path (e.g., versioned release or package manager) and/or pin via checksum or signature verification so a compromised install endpoint can’t silently impact CI runs.

Suggested implementation:

      - name: Install Claude CLI
        env:
          CLAUDE_INSTALL_URL: https://claude.ai/install.sh
          # TODO: Replace this placeholder with the official SHA256 for the installer at CLAUDE_INSTALL_URL
          CLAUDE_INSTALL_SHA256: "<expected-sha256-of-install.sh>"
        run: |
          set -euo pipefail
          curl -fsSL "$CLAUDE_INSTALL_URL" -o /tmp/claude-install.sh

          echo "$CLAUDE_INSTALL_SHA256  /tmp/claude-install.sh" | sha256sum -c -

          bash /tmp/claude-install.sh

  1. Determine the official SHA256 checksum for the https://claude.ai/install.sh script (e.g., from release notes or by downloading the script once in a controlled environment and computing sha256sum install.sh).
  2. Replace the "<expected-sha256-of-install.sh>" placeholder with that exact checksum value so the workflow will fail if the installer content changes unexpectedly.
  3. Optionally, you may want to pin CLAUDE_INSTALL_URL to a specific versioned installer URL if the project provides one, further reducing the risk of unexpected changes.

@qodo-free-for-open-source-projects
Copy link

qodo-free-for-open-source-projects bot commented Feb 15, 2026

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment on lines +89 to +93
if os.name == "nt":
launcher_path = Path(temp_dir) / "claude.cmd"
launcher_code = f'@echo off\r\n"{sys.executable}" "{runner_path}" %*\r\n'
launcher_path.write_text(launcher_code, encoding="utf-8")
return str(launcher_path)

Choose a reason for hiding this comment

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

Action required

1. Windows .cmd exec fails 🐞 Bug ⛯ Reliability

On Windows, the new mock Claude launcher returns a .cmd path, but the app spawns the Claude binary
with asyncio.create_subprocess_exec (no shell). This is likely to fail on windows-latest,
breaking deterministic tests that hit /v1/chat/completions in the new CI matrix.
Agent Prompt
## Issue description
Windows test runs will likely fail because the mock Claude launcher returns a `.cmd` batch script, while the application spawns the Claude binary via `asyncio.create_subprocess_exec` (no shell). Batch scripts generally need a command interpreter (`cmd.exe /c`) to run.

## Issue Context
- The new CI matrix includes `windows-latest`.
- Deterministic tests call `/v1/chat/completions`, which triggers the subprocess spawn.
- `settings.claude_binary_path` may be a `.cmd` on Windows both for the mock and potentially for a real Claude install discovered via PATH.

## Fix Focus Areas
- claude_code_api/core/claude_manager.py[44-105]
- claude_code_api/core/claude_manager.py[355-380]
- claude_code_api/core/claude_manager.py[614-624]
- tests/conftest.py[89-93]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

@Mehdi-Bl Mehdi-Bl marked this pull request as draft February 15, 2026 08:20
@Mehdi-Bl Mehdi-Bl marked this pull request as ready for review February 15, 2026 16:56
@chatgpt-codex-connector
Copy link

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@Mehdi-Bl Mehdi-Bl merged commit 216e948 into main Feb 15, 2026
28 checks passed
@qodo-free-for-open-source-projects

Review Summary by Qodo

Add cross-platform install matrix and API smoke checks with test improvements

✨ Enhancement 🧪 Tests 🐞 Bug fix

Grey Divider

Walkthroughs

Description
• Add cross-platform CI matrix for install validation across Linux/macOS/Windows with Python
  3.11-3.12
• Replace bash-only mock Claude binary with cross-platform Python launcher in tests
• Add deterministic API smoke tests for /health and /v1/models endpoints
• Include optional manual live Claude + Haiku validation job (non-blocking)
• Add explicit greenlet runtime dependency and requests test dependency
• Fix HTTP 422 status code fallback to numeric constant for compatibility
Diagram
flowchart LR
  A["CI Workflow Trigger"] --> B["Install Matrix Job"]
  B --> C["Multi-OS/Python Test"]
  C --> D["Dependency Validation"]
  D --> E["API Smoke Tests"]
  E --> F["Health & Models Check"]
  F --> G["Optional Live Claude"]
  H["Mock Claude Binary"] --> I["Cross-Platform Launcher"]
  I --> J["POSIX & Windows Support"]
Loading

Grey Divider

File Changes

1. .github/workflows/install-matrix.yml ✨ Enhancement +217/-0

Cross-platform install and API smoke test matrix workflow

• New workflow file implementing cross-platform install and API smoke test matrix
• Covers Ubuntu, macOS, Windows with Python 3.11 and 3.12
• Tests both PEP 517 editable and fallback install modes
• Includes deterministic pytest runs and targeted API health/models smoke tests
• Optional manual live Claude + Haiku validation job with ANTHROPIC_API_KEY secret gating

.github/workflows/install-matrix.yml


2. tests/conftest.py ✨ Enhancement +92/-37

Replace bash mock binary with cross-platform Python launcher

• Replace bash-only mock Claude binary with cross-platform Python launcher
• Add _create_mock_claude_binary() function generating Python runner and platform-specific wrapper
• Support both POSIX shell script and Windows batch file launchers
• Serialize fixture rules and embed in generated Python code for portability
• Maintain fixture matching logic across all platforms

tests/conftest.py


3. tests/test_security.py 🐞 Bug fix +6/-2

Make security path assertions cross-platform compatible

• Import os module for cross-platform path handling
• Update path assertions to use os.path.realpath() for normalized comparisons
• Ensure tests work consistently on Windows and POSIX systems

tests/test_security.py


View more (5)
4. claude_code_api/main.py 🐞 Bug fix +1/-5

Fix HTTP 422 status code fallback to numeric constant

• Simplify HTTP 422 status code fallback from status.HTTP_422_UNPROCESSABLE_ENTITY to numeric
 constant 422
• Ensures validation error responses use stable status code even when newer FastAPI/Starlette
 constants unavailable

claude_code_api/main.py


5. claude_code_api/core/database.py 🐞 Bug fix +1/-2

Update declarative_base import to newer SQLAlchemy location

• Move declarative_base import from sqlalchemy.ext.declarative to sqlalchemy.orm
• Consolidate imports on single line with relationship
• Removes deprecation warning from newer SQLAlchemy versions

claude_code_api/core/database.py


6. setup.py Dependencies +2/-0

Add greenlet runtime and requests test dependencies

• Add explicit greenlet>=3.0.0 runtime dependency
• Add requests>=2.31.0 to test extras for HTTP testing support
• Ensures required async runtime dependencies are explicitly declared

setup.py


7. pyproject.toml Dependencies +2/-0

Add greenlet runtime and requests test dependencies

• Add explicit greenlet>=3.0.0 runtime dependency
• Add requests>=2.31.0 to test dependencies
• Mirrors changes in setup.py for consistency

pyproject.toml


8. docs/dev.md 📝 Documentation +17/-0

Document CI matrix and live validation workflow usage

• Document new CI matrix workflow in .github/workflows/install-matrix.yml
• Explain matrix coverage for OS, Python versions, and install modes
• Document optional manual live validation workflow with workflow_dispatch trigger
• Provide instructions for ANTHROPIC_API_KEY secret configuration

docs/dev.md


Grey Divider

Qodo Logo

@Mehdi-Bl Mehdi-Bl deleted the feature/os-matrix-install-smoke branch February 15, 2026 16:56
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@qodo-free-for-open-source-projects

Persistent review updated to latest commit 4c5a2f1

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