chore: qwen3tts standalone → hal0-slot migration prep (runbook + guarded script) #1659
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| # Cancel superseded PR runs to save runners; never cancel a push to main | |
| # (every main commit must build — required checks + the nightly greenness gate). | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: ${{ github.event_name == 'pull_request' }} | |
| # Least privilege: CI only needs to read the repo. | |
| permissions: | |
| contents: read | |
| jobs: | |
| python: | |
| runs-on: ubuntu-latest | |
| # 3.14 is experimental until every dep ships 3.14 wheels — surface it | |
| # without reddening main. No-op on PRs, which run 3.12 only. | |
| continue-on-error: ${{ matrix.python-version == '3.14' }} | |
| env: | |
| # fastembed (cognee memory tests) honours FASTEMBED_CACHE_PATH | |
| # (fastembed/common/utils.py). Pin it to a stable, cacheable dir so the | |
| # warm step AND pytest share one location that actions/cache persists. | |
| FASTEMBED_CACHE_PATH: ${{ github.workspace }}/.fastembed-cache | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| # PRs test the primary 3.12 only (fast feedback; matches the required | |
| # "python (3.12)" status check). Pushes to main test the full supported | |
| # range so Python-version drift still gates the protected branch. | |
| python-version: ${{ (github.event_name == 'pull_request' && fromJSON('["3.12"]')) || fromJSON('["3.12","3.13","3.14"]') }} | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-python@v6 | |
| with: | |
| python-version: ${{ matrix.python-version }} | |
| cache: pip | |
| - name: Install system deps | |
| # ffmpeg backs the in-container moonshine audio decoder | |
| # (packaging/toolbox/moonshine/moonshine_server.py). The redaction | |
| # tests in tests/providers/test_moonshine_server.py exercise the | |
| # real subprocess path; without ffmpeg they hit FileNotFoundError | |
| # instead of the CalledProcessError the code catches. | |
| run: sudo apt-get update && sudo apt-get install -y --no-install-recommends ffmpeg | |
| - name: Install | |
| run: pip install -e ".[dev]" | |
| - name: Cache fastembed embedding model | |
| # cognee memory tests (tests/memory/test_cognee_wrapper.py) embed via | |
| # fastembed, which downloads qdrant/bge-small-en-v1.5-onnx-q (~64 MB) | |
| # into FASTEMBED_CACHE_PATH on first use. That per-run download | |
| # intermittently slow-fails (could-not-load-model-from-any-source) and | |
| # gated unrelated PRs (#442, #445). The model id is fixed, so a static | |
| # key caches once and restores forever (bump -vN to refresh). | |
| uses: actions/cache@v5 | |
| with: | |
| path: ${{ github.workspace }}/.fastembed-cache | |
| key: fastembed-bge-small-en-v1.5-v2 | |
| - name: Warm fastembed cache | |
| # On a cache miss, download the model now. fastembed already retries 3x | |
| # internally; we wrap each attempt in `timeout` so a stalled connection | |
| # is bounded (~6 min) and retried fresh rather than hanging. Best-effort: | |
| # on total failure, let pytest surface the error rather than masking it. | |
| run: | | |
| for attempt in 1 2 3; do | |
| timeout 360 python -c "from fastembed import TextEmbedding; TextEmbedding('BAAI/bge-small-en-v1.5'); print('fastembed model warmed')" && exit 0 | |
| echo "::warning::fastembed warm attempt $attempt failed/timed out; retrying in 10s" | |
| sleep 10 | |
| done | |
| echo "::warning::fastembed warm-up failed after 3 attempts; cognee tests will surface it" | |
| - name: Lint | |
| run: ruff check src tests | |
| - name: Format check | |
| run: ruff format --check src tests | |
| - name: Test | |
| # Coverage (+ verbose) only on main pushes — it's a report, not a gate, | |
| # so PRs skip the instrumentation overhead and run a quiet, faster suite. | |
| run: pytest tests/ ${{ github.event_name == 'push' && '-v --cov=hal0 --cov-report=term-missing' || '-q' }} | |
| ui: | |
| runs-on: ubuntu-latest | |
| defaults: | |
| run: | |
| working-directory: ui | |
| steps: | |
| - uses: actions/checkout@v6 | |
| - uses: actions/setup-node@v6 | |
| with: | |
| node-version: "22" | |
| cache: npm | |
| cache-dependency-path: ui/package-lock.json | |
| - name: Install | |
| run: npm ci | |
| - name: Build | |
| run: npm run build |