name: Tests permissions: contents: read on: push: branches: [main, develop] pull_request: branches: [main] jobs: test: name: py${{ matrix.python-version }} on ${{ matrix.os }} runs-on: ${{ matrix.os }} strategy: fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - uses: actions/checkout@v7 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v7 with: python-version: ${{ matrix.python-version }} cache: pip cache-dependency-path: requirements-dev.txt # The default Linux torch wheel bundles CUDA (~2.5 GB); tests only need CPU. # Windows and macOS default wheels are already CPU-only. - name: Install CPU torch (Linux) if: runner.os == 'Linux' run: | python -m pip install --upgrade pip pip install torch --index-url https://download.pytorch.org/whl/cpu - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements-dev.txt - name: Run tests run: python -m pytest tests --junitxml=test-results/pytest.xml - name: Upload test results if: always() uses: actions/upload-artifact@v7 with: name: python-${{ matrix.os }}-${{ matrix.python-version }} path: test-results/ if-no-files-found: ignore retention-days: 14 comfyui: name: real ComfyUI compatibility runs-on: ubuntu-latest timeout-minutes: 25 steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-node@v7 with: node-version: "24" cache: npm cache-dependency-path: tools/testing/package-lock.json - name: Read the reviewed runtime pins id: runtime run: | node --input-type=module <<'JS' >> "$GITHUB_OUTPUT" import runtime from './tools/testing/comfyui-runtime.json' with { type: 'json' }; for (const [key, value] of Object.entries(runtime)) console.log(`${key}=${value}`); JS - name: Check out pinned ComfyUI uses: actions/checkout@v7 with: repository: ${{ steps.runtime.outputs.repository }} ref: ${{ steps.runtime.outputs.revision }} path: .ci-comfyui persist-credentials: false - uses: actions/setup-python@v7 with: python-version: ${{ steps.runtime.outputs.pythonVersion }} cache: pip cache-dependency-path: | requirements-dev.txt .ci-comfyui/requirements.txt tools/testing/comfyui-runtime.json - name: Install CPU runtime and test dependencies run: | python -m pip install --upgrade pip pip install "torch==${{ steps.runtime.outputs.torchVersion }}" "torchvision==${{ steps.runtime.outputs.torchvisionVersion }}" --index-url https://download.pytorch.org/whl/cpu pip install -r .ci-comfyui/requirements.txt -r requirements-dev.txt "torch==${{ steps.runtime.outputs.torchVersion }}" "torchvision==${{ steps.runtime.outputs.torchvisionVersion }}" - run: npm ci --prefix tools/testing --ignore-scripts - run: npx --prefix tools/testing playwright install --with-deps chromium - name: Classic and Nodes 2.0 startup and compatibility env: KIKO_COMFY_ROOT: ${{ github.workspace }}/.ci-comfyui KIKO_TEST_PYTHON: python run: npm run --prefix tools/testing test:comfyui - name: Upload real-host reports and startup logs if: always() uses: actions/upload-artifact@v7 with: name: real-comfyui-reports path: tools/testing/test-results/ if-no-files-found: ignore retention-days: 14 coverage: name: coverage gate (85%) runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 with: python-version: "3.12" cache: pip cache-dependency-path: requirements-dev.txt - name: Install dependencies run: | python -m pip install --upgrade pip pip install torch --index-url https://download.pytorch.org/whl/cpu pip install -r requirements-dev.txt # fail_under = 85 lives in pyproject.toml [tool.coverage.report] - name: Measure coverage run: python -m pytest tests --cov=kikotools --cov-report=term-missing --cov-report=html --cov-report=xml - name: Upload coverage reports if: always() uses: actions/upload-artifact@v7 with: name: python-coverage path: | htmlcov/ coverage.xml if-no-files-found: ignore retention-days: 14 js-check: name: frontend syntax runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-node@v7 with: node-version: "24" # Check every shipped module, including files without behavioral tests. - name: Check all shipped JavaScript modules parse run: | shopt -s globstar nullglob for f in web/**/*.js web/**/*.mjs; do node --input-type=module --check < "$f" || { echo "Syntax error in $f"; exit 1; } done frontend: name: frontend workflows and coverage runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 with: python-version: "3.12" cache: pip cache-dependency-path: requirements-dev.txt - name: Install Python test dependencies run: | python -m pip install --upgrade pip pip install torch --index-url https://download.pytorch.org/whl/cpu pip install -r requirements-dev.txt - uses: actions/setup-node@v7 with: node-version: "24" cache: npm cache-dependency-path: tools/testing/package-lock.json - run: npm ci --prefix tools/testing --ignore-scripts - run: npx --prefix tools/testing playwright install --with-deps chromium firefox webkit - name: JavaScript regressions, Chromium workflows, and coverage gate run: npm run --prefix tools/testing test:coverage - name: Firefox and WebKit workflows run: npm run --prefix tools/testing test:browser -- --project firefox --project webkit - name: Upload frontend reports if: always() uses: actions/upload-artifact@v7 with: name: frontend-test-reports path: | tools/testing/test-results/ coverage/js/ !coverage/js/raw/ if-no-files-found: ignore retention-days: 14