# CI Requirements — ThoughtSync > Spec lives in [`docs/process.md`](https://git.fabledsword.com/bvandeusen/CI-runner/src/branch/main/docs/process.md) > in the CI-Runner repo. ## Runtime image ``` git.fabledsword.com/bvandeusen/ci-python:3.14 ``` Selected via `container.image` (not a `runs-on` label) on all four jobs in `.forgejo/workflows/ci.yml`: typecheck (Vue/TS), lint (ruff), test (pytest), build (docker buildx). ## Image deps used - python 3.12+ (the runtime `Dockerfile` targets python:3.12-slim; tests run on the image's 3.14 — both >=3.12, so results stay representative) - node 24 — `npm ci` + `vue-tsc` in the typecheck job, and the frontend builder stage inside the production `Dockerfile`. (Also required by the JS-based `actions/checkout` action — a Node-less runner fails every job at checkout.) - ruff — lint job runs `ruff check src/` with zero install overhead - uv — test job creates the venv (`uv venv /opt/venv`) and installs the package with dev deps - docker CLI + buildx — build job pushes the dev/release image to the Forgejo registry ## Per-job tool installs Nothing installed at job time beyond what the image provides — all four jobs run entirely on `ci-python:3.14`. ## Notes - **No `actions/cache`.** Deliberately omitted for npm/uv: it's a GitHub-fetched JS action and on a cold runner concurrent jobs race fetching it. We lean on the pinned `ci-python` image's pre-installed toolchain instead; `npm ci` / `uv pip install` cold cost is a non-blocker. - Build gates on `typecheck` + `lint` only. The `test` job runs in parallel for visibility but does not block the dev image push. DB-backed / integration tests run against the dev image manually — ThoughtSync's unit tests are DB-free (no Postgres service lane in CI yet). - `dev` push -> `:dev` + `:`; `v*` tag -> `:latest` + `:` + `:` (family rule 46). - The production runtime `Dockerfile` tracks python:3.12 so test results stay representative of the deployed image. ## Desktop (Tauri) lane — separate workflow The Tauri desktop client (`desktop/`) builds in its own workflow, `.forgejo/workflows/desktop.yml`, NOT in `ci.yml` — it's a heavy Rust + AppImage build (~20–40 min) that should only run on `desktop/**` changes, not on every backend/frontend push. - **Image:** `git.fabledsword.com/bvandeusen/ci-tauri:1.97` (Rust + Node + WebKitGTK 4.1 + Tauri v2 Linux deps + `tauri-cli`). Selected via `container.image`; `runs-on: python-ci` is only a scheduling label. - **Steps:** build the shared frontend (embedded by `generate_context!`) → `cargo tauri icon app-icon.png` (platform icon set from the committed 1024px source) → `cargo fmt --check` → `cargo clippy -D warnings` → `cargo test` → `cargo tauri build` (produces `.deb` + `.AppImage`). - **`APPIMAGE_EXTRACT_AND_RUN=1`** is set: AppImage tooling FUSE-mounts by default and CI containers have no `/dev/fuse`. - No Postgres lane (unchanged): the desktop app's local store + sync behavior is verified on the operator's machine, not in CI.