From 3a2119bcb90d47e83b6b6887c1611ef253be55a5 Mon Sep 17 00:00:00 2001 From: Anthony Date: Fri, 29 May 2026 15:43:16 +0200 Subject: [PATCH] Add AUR PKGBUILD + systemd user service `tutabridge-git` VCS package builds only the headless CLI (no GUI/Node). Handles the SDK submodule in prepare(), fetches crates for an offline `--frozen` build, installs the binary + a systemd *user* unit (the bridge runs per-user, binds localhost, uses the login keyring). packaging/aur/README documents local build + AUR publish (.SRCINFO is generated on Arch). --- packaging/aur/PKGBUILD | 53 ++++++++++++++++++++++++++++ packaging/aur/README.md | 52 +++++++++++++++++++++++++++ packaging/systemd/tutabridge.service | 26 ++++++++++++++ 3 files changed, 131 insertions(+) create mode 100644 packaging/aur/PKGBUILD create mode 100644 packaging/aur/README.md create mode 100644 packaging/systemd/tutabridge.service diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD new file mode 100644 index 0000000..0d7006f --- /dev/null +++ b/packaging/aur/PKGBUILD @@ -0,0 +1,53 @@ +# Maintainer: spartanz51 +# +# VCS package — builds the headless TutaBridge CLI/daemon from the latest +# commit. The GUI (Tauri) is intentionally not built here; this package is +# the lean daemon for terminal / server use. + +pkgname=tutabridge-git +pkgver=0.r0.0000000 +pkgrel=1 +pkgdesc="Local IMAP/SMTP bridge for Tuta encrypted email (headless CLI/daemon)" +arch=('x86_64' 'aarch64') +url="https://github.com/spartanz51/tutabridge" +license=('GPL-3.0-or-later') +depends=('gcc-libs') +makedepends=('rust' 'cargo' 'git' 'cmake' 'nasm') +optdepends=('gnome-keyring: persist the Tuta session across reboots (Secret Service)' + 'kwallet: alternative Secret Service provider') +provides=('tutabridge') +conflicts=('tutabridge') +source=("$pkgname::git+https://github.com/spartanz51/tutabridge.git") +sha256sums=('SKIP') + +pkgver() { + cd "$pkgname" + # 0.. + printf "0.r%s.%s" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" +} + +prepare() { + cd "$pkgname" + # The Tuta Rust SDK is a git submodule and the build needs it. + git submodule update --init --recursive + # Fetch crates up-front so build() can run fully offline (--frozen). + export CARGO_HOME="$srcdir/cargo-home" + cargo fetch --locked +} + +build() { + cd "$pkgname" + export CARGO_HOME="$srcdir/cargo-home" + export RUSTUP_TOOLCHAIN=stable + # Build only the CLI crate — no GUI, no Node, no webkit. + cargo build --release --frozen -p tutabridge +} + +package() { + cd "$pkgname" + install -Dm755 "target/release/tutabridge" "$pkgdir/usr/bin/tutabridge" + install -Dm644 "packaging/systemd/tutabridge.service" \ + "$pkgdir/usr/lib/systemd/user/tutabridge.service" + install -Dm644 "LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" + install -Dm644 "README.md" "$pkgdir/usr/share/doc/$pkgname/README.md" +} diff --git a/packaging/aur/README.md b/packaging/aur/README.md new file mode 100644 index 0000000..31fd381 --- /dev/null +++ b/packaging/aur/README.md @@ -0,0 +1,52 @@ +# AUR packaging + +`PKGBUILD` for the **headless TutaBridge daemon** (CLI only — no GUI). It builds +just the `tutabridge` binary, so it pulls no Node / Tauri / webkit dependencies. + +## Local build / test + +On an Arch machine: + +```bash +cd packaging/aur +makepkg -si # build + install +``` + +## First run + +The daemon resumes a saved keyring session on start, so sign in **once** +interactively before enabling the service: + +```bash +tutabridge # prompts for email, then Tuta password + TOTP +systemctl --user enable --now tutabridge # run it in the background from now on +``` + +Connect your mail client to `127.0.0.1:1143` (IMAP) / `127.0.0.1:1025` (SMTP), +using the bridge password printed in the logs (`journalctl --user -u tutabridge`). + +## Publishing to the AUR + +This directory is the package *source*, not the AUR git repo. To publish: + +```bash +git clone ssh://aur@aur.archlinux.org/tutabridge-git.git +cp packaging/aur/PKGBUILD tutabridge-git/ +cd tutabridge-git +makepkg --printsrcinfo > .SRCINFO # must be generated on Arch +git add PKGBUILD .SRCINFO +git commit -m "Initial import" && git push +``` + +`.SRCINFO` is intentionally not committed here — it has to be generated by +`makepkg` on an Arch host so it matches the PKGBUILD exactly. + +## Notes + +- `pkgver()` derives `0.r.` from git; `makepkg` rewrites the + `pkgver=` line on each build. +- Linux secret-service (keyring persistence) needs a running provider + (gnome-keyring / kwallet) — listed as optdepends. Without one the daemon + still works but will ask for the Tuta password on every start. +- A future tagged release can add a non-`-git` `tutabridge` package built from + a release tarball. diff --git a/packaging/systemd/tutabridge.service b/packaging/systemd/tutabridge.service new file mode 100644 index 0000000..fc94918 --- /dev/null +++ b/packaging/systemd/tutabridge.service @@ -0,0 +1,26 @@ +# systemd *user* service for the TutaBridge daemon. +# +# TutaBridge runs per-user (it binds localhost IMAP/SMTP and uses the user's +# login keyring), so it belongs in the user manager, not the system one. +# +# First run interactively once to sign in (this seeds the keyring session): +# tutabridge +# then enable the background service: +# systemctl --user enable --now tutabridge.service +# +# It will resume the saved keyring session on start — no password prompt. + +[Unit] +Description=TutaBridge — local IMAP/SMTP bridge for Tuta encrypted email +After=network-online.target +Wants=network-online.target + +[Service] +ExecStart=/usr/bin/tutabridge +Restart=on-failure +RestartSec=5 +# Keep logs at info; override with `systemctl --user edit tutabridge` if needed. +Environment=RUST_LOG=info + +[Install] +WantedBy=default.target