diff --git a/.gitea/workflows/deb.yml b/.gitea/workflows/deb.yml new file mode 100644 index 0000000..6e99620 --- /dev/null +++ b/.gitea/workflows/deb.yml @@ -0,0 +1,82 @@ +# Build the punktfunk-host .deb and publish it to Gitea's Debian package registry, so the +# Ubuntu hosts get new builds via `apt update && apt upgrade`. Runs inside the same Ubuntu +# 26.04 rust-ci builder image as ci.yml, so dpkg-shlibdeps pins the runtime lib package names +# (libavcodec62, libpipewire-0.3-0t64, …) to exactly what the target boxes run. +# +# Registry (public, unom org): https://git.unom.io/unom/-/packages +# Box setup (once): see packaging/debian/README.md +# +# REGISTRY_TOKEN: repo Actions secret, a PAT with write:package scope (shared with docker.yml). +name: deb + +on: + push: + branches: [main] + tags: ['v*'] + workflow_dispatch: + +env: + REGISTRY: git.unom.io + OWNER: unom + DISTRIBUTION: stable + COMPONENT: main + +jobs: + build-publish: + runs-on: ubuntu-24.04 + container: + image: git.unom.io/unom/punktfunk-rust-ci:latest + timeout-minutes: 90 + steps: + - uses: actions/checkout@v4 + + # dpkg-shlibdeps (Depends resolution) + dpkg-deb live in dpkg-dev. + - name: dpkg-dev + run: apt-get update && apt-get install -y --no-install-recommends dpkg-dev + + # Share ci.yml's cache keys so the release build reuses its registry + target artifacts. + - name: Cache keys + run: echo "rustc=$(rustc --version | cut -d' ' -f2)" >> "$GITHUB_ENV" + - uses: actions/cache@v4 + with: + path: | + /usr/local/cargo/registry + /usr/local/cargo/git + key: cargo-home-${{ hashFiles('Cargo.lock') }} + restore-keys: cargo-home- + - uses: actions/cache@v4 + with: + path: target + key: cargo-target-${{ env.rustc }}-${{ hashFiles('Cargo.lock') }} + restore-keys: cargo-target-${{ env.rustc }}- + + - name: Build release host + run: | + git config --global --add safe.directory "$PWD" + cargo build --release -p punktfunk-host --locked + + - name: Version + # Tag v1.2.3 -> 1.2.3 (a real release); a main push -> 0.0.1~ciN.g, which sorts + # BEFORE 0.0.1 (the '~') yet monotonically increases by run number, so `apt upgrade` + # always moves the boxes to the newest main build. + run: | + case "$GITHUB_REF" in + refs/tags/v*) V="${GITHUB_REF_NAME#v}" ;; + *) V="0.0.1~ci${GITHUB_RUN_NUMBER}.g${GITHUB_SHA::8}" ;; + esac + echo "VERSION=$V" >> "$GITHUB_ENV" + echo "package version $V" + + - name: Build .deb + run: VERSION="$VERSION" bash packaging/debian/build-deb.sh + + - name: Publish to the Gitea apt registry + env: + TOKEN: ${{ secrets.REGISTRY_TOKEN }} + run: | + DEB="$(ls dist/*.deb)" + echo "uploading $DEB" + # PAT owner (enricobuehler), not the push actor — matches docker.yml's registry login. + curl -fsS --user "enricobuehler:$TOKEN" --upload-file "$DEB" \ + "https://$REGISTRY/api/packages/$OWNER/debian/pool/$DISTRIBUTION/$COMPONENT/upload" + echo "published $DEB to $OWNER/debian $DISTRIBUTION/$COMPONENT" diff --git a/.gitignore b/.gitignore index 6c039d8..5b54e79 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ clients/apple/PunktfunkCore.xcframework/ clients/apple/.swiftpm/ # Xcode per-user state xcuserdata/ + +# Debian package build output +/dist/ diff --git a/packaging/README.md b/packaging/README.md index 77eb01d..8ee9f26 100644 --- a/packaging/README.md +++ b/packaging/README.md @@ -4,6 +4,9 @@ The punktfunk host is Linux-only and links system FFmpeg (NVENC), PipeWire, Opus the NVIDIA driver. This directory packages it for the **Fedora Atomic / Bazzite** world (rpm-ostree + bootc), where most of those deps are already present. +> 👉 **Ubuntu/Debian hosts** install via `apt` from Gitea's package registry — see +> [`debian/README.md`](debian/README.md) (`apt update && apt upgrade` for new builds). + > 👉 **End-to-end Bazzite setup walkthrough** (install → udev/group → `host.env` → service → > firewall → verify → troubleshooting): [`bazzite/README.md`](bazzite/README.md). This file is the > higher-level packaging rationale. diff --git a/packaging/debian/README.md b/packaging/debian/README.md new file mode 100644 index 0000000..d491835 --- /dev/null +++ b/packaging/debian/README.md @@ -0,0 +1,55 @@ +# punktfunk-host — Debian/Ubuntu package (apt) + +`punktfunk-host` is published as a `.deb` to **Gitea's Debian package registry** in the public +`unom` org, so the Ubuntu hosts update with plain `apt`. CI (`.gitea/workflows/deb.yml`) builds +and publishes on every push to `main` (a rolling `0.0.1~ciN.` build) and on `v*` tags +(a clean `X.Y.Z`). + +Package layout mirrors the Fedora RPM (`../rpm/punktfunk.spec`): the host binary, the `/dev/uinput` +udev rule, the systemd **user** unit, headless session helpers, the example config, and the OpenAPI +doc. Runtime `Depends` are computed by `dpkg-shlibdeps` from the binary itself (built in the Ubuntu +26.04 rust-ci image, so the lib soname package names match the target). The NVIDIA driver +(`libnvidia-encode` / `libEGL_nvidia` / `libcuda`) is **not** a dependency — it's installed out of +band, like on the RPM side. + +## Install on a host (one-time) + +The registry is public, so no apt auth is needed — just trust the repo's signing key: + +```sh +sudo install -d -m 0755 /etc/apt/keyrings +curl -fsSL https://git.unom.io/api/packages/unom/debian/repository.key \ + | sudo tee /etc/apt/keyrings/punktfunk.asc >/dev/null + +echo "deb [signed-by=/etc/apt/keyrings/punktfunk.asc] https://git.unom.io/api/packages/unom/debian stable main" \ + | sudo tee /etc/apt/sources.list.d/punktfunk.list + +sudo apt update +sudo apt install punktfunk-host +``` + +Then, as the desktop user: + +```sh +sudo usermod -aG input "$USER" # virtual gamepads (re-login to take effect) +mkdir -p ~/.config/punktfunk +cp /usr/share/punktfunk-host/host.env.example ~/.config/punktfunk/host.env # then edit +systemctl --user enable --now punktfunk-host +``` + +## Updates + +```sh +sudo apt update && sudo apt upgrade # picks up the newest published build +systemctl --user restart punktfunk-host # if the unit was already running +``` + +## Build a `.deb` locally + +```sh +VERSION=0.0.1 bash packaging/debian/build-deb.sh # -> dist/punktfunk-host_0.0.1_amd64.deb +``` + +Needs `dpkg-dev` (`dpkg-shlibdeps`, `dpkg-deb`). It builds the release binary first if missing. +Build it in the rust-ci image (or on an Ubuntu 26.04 box) so the resolved `Depends` match the +hosts; building on a GPU box is fine — the NVIDIA driver lib is filtered out either way. diff --git a/packaging/debian/build-deb.sh b/packaging/debian/build-deb.sh old mode 100644 new mode 100755 index ac18510..6414105 --- a/packaging/debian/build-deb.sh +++ b/packaging/debian/build-deb.sh @@ -123,7 +123,7 @@ Description: Low-latency desktop/game streaming host (Moonlight + punktfunk/1) . NVENC + GPU EGL come from the NVIDIA driver (libnvidia-encode / libEGL_nvidia), installed out of band. After install: add yourself to the 'input' group for virtual - gamepads, then `systemctl --user enable --now punktfunk-host`. + gamepads, then enable the systemd user service punktfunk-host. EOF cat > "$STAGE/DEBIAN/postinst" <<'EOF'