name: Tests on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v4 with: enable-cache: true - name: Set up Python uses: actions/setup-python@v5 with: python-version-file: "pyproject.toml" - name: Install dependencies run: uv sync --all-extras - name: Lint run: uv run ruff check - name: Type check run: uv run ty check lint-frontend: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: pnpm/action-setup@v4 with: version: 10 - name: Set up Node.js uses: actions/setup-node@v4 with: node-version: "22" cache: "pnpm" cache-dependency-path: app/frontend/pnpm-lock.yaml - name: Install dependencies working-directory: app/frontend run: pnpm install --frozen-lockfile - name: Lint and format check working-directory: app/frontend run: pnpm run check test: needs: [lint, lint-frontend] runs-on: ubuntu-latest env: HF_TOKEN: ${{ secrets.HF_TOKEN }} steps: - uses: actions/checkout@v4 - uses: astral-sh/setup-uv@v4 with: enable-cache: true - name: Set up Python uses: actions/setup-python@v5 with: python-version-file: "pyproject.toml" - name: Install dependencies run: uv sync --all-extras - name: Cache HuggingFace models id: hf-cache uses: actions/cache@v4 with: path: ~/.cache/huggingface key: huggingface-${{ runner.os }}-test-models-v1 - name: Pre-download tokenizer if: steps.hf-cache.outputs.cache-hit != 'true' run: uv run python -c "from transformers import AutoTokenizer; AutoTokenizer.from_pretrained('Qwen/Qwen3-Embedding-0.6B')" - name: Pre-download cross-encoder test model if: steps.hf-cache.outputs.cache-hit != 'true' run: uv run python -c "from sentence_transformers import CrossEncoder; CrossEncoder('cross-encoder/ms-marco-MiniLM-L-6-v2')" - name: Run tests with coverage env: HF_HUB_OFFLINE: ${{ steps.hf-cache.outputs.cache-hit == 'true' && '1' || '0' }} TRANSFORMERS_OFFLINE: ${{ steps.hf-cache.outputs.cache-hit == 'true' && '1' || '0' }} run: uv run pytest -m "not integration" --cov=haiku --cov-report=xml - name: Upload coverage to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} files: ./coverage.xml fail_ci_if_error: false