From e6b693959c41264573021480da0d315b96c77fce Mon Sep 17 00:00:00 2001 From: RDCLder Date: Thu, 5 Nov 2026 16:22:36 -0600 Subject: [PATCH] Add CI: lint and tests on Python 3.11 and 3.12, viewer and wheel build The Python job checks that uv.lock matches pyproject.toml, then installs the locked versions with the CPU build of torch, so runners skip about 3 GB of CUDA packages. ffmpeg is installed so the rotation test runs. The opt-in real-model test stays skipped. The second job builds and type-checks the viewer, builds the wheel, fails if the wheel lacks the viewer, and lints the viewer source. Signed-off-by: RDCLder --- .github/workflows/ci.yml | 78 ++++++++++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 80 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9a00031 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,78 @@ +name: CI + +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +jobs: + python: + name: Python ${{ matrix.python }} + runs-on: ubuntu-latest + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + python: ["3.11", "3.12"] + steps: + - uses: actions/checkout@v7.0.1 + + - uses: astral-sh/setup-uv@v10.3.3 + with: + version: "0.13.6" + python-version: ${{ matrix.python }} + + - name: Check the lockfile matches pyproject.toml + run: uv lock --check + + # The locked Linux torch pulls about 3 GB of CUDA packages that a CI runner cannot use. + # Install the CPU build of torch, with every other package pinned to the version in uv.lock. + - name: Install locked versions (CPU torch) + run: | + uv export --frozen --no-hashes --no-emit-project -o "$RUNNER_TEMP/constraints.txt" + uv venv + uv pip install --torch-backend cpu -c "$RUNNER_TEMP/constraints.txt" -e . --group dev + + # The rotation test writes rotation metadata with the ffmpeg CLI. + - name: Install ffmpeg + run: sudo apt-get update -q && sudo apt-get install -y -q ffmpeg + + - name: Lint + run: | + uv run --no-sync ruff check src tests + uv run --no-sync ruff format --check src tests + + - name: Test + run: uv run --no-sync pytest -q -rs + + viewer-and-wheel: + name: Viewer and wheel + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@v7.0.1 + + - uses: actions/setup-node@v7.1.0 + with: + node-version: 24 + cache: npm + cache-dependency-path: web/package-lock.json + + - uses: astral-sh/setup-uv@v10.3.3 + with: + version: "0.13.6" + + # Installs and type-checks the viewer, builds it and the wheel, and fails if the wheel lacks it. + - name: Build + run: ./scripts/build.sh + + - name: Lint viewer + working-directory: web + run: npx oxlint src diff --git a/README.md b/README.md index eb9d42b..9f3e0ae 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # jepa-scope +[![CI](https://github.com/ryangswe/jepa-scope/actions/workflows/ci.yml/badge.svg)](https://github.com/ryangswe/jepa-scope/actions/workflows/ci.yml) + jepa-scope shows you what a JEPA video encoder sees. Point it at a video and it opens a local viewer with the model's patch features drawn over the picture, plus a timeline of how surprised the model was by each moment. It runs Meta's pre-trained V-JEPA 2 on a laptop, so you need no training run, no