diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 0000000..c828abc --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,135 @@ +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 (same minor as the GPU box) + run: pip install "torch==2.13.*" --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