Files
thoughtsync/.forgejo/workflows/desktop.yml
T
bvandeusenandClaude Opus 5 85ca7c2a2d
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 7s
CI & Build / Python tests (push) Successful in 8s
CI & Build / Build & push image (push) Successful in 17s
Desktop (Tauri) / Tauri desktop (Linux) (push) Successful in 3m28s
desktop: drop the redundant deb depends, correct the pacman docs
Follow-up to 8a8b2b1, driven by what run 2872's new checks actually printed.

The .deb verification did its job on its first run: tauri already infers
exactly libwebkit2gtk-4.1-0 + libgtk-3-0, so declaring the same two in
tauri.conf.json produced a control file listing each of them twice. Removed
the declaration — verify.sh is the real guard, and it fails the build if
inference ever stops covering what the binary links.

The pacman step revealed ci-tauri carries neither zstd nor bsdtar, so packages
currently ship as .pkg.tar.xz with no .MTREE. Both are working outcomes
(pacman reads xz; only `pacman -Qkk` needs .MTREE), but the docs promised
.zst, so the README, the release notes and ci-requirements.md now describe
what the build actually produces.

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

129 lines
5.8 KiB
YAML

# Tauri desktop (Linux) build — SEPARATE from ci.yml on purpose: this is a heavy
# Rust + AppImage build (~20-40 min) that should NOT run on backend/frontend-only
# pushes. Scoped to desktop/** (+ this file). Produces the .deb and .AppImage.
#
# Toolchain comes from the ci-tauri image (Rust + Node + WebKitGTK 4.1 + tauri-cli);
# runs-on is just a registered scheduling label (Label Model B), not a per-purpose
# runner. The frontend is built here because tauri's generate_context! embeds it.
name: Desktop (Tauri)
on:
push:
branches: [dev, main]
tags: ["v*"]
paths:
- "desktop/**"
# The desktop app embeds the frontend, and the data seam / Tauri bridge are
# what the offline core rides on — rebuild the app when those change too.
- "frontend/src/adapters/**"
- "frontend/src/desktop/**"
- ".forgejo/workflows/desktop.yml"
workflow_dispatch:
concurrency:
group: desktop-${{ github.ref }}
cancel-in-progress: ${{ !startsWith(github.ref, 'refs/tags/') }}
permissions:
# write (not read) so the tag build can publish a Release with the bundles
# attached (the "Publish release" step). Read is enough for dev/main builds,
# but the token scope is per-workflow, so it's set once here.
contents: write
jobs:
build:
name: Tauri desktop (Linux)
if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')
runs-on: python-ci
container:
image: git.fabledsword.com/bvandeusen/ci-tauri:1.97
env:
# AppImage tooling (linuxdeploy) FUSE-mounts itself by default; CI containers
# have no /dev/fuse, so tell it to extract-and-run instead. Without this the
# AppImage bundle step fails with a FUSE error.
APPIMAGE_EXTRACT_AND_RUN: "1"
steps:
- uses: actions/checkout@v6
# tauri's generate_context! embeds the built frontend at compile time, so the
# frontend must exist before any cargo compile (clippy/test/build), not just
# at bundle time.
- name: Build the shared frontend
run: npm ci && npm run build
working-directory: frontend
- name: Rust format check
run: cargo fmt --check
working-directory: desktop/src-tauri
- name: Clippy
run: cargo clippy --all-targets -- -D warnings
working-directory: desktop/src-tauri
- name: Test
run: cargo test
working-directory: desktop/src-tauri
# Frontend already built above; skip the beforeBuildCommand rebuild.
- name: Tauri build (deb + AppImage)
run: cargo tauri build --config '{"build":{"beforeBuildCommand":""}}'
working-directory: desktop/src-tauri
# Tauri's AppImage bundles the build host's graphics/display libs
# (libEGL/libGL/libdrm/libgbm/libwayland-*), which clash with end-user GPU
# drivers and abort to a black window (EGL_BAD_PARAMETER, issue 2021).
# Strip that host-coupled stack so the app uses the running system's
# graphics libs; webkit/gtk stay bundled. Runs from the repo root (the
# script resolves its own paths), overwriting the AppImage in place.
- name: De-bundle AppImage graphics libraries
run: bash desktop/packaging/appimage/debundle-graphics.sh
# install.sh hands the .deb to every Debian/Ubuntu user, so the package's
# Depends must be right BEFORE a release exists. Prints the generated
# control file and cross-checks it against what the ELF actually needs
# (dpkg-shlibdeps).
#
# We deliberately do NOT set bundle.linux.deb.depends: run 2872 showed
# tauri already infers exactly libwebkit2gtk-4.1-0 + libgtk-3-0, so
# declaring them again only produced a control file listing each twice.
# This step is the guard instead — if tauri's inference ever stops
# covering what the binary links, the build fails here.
- name: Verify the .deb
run: bash desktop/packaging/deb/verify.sh
# Repackage the binary just built into a native pacman package, so Arch /
# CachyOS gets a real native install from install.sh instead of the AppImage
# fallback — without a second Rust build or an Arch CI image. Safe because
# nothing is bundled: the binary resolves webkit/gtk by soname, which is
# identical across the two distros. Can't be pacman-tested here (Debian
# runner), so the step logs .PKGINFO + the full file listing for audit.
- name: Package for Arch (pacman)
run: bash desktop/packaging/arch/package-prebuilt.sh
# Make the built .deb + .AppImage downloadable from the run (for hand-testing).
# continue-on-error: the Forgejo artifact backend may not be configured yet; a
# failed upload must not fail the build itself.
# Forgejo doesn't support the v4 artifact protocol (@actions/artifact v2+),
# so pin v3, which uses the older protocol the instance accepts.
- name: Upload bundles
continue-on-error: true
uses: actions/upload-artifact@v3
with:
name: thoughtsync-linux
path: |
desktop/src-tauri/target/release/bundle/appimage/*.AppImage
desktop/src-tauri/target/release/bundle/deb/*.deb
desktop/src-tauri/target/release/bundle/arch/*.pkg.tar.*
if-no-files-found: warn
# Tag builds only: publish a real, versioned Fabled-Git Release with the
# AppImage + .deb attached — the stable fetch target the install script and
# the in-app updater consume (Actions artifacts above are ephemeral/test).
# Cutting the tag is the operator's action (rule 2); this only publishes a
# Release for a tag that already exists. Dormant on dev/main pushes.
- name: Publish release
if: startsWith(github.ref, 'refs/tags/v')
env:
GITHUB_TOKEN: ${{ github.token }}
run: bash desktop/packaging/publish-release.sh