name: Tests on: push: pull_request: permissions: contents: read concurrency: group: tests-${{ github.ref }} cancel-in-progress: true jobs: pytest-stubs: name: pytest (ComfyUI + torch stubbed) runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" cache: pip cache-dependency-path: tests/requirements-ci.txt - run: pip install -r tests/requirements-ci.txt - name: Assert torch is NOT installed (this leg tests the stub path) run: python -c "import importlib.util,sys; sys.exit(importlib.util.find_spec('torch') is not None)" # expect: 137 passed, 15 skipped (the requires_torch tests) - run: python -m pytest tests/ -q -ra --ignore=tests/e2e pytest-torch: name: pytest (real CPU torch) runs-on: ubuntu-latest timeout-minutes: 20 env: USCG_REQUIRE_TORCH: "1" steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.12" cache: pip cache-dependency-path: tests/requirements-ci.txt - name: Install CPU torch (latest CPU wheel; the tests only need the torch API, not a specific minor) run: pip install torch --index-url https://download.pytorch.org/whl/cpu - run: pip install -r tests/requirements-ci.txt - run: python -c "import torch; print(torch.__version__); assert hasattr(torch, 'inference_mode')" # expect: 152 passed, 0 skipped - run: python -m pytest tests/ -q -ra --ignore=tests/e2e js-syntax: name: JS syntax runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22 - uses: actions/setup-python@v5 with: python-version: "3.12" - name: web/**/*.js (ES modules) run: | for f in $(find web -name '*.js'); do node --input-type=module --check < "$f" || { echo "FAIL $f"; exit 1; } done - name: resources/*.js (plain scripts) run: | for f in resources/*.js; do node --check "$f" || { echo "FAIL $f"; exit 1; } done - name: Assembled Dashboard page (all logic_*.js share ONE script scope) run: | python - <<'PY' import os, re, sys sys.path.insert(0, os.getcwd()) import html_generator page = html_generator.get_html_template("ci", {"items": []}, "1") bodies = re.findall(r"]*\bsrc=)[^>]*>(.*?)", page, re.S) assert bodies, "no inline