diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7ccffcb8..14933d26 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,9 +8,10 @@ on: jobs: test: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} strategy: matrix: + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.10", "3.11", "3.12", "3.13"] steps: @@ -37,10 +38,11 @@ jobs: fail_ci_if_error: false test-e2e: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} needs: test # Run after unit tests pass strategy: matrix: + os: [ubuntu-latest, macos-latest, windows-latest] python-version: ["3.10", "3.11", "3.12", "3.13"] steps: @@ -51,11 +53,20 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install Claude Code + - name: Install Claude Code (Linux/macOS) + if: runner.os == 'Linux' || runner.os == 'macOS' run: | curl -fsSL https://claude.ai/install.sh | bash echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Install Claude Code (Windows) + if: runner.os == 'Windows' + run: | + irm https://claude.ai/install.ps1 | iex + $claudePath = "$env:USERPROFILE\.local\bin" + echo "$claudePath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + shell: pwsh + - name: Verify Claude Code installation run: claude -v @@ -85,11 +96,20 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install Claude Code + - name: Install Claude Code (Linux) + if: runner.os == 'Linux' run: | curl -fsSL https://claude.ai/install.sh | bash echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Install Claude Code (Windows) + if: runner.os == 'Windows' + run: | + irm https://claude.ai/install.ps1 | iex + $claudePath = "$env:USERPROFILE\.local\bin" + echo "$claudePath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + shell: pwsh + - name: Verify Claude Code installation run: claude -v @@ -98,9 +118,22 @@ jobs: python -m pip install --upgrade pip pip install -e . - - name: Run example scripts + - name: Run example scripts (Linux) + if: runner.os == 'Linux' env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} run: | python examples/quick_start.py timeout 120 python examples/streaming_mode.py all + + - name: Run example scripts (Windows) + if: runner.os == 'Windows' + env: + ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }} + run: | + python examples/quick_start.py + $job = Start-Job { python examples/streaming_mode.py all } + Wait-Job $job -Timeout 120 | Out-Null + Stop-Job $job + Receive-Job $job + shell: pwsh diff --git a/e2e-tests/test_agents_and_settings.py b/e2e-tests/test_agents_and_settings.py index 678ea819..6e040664 100644 --- a/e2e-tests/test_agents_and_settings.py +++ b/e2e-tests/test_agents_and_settings.py @@ -1,5 +1,7 @@ """End-to-end tests for agents and setting sources with real Claude API calls.""" +import asyncio +import sys import tempfile from pathlib import Path @@ -80,6 +82,10 @@ async def test_setting_sources_default(): ), f"outputStyle should be 'default', got: {output_style}" break + # On Windows, wait for file handles to be released before cleanup + if sys.platform == "win32": + await asyncio.sleep(0.5) + @pytest.mark.e2e @pytest.mark.asyncio @@ -120,6 +126,10 @@ async def test_setting_sources_user_only(): ), f"testcmd should NOT be available with user-only sources, got: {commands}" break + # On Windows, wait for file handles to be released before cleanup + if sys.platform == "win32": + await asyncio.sleep(0.5) + @pytest.mark.e2e @pytest.mark.asyncio @@ -152,4 +162,8 @@ async def test_setting_sources_project_included(): assert ( output_style == "local-test-style" ), f"outputStyle should be from local settings, got: {output_style}" - break \ No newline at end of file + break + + # On Windows, wait for file handles to be released before cleanup + if sys.platform == "win32": + await asyncio.sleep(0.5) \ No newline at end of file