feat(client): linux flatpak via tauri shell (#188) #222
No reviewers
Labels
No labels
area:auth
area:ci
area:db
area:infra
area:native
area:pwa
area:service
epic
feature
foundation
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
james/carol!222
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "188-linux-flatpak"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Wraps the Expo Web bundle in a Tauri v2 shell and ships it as a Linux Flatpak, attached tag-driven to the same release page the API container goes to. Closes #188 (well — closes once verified on the runner).
Shell decision: Tauri 2 (kept)
ADR-0027 §2 already calls Tauri out as the recommended shell; the ticket agrees; I agree after running the build out. Why I didn't switch:
tauri = 2.11.3,tauri-build = 2.6.3).gtk-webkit2Rust binding wrapper would be smaller still but every desktop feature (window controls, drag regions, future system-tray) becomes hand-glue. Tauri 2 is the right next step.No fatal Tauri blocker showed up. If one ever does, the manifest + shell layout in this PR ports cleanly to a smaller wrapper.
Runtime URL plumbing
Tauri's webview loads the bundle from
tauri://localhost, soPlatform.OS === "web"matches but the API is not at same-origin. New helperapps/client/lib/runtimeShell.tsdetects the Tauri webview via the standardwindow.__TAURI_INTERNALS__(v2) /window.__TAURI__(v1) markers.apiClient.ts,serverUrl.ts, and theServerUrlGatein_layout.tsxall collapse the previous "is it native?" check into a new "is it off-origin?" check that returns true for both Android and the Tauri shell.serverUrl.tsswaps its backing store betweenexpo-secure-store(Android) andlocalStorage(Tauri webview) based on the same signal.PWA behaviour is unchanged.
What's in the PR
apps/client/lib/runtimeShell.ts+ the apiClient/serverUrl/_layout cascade.apps/client/src-tauri/— Tauri 2 project (Cargo.toml,Cargo.lock,tauri.conf.json,capabilities/default.json, placeholder icons, minimalmain.rs+lib.rs).apps/client/scripts/build-flatpak.sh+pnpm -F @carol/client build:flatpakscript.flatpak/tech.wynning.carol.{yml,desktop,metainfo.xml}at the repo root (flatpak-builder resolves source paths relative to the manifest dir, and several sources live outsideapps/client/)..forgejo/workflows/release-flatpak.yml— tag-triggered, polls the API release page fromrelease.yml, attaches acarol-vX.Y.Z.flatpakasset. Mirrors the shape ofrelease-android.yml.apps/client/README.md— "Linux Flatpak build" section + the off-origin runtime URL notes.apps/client/tests/runtimeShell.test.ts— pure unit coverage for the Tauri detector.Flatpak runtime / SDK pin
org.gnome.Platform//48+org.gnome.Sdk//48. GNOME 48 ships webkit2gtk-4.1 (Tauri 2's webview), gtk3, glib, and librsvg out of the box. We do not useorg.freedesktop.Platformbecause it lacks webkit2gtk; switching would force building webkit from source inside the manifest (multi-hour). The pin is manual (Renovate doesn't track Flatpak runtimes); bumping requires editing the manifest + workflow env in the same PR.Forgejo runner image — system deps
The current self-hosted runner uses
ghcr.io/catthehacker/ubuntu:js-24.04, which does not ship rustup, webkit2gtk-4.1-dev, or flatpak. The workflow installs them on each run (apt-get install+ rustup-init). Single Rust build + GNOME runtime download dominates runtime — expect roughly 5-10 min added per release vs. the API container build. Worth filing a follow-up to bake those deps into a custom runner image (see follow-ups below) but functionally fine today.Verified locally
pnpm install --frozen-lockfilepnpm -F @carol/api typecheckpnpm -F @carol/api-client typecheckpnpm -F @carol/client typecheckpnpm -F @carol/client lintpnpm -F @carol/client test— all 29 tests pass (4 new Tauri-detector cases)pnpm -F @carol/client export:web— bundle still produces cleanlyactionlint .forgejo/workflows/*.yml— no findingscargo metadatainsidesrc-tauri/parses (Cargo.toml syntax + dep resolution OK)cargo generate-lockfileresolvestauri = "2"to v2.11.3 — committedflatpak-builder --show-manifest flatpak/tech.wynning.carol.yml— manifest parses cleanlydesktop-file-validate flatpak/tech.wynning.carol.desktop— passesappstreamcli validate flatpak/tech.wynning.carol.metainfo.xml— passesWaits on CI
cargo build --releaseinsidesrc-tauri/— needs webkit2gtk-4.1-dev system deps; my local box doesn't have them.flatpak-builder+flatpak build-bundleagainst GNOME Platform 48 — needs the runtime installed..flatpak(flatpak install,flatpak run, server-setup screen).Per the ticket's guidance, the actual Flatpak production runs on the Forgejo runner. The first tag push after this lands is the first true end-to-end test.
Follow-ups worth filing
Test plan
v0.0.0-rc.1tag to a fork or a maintenance branch; watch the workflow run end-to-end and attach the.flatpakasset.flatpak install --user carol-v0.0.0-rc.1.flatpakon a Fedora Workstation box.apps/apiservingapps/client/dist/) still works unchanged (no regression in same-origin path).Generated with Claude Code
📊 Test coverage
Patch coverage: no testable lines changed.
Overall (
app/,lib/,db/, excluding UI per ADR-0019):Soft thresholds per ADR-0019. Coverage is informational and does not block merge.
Trivy (container image)
Threshold:
high· Total findings: 121 · At/above threshold: 16.27.0, 7.28.0, 8.5.0