LΓͺ Phi Nam
Deploy to HF Space
94004a2
Raw
History Blame Contribute Delete
9.18 kB
# PR-gated continuous integration β€” runs backend pytest + frontend node:test
# + TypeScript typecheck on every pull request and push to main. Keeps the
# heavy 4-platform Tauri bundle off this path (that's release.yml on tag
# push) so PRs turn around in a few minutes instead of ~40.
name: CI
on:
pull_request:
branches: [main]
push:
branches: [main]
workflow_dispatch:
permissions:
contents: read
env:
# Run all JavaScript actions on Node 24 (GH deprecates Node 20 in Sep 2026).
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true
jobs:
test:
name: Tests (backend + frontend)
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
# enable-cache persists ~/.cache/uv across runs, keyed on uv.lock β€”
# turns `uv sync` from ~45 s cold to ~5 s warm.
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
# Node 22 is needed for --experimental-strip-types so node:test can
# import .ts files directly from frontend/src/api/*.
- name: Setup Node 22
uses: actions/setup-node@v4
with:
node-version: '22'
- name: Setup Bun
uses: oven-sh/setup-bun@v1
# apt install ffmpeg is ~30 s every run; cache the resolved .debs.
- name: System deps (ffmpeg)
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: ffmpeg
version: 1.0
- name: Install Python deps
# `--all-extras` installs optional engine deps (e.g. `supertonic`)
# so their tests can exercise the real import path, not the
# "package not installed" fallback. Smoke job below stays on bare
# `uv sync` because smoke only hits /health + fixture profiles.
run: uv sync --all-extras
- name: Run pytest
run: uv run pytest tests/ -q --tb=short
# Docs-drift CI gate (Phase 1 INST-06). The validator extracts code
# blocks tagged `<!-- validate -->` from docs/install/*.md and asserts
# each line appears in scripts/desktop-prod.sh after normalisation.
# Its own correctness is enforced by tests/scripts/test_validate_install_docs.py
# (checker B-5) β€” those tests run in the previous step.
- name: Validate install docs against desktop-prod.sh
run: python scripts/validate-install-docs.py
# `backend/tests/` stubs core.config in sys.modules to avoid the heavy
# main app import chain β€” that pollutes import state for other modules,
# so it runs in its own pytest session to stay isolated from tests/.
- name: Run pytest (backend/tests, isolated)
run: uv run pytest backend/tests/ -q --tb=short
# Cache ~/.bun/install/cache keyed on bun.lock β€” `bun install` drops
# from ~15 s cold to near-instant on warm cache.
- name: Cache bun deps
uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lock', 'bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install frontend deps
working-directory: frontend
run: bun install
# checkJs is true in tsconfig for IDE feedback, but 947 pre-existing
# JS errors remain. Override to false in CI so only .ts files block.
# Sourced from `typecheck:ci` in frontend/package.json so the release
# workflow runs an identical command β€” drift broke v0.3.x release runs.
- name: Frontend typecheck
working-directory: frontend
run: bun run typecheck:ci
- name: Run Vitest (frontend)
working-directory: frontend
run: bunx vitest run
# Legacy node:test runner for tests/frontend/*.test.mjs
- name: Run frontend node:test (legacy)
working-directory: frontend
run: node --experimental-strip-types --no-warnings --test ../tests/frontend/*.test.mjs
# ── Cross-platform Tauri shell check ────────────────────────────────────
# Catches platform-specific Rust regressions on PR (cfg(target_os=...)
# gates, missing Windows/macOS deps, etc.) without spending the 15+ min
# per-platform that a full `tauri build` takes. `cargo check` is the
# lightest gate that exercises type-checking + linking for each target.
# Full bundling stays in release.yml on tag push.
tauri-cross-platform:
name: Tauri shell check (${{ matrix.label }})
needs: test
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
label: macOS
rust_target: aarch64-apple-darwin
- os: windows-2022
label: Windows
rust_target: x86_64-pc-windows-msvc
- os: ubuntu-22.04
label: Linux
rust_target: x86_64-unknown-linux-gnu
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Setup Rust (stable)
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.rust_target }}
# Per-target cache key so we don't conflict with the release matrix.
- name: Rust cache
uses: Swatinem/rust-cache@v2
with:
workspaces: frontend/src-tauri -> target
key: ${{ matrix.rust_target }}-check
- name: Setup Bun
uses: oven-sh/setup-bun@v1
# Linux is the only host with non-trivial Tauri build deps β€”
# webkit2gtk + libayatana-appindicator + xdo. Mirror release.yml.
- name: Linux system deps
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
build-essential curl wget file libxdo-dev libssl-dev \
libayatana-appindicator3-dev librsvg2-dev \
libasound2-dev
- name: Cache bun deps
uses: actions/cache@v4
with:
path: ~/.bun/install/cache
key: ${{ runner.os }}-bun-${{ hashFiles('frontend/bun.lock', 'bun.lock') }}
restore-keys: |
${{ runner.os }}-bun-
- name: Install frontend deps
working-directory: frontend
run: bun install
# tauri-build's setup hook reads tauri.conf.json's `frontendDist`
# ("../dist"), which only exists after a frontend build. Without this,
# `cargo check` would fail on a fresh checkout because the embedded
# asset map can't resolve.
- name: Build frontend (for tauri.conf.json frontendDist)
working-directory: frontend
run: bun run build
- name: Cargo check (Tauri shell)
working-directory: frontend/src-tauri
run: cargo check --target ${{ matrix.rust_target }} --message-format=short
# ── Cross-platform Python runtime smoke (Phase 0 GATE-02) ───────────────
# Loads the frozen tests/fixtures/omnivoice_data/ fixture and boots the
# FastAPI app in-process via TestClient on macOS/Windows/Linux. Catches
# platform-specific Python import / path bugs that the Linux-only `test`
# job above misses. Narrow scope (tests/smoke/ only) β€” full pytest stays
# on Linux until Phase 1's INST-01 lands setuptools for WhisperX.
smoke-matrix:
name: Smoke (${{ matrix.label }})
needs: test
strategy:
fail-fast: false
matrix:
include:
- os: macos-14
label: macOS
- os: windows-2022
label: Windows
- os: ubuntu-22.04
label: Linux
runs-on: ${{ matrix.os }}
timeout-minutes: 10
env:
# Restricted-network resilience (RESEARCH Pitfall #6) β€” keeps uv from
# giving up on the first slow PyPI / python-build-standalone fetch.
UV_HTTP_TIMEOUT: "120"
UV_HTTP_RETRIES: "5"
steps:
- uses: actions/checkout@v4
- name: Setup Python 3.11
uses: actions/setup-python@v5
with:
python-version: "3.11"
- name: Install uv
uses: astral-sh/setup-uv@v3
with:
enable-cache: true
cache-dependency-glob: "uv.lock"
# ffmpeg + libsndfile are needed by soundfile / audio fixtures even
# though the silence WAV doesn't decode anything heavy β€” keeps test
# collection from import-erroring on optional audio modules.
- name: System deps (macOS)
if: runner.os == 'macOS'
run: brew install ffmpeg libsndfile || true
- name: System deps (Windows)
if: runner.os == 'Windows'
shell: bash
run: |
choco install ffmpeg -y --no-progress
ffmpeg -version
- name: System deps (Linux)
if: runner.os == 'Linux'
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: ffmpeg libsndfile1
version: 1.0
- name: Install Python deps
run: uv sync
- name: Run smoke tests
run: uv run pytest tests/smoke/ -q --tb=short