Files
thoughtsync/ci-requirements.md
T
bvandeusenandClaude Opus 5 ab961f13ce
Desktop (Tauri) / Windows installer (cross-compiled) (push) Failing after 48s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m40s
desktop: cross-compiled Windows NSIS installer lane (task 2015)
Adds a `windows` job to desktop.yml on the new ci-tauri-win image, producing a
Windows -setup.exe without any Windows hardware. A Windows container can't run
on a Linux host, so cross-compilation is the only route: --runner cargo-xwin
supplies the MSVC CRT/SDK (pre-warmed into the image) and links with lld-link,
and makensis builds the installer.

NSIS only. .msi needs WiX v3, a Windows program — per Tauri, ".msi installers
can only be created on Windows". It comes back if a Windows node ever exists.

Kept as a separate job so a Windows-side failure can never block the Linux
artifacts, which are the primary product today. publish-release.sh now globs
the windows target root too; nullglob means each job uploads only what its own
workspace contains, and the release is created once and reused via the 409
path, so both jobs can publish to the same release safely.

No app code changes were needed. The AppImage self-integration UI already
gates on is_appimage (AccountView.vue:131, DesktopIntegrationPrompt.vue:22),
and $APPIMAGE is never set on Windows, so the OOBE prompt and Settings toggle
hide themselves.

Recorded plainly in ci-requirements.md that this is the weakest-verified lane
we have: Tauri calls Linux->Windows cross-compilation "not tested as much" and
a last resort, and a Linux runner cannot execute a Windows binary. Green means
it built. A real Windows machine check is mandatory before trusting a release,
and installers are unsigned until a certificate exists.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SreJkbxB4gx8pPsu8QbLPi
2026-07-25 20:14:55 -04:00

111 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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` + `:<sha>`; `v*` tag -> `:latest` + `:<version>` + `:<sha>`
(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 (~2040 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`) → de-bundle the AppImage's
graphics libs → verify the `.deb` → repackage for pacman.
- **`APPIMAGE_EXTRACT_AND_RUN=1`** is set: AppImage tooling FUSE-mounts by default
and CI containers have no `/dev/fuse`.
- **Packaging tools used from the image** (none installed at job time, rule 5):
`dpkg-deb` / `dpkg-query` / `apt-cache` and `dpkg-shlibdeps` (from `dpkg-dev`,
pulled in by `build-essential`) for `desktop/packaging/deb/verify.sh`; `tar` +
a compressor for `desktop/packaging/arch/package-prebuilt.sh`. Both scripts
degrade gracefully rather than hard-failing on an absent optional tool:
`bsdtar` (`libarchive-tools`) is used for the pacman package's `.MTREE` when
present and skipped when not, compression falls back zstd → xz → gzip, and the
`.deb` clean-container install test runs only if a docker CLI is available.
Run 2872 confirmed all three optional tools are ABSENT today, so the current
build takes every fallback: the pacman package ships as `.pkg.tar.xz` with no
`.MTREE`, and the `.deb` clean-container install test is skipped. All three are
functional outcomes — pacman installs an `.xz` package fine, and only
`pacman -Qkk` file verification needs `.MTREE`. Adding `libarchive-tools` +
`zstd` + a docker CLI to `ci-tauri` would upgrade these paths; none of them
block a green build.
- **Not verifiable in CI:** the runner is Debian, so the pacman package cannot be
`pacman -U`-tested here. That step logs `.PKGINFO` + the full file listing so
the package is auditable from the run log; a real Arch install is the operator's
confirm.
### Windows lane — second job, second image
`desktop.yml` also runs a `windows` job that cross-compiles the NSIS installer.
- **Image:** `git.fabledsword.com/bvandeusen/ci-tauri-win:1.97` (Rust + Node +
`cargo-xwin` + LLVM/`lld` + NSIS). A separate image from `ci-tauri` per
CI-Runner's `docs/process.md` fork rule — the MSVC CRT/SDK cache alone is >1 GB.
Its pins are held in lockstep with `ci-tauri`; bump them together, since both
lanes compile the same source.
- **Why cross-compile:** there is no Windows build host, and a Windows container
cannot run on a Linux host (containers share the host kernel). `cargo-xwin`,
`lld-link` and `makensis` are Linux programs that emit Windows PE output.
- **NSIS only.** `.msi` requires WiX v3, a Windows program — per Tauri, "`.msi`
installers can only be created on Windows."
- **Separate job on purpose:** a Windows failure must not block the Linux
artifacts, which are the primary product today.
- **Weakest verification of any lane.** Tauri documents this path as "not as
straight forward as compiling on Windows directly and is not tested as much",
to be used "only as a last resort" — and a Linux runner cannot execute a
Windows binary. Green means it *built*. A real Windows machine check is
mandatory before trusting a release.
- **Unsigned.** Installers will trip SmartScreen until a code-signing
certificate exists; that is a purchasing decision, not a CI one.
- No Postgres lane (unchanged): the desktop app's local store + sync behavior is
verified on the operator's machine, not in CI.