feat(packaging/flatpak,decky): Steam Deck client flatpak + plugin deploy + CI
apple / swift (push) Successful in 53s
android / android (push) Successful in 3m48s
ci / web (push) Successful in 29s
ci / docs-site (push) Successful in 34s
ci / rust (push) Successful in 2m21s
ci / bench (push) Successful in 1m36s
decky / build-publish (push) Successful in 31s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 6s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 3s
flatpak / build-publish (push) Failing after 4s
deb / build-publish (push) Successful in 2m38s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 5m9s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 4m42s
docker / deploy-docs (push) Successful in 16s
apple / swift (push) Successful in 53s
android / android (push) Successful in 3m48s
ci / web (push) Successful in 29s
ci / docs-site (push) Successful in 34s
ci / rust (push) Successful in 2m21s
ci / bench (push) Successful in 1m36s
decky / build-publish (push) Successful in 31s
docker / build-push (--build-arg FEDORA_VERSION=44, ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora44-rpm) (push) Successful in 5s
docker / build-push (., web/Dockerfile, punktfunk-web) (push) Successful in 6s
docker / build-push (ci, ci/fedora-rpm.Dockerfile, punktfunk-fedora-rpm) (push) Successful in 4s
docker / build-push (ci, ci/rust-ci.Dockerfile, punktfunk-rust-ci) (push) Successful in 5s
docker / build-push (docs-site, docs-site/Dockerfile, punktfunk-docs) (push) Successful in 3s
flatpak / build-publish (push) Failing after 4s
deb / build-publish (push) Successful in 2m38s
rpm / build-publish (bazzite, punktfunk-fedora-rpm) (push) Successful in 5m9s
rpm / build-publish (fedora-44, punktfunk-fedora44-rpm) (push) Successful in 4m42s
docker / deploy-docs (push) Successful in 16s
Ship the punktfunk Linux client to the Steam Deck as a Flatpak — the only viable
SteamOS install path, since /usr is read-only and lacks libadwaita/SDL3 — and
publish both it and the Decky plugin through Gitea. Built and validated live on a
Steam Deck (SteamOS 3.7): bundle installs user-scope, all libs resolve, libavcodec
resolves to the codecs-extra HEVC build, devices=all for DualSense hidraw.
packaging/flatpak (new):
- io.unom.Punktfunk.yml on GNOME 50 / freedesktop-sdk 25.08. rust-stable//25.08
(rustc 1.96 — the GTK4 chain needs >=1.92; the EOL GNOME-48/24.08 rust-stable at
1.89 could not build it) + llvm20 (libclang for bindgen in ffmpeg-sys-next/sdl3-sys).
HEVC libavcodec comes from the runtime's auto codecs-extra extension point (no
app-side codec declaration). Bundled SDL3 3.4.10 (matches sdl3-sys 0.6.6+SDL-3.4.10).
finish-args: wayland/fallback-x11, --device=all (GPU/VAAPI + evdev + hidraw — flatpak
cannot bind /dev/hidrawN char devices via --filesystem), pulseaudio, network,
~/.config/punktfunk.
- metainfo.xml, desktop, square SVG icon, build-flatpak.sh (offline cargo-sources;
on-Deck org.flatpak.Builder or CI), README.
clients/decky:
- add LICENSE (MIT), fix package.json license (BSD-3-Clause -> Apache-2.0 OR MIT),
add scripts/{package.sh,deploy.sh} (the plugins dir is root-owned: stage to /tmp,
sudo install, restart plugin_loader), align the launcher fallback to the real
flatpak app id io.unom.Punktfunk, rewrite the install section.
.gitea/workflows:
- flatpak.yml: privileged Fedora container builds the bundle and publishes to the
Gitea generic registry (+ release attachment on tags).
- decky.yml: pnpm build -> store-layout zip -> registry (stable latest/ URL for
Decky "install from URL").
docs: packaging/README + packaging/flatpak/README.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
# Flatpak manifest for the native punktfunk Linux client (crate punktfunk-client-linux,
|
||||
# binary `punktfunk-client`). Built into a single-file `.flatpak` bundle and published to
|
||||
# Gitea's generic package registry (see .gitea/workflows/flatpak.yml + packaging/flatpak/README.md).
|
||||
#
|
||||
# Why flatpak for the CLIENT (the host stays an RPM/deb — see packaging/README.md "Why not
|
||||
# Flatpak"): on SteamOS the Steam Deck's /usr is read-only and image-based, so a bare
|
||||
# `punktfunk-client` binary in ~/.local/bin can't bring its own libadwaita / SDL3 (both
|
||||
# MISSING from the SteamOS system) — but flatpak is the Deck's native, update-survivable app
|
||||
# path (the user already runs Moonlight + chiaki-ng as flatpaks). Unlike the host, the client
|
||||
# is sandbox-friendly: it only needs the GPU render node, the host PipeWire socket, the
|
||||
# network, Wayland, hidraw for DualSense, and its config dir — all expressible as finish-args.
|
||||
#
|
||||
# Runtime: GNOME 50 ships GTK 4.20 and libadwaita 1.8 — both far exceed the crate floors
|
||||
# (gtk4 0.11 "v4_16", libadwaita 0.9 "v1_5"). GNOME 50 is built on freedesktop-sdk 25.08, so
|
||||
# `org.freedesktop.Sdk.Extension.rust-stable` resolves to //25.08 (rustc 1.96 — the GTK4 dep
|
||||
# chain, e.g. pango-sys 0.22, needs >= 1.92, which the older GNOME-48/24.08 rust-stable at 1.89
|
||||
# could NOT satisfy). GNOME 50 is also a *supported* runtime (GNOME 48 went EOL in March 2026).
|
||||
# libopus and the PipeWire client lib are in the freedesktop base; SDL3 is NOT, so it is built
|
||||
# from source as a bundled module.
|
||||
#
|
||||
# HEVC decode: the base runtime's libavcodec is a stripped build (no encumbered codecs). The
|
||||
# freedesktop runtime declares `org.freedesktop.Platform.codecs-extra` as a built-in extension
|
||||
# point (directory lib/x86_64-linux-gnu/codecs-extra, add-ld-path lib, auto-downloaded with the
|
||||
# runtime), whose full libavcodec.so.61 transparently shadows the base one at runtime. So HEVC
|
||||
# (software + VAAPI) works with NO app-side codec extension to declare — we just build against
|
||||
# the SDK's linkable libavcodec.so.61 and let the runtime swap in the capable build.
|
||||
app-id: io.unom.Punktfunk
|
||||
runtime: org.gnome.Platform
|
||||
runtime-version: '50'
|
||||
sdk: org.gnome.Sdk
|
||||
# Build-time SDK extensions:
|
||||
# - rust-stable: cargo/rustc 1.96 + the bundled mold linker (/usr/lib/sdk/rust-stable/bin).
|
||||
# - llvm20: provides libclang (/usr/lib/sdk/llvm20/lib), which bindgen needs — ffmpeg-sys-next
|
||||
# and sdl3-sys generate their FFI bindings via bindgen at build time. The base SDK ships no
|
||||
# clang/libclang, so without this the build panics ("Unable to find libclang").
|
||||
# Both are added to PATH / LIBCLANG_PATH in build-options below.
|
||||
sdk-extensions:
|
||||
- org.freedesktop.Sdk.Extension.rust-stable
|
||||
- org.freedesktop.Sdk.Extension.llvm20
|
||||
command: punktfunk-client
|
||||
|
||||
cleanup:
|
||||
- /include
|
||||
- /lib/pkgconfig
|
||||
- /lib/cmake
|
||||
- /share/aclocal
|
||||
- /man
|
||||
- /share/man
|
||||
- '*.a'
|
||||
- '*.la'
|
||||
|
||||
finish-args:
|
||||
# --- display ---
|
||||
- --socket=wayland # GTK4 native Wayland window (the client is Wayland-first)
|
||||
- --socket=fallback-x11 # Xwayland fallback when no Wayland socket is exposed
|
||||
- --share=ipc # required alongside X11 for shared-memory surfaces
|
||||
# --- GPU + all input devices ---
|
||||
# --device=all (not just --device=dri): covers the GPU render node (VAAPI HEVC decode + GL),
|
||||
# evdev joysticks, AND the hidraw CHAR devices SDL3's HIDAPI needs for DualSense touchpad/
|
||||
# motion/adaptive-triggers/lightbar. flatpak cannot bind individual /dev/hidrawN via
|
||||
# --filesystem (they are char devices — "unsupported type 0o20000"), and there is no granular
|
||||
# --device=hidraw; --device=all is what game/emulator flatpaks (RetroArch, Dolphin) use. We
|
||||
# self-host via the Gitea generic registry — NOT Flathub — so its --device=all review rule
|
||||
# does not apply.
|
||||
- --device=all
|
||||
- --filesystem=/run/udev:ro # SDL/HIDAPI enumerates devices via udev
|
||||
# --- audio: PipeWire via its PulseAudio shim — covers playback AND mic uplink. SteamOS
|
||||
# exposes PipeWire-pulse here; --socket=pulseaudio is the portable arg Moonlight/chiaki
|
||||
# also use on the Deck (a bare --socket=pipewire would also need the camera/portal dance
|
||||
# for capture; the pulse shim gives mic + speaker in one grant). ---
|
||||
- --socket=pulseaudio
|
||||
# --- network: QUIC control + UDP data plane + mDNS discovery (_punktfunk._udp) ---
|
||||
- --share=network
|
||||
# --- persistent client identity / pairing store (shared with punktfunk-client-rs) ---
|
||||
- --filesystem=~/.config/punktfunk:create # client-{cert,key}.pem, known-hosts, settings
|
||||
|
||||
build-options:
|
||||
append-path: /usr/lib/sdk/rust-stable/bin:/usr/lib/sdk/llvm20/bin
|
||||
# The rust build resolves everything via pkg-config: gtk4/libadwaita/pipewire/opus AND a
|
||||
# linkable libavcodec.so.61 from org.gnome.Sdk//50 (the multiarch /usr dir), plus the bundled
|
||||
# SDL3's .pc from /app. (At runtime the codecs-extra extension swaps in the HEVC-capable
|
||||
# libavcodec — see the header.)
|
||||
env:
|
||||
PKG_CONFIG_PATH: /app/lib/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig
|
||||
# bindgen (ffmpeg-sys-next / sdl3-sys) loads libclang from the llvm20 extension.
|
||||
LIBCLANG_PATH: /usr/lib/sdk/llvm20/lib
|
||||
# mold (shipped in rust-stable) speeds the ~450-crate link on the Deck APU.
|
||||
RUSTFLAGS: -C link-arg=-fuse-ld=mold
|
||||
|
||||
modules:
|
||||
# ---------------------------------------------------------------------------------------
|
||||
# SDL3 — NOT provided as a linkable libSDL3.so.0 by org.gnome.Platform/freedesktop-sdk
|
||||
# 25.08, and there is no SDL3 recipe in flathub/shared-modules. Build it from source.
|
||||
# Pinned to 3.4.10 to match the crate exactly: sdl3-sys is `0.6.6+SDL-3.4.10`, i.e. its
|
||||
# bindings target SDL 3.4.10 — building an older SDL risks missing symbols at link time.
|
||||
# HIDAPI is enabled (DualSense touchpad/motion/triggers/lightbar over hidraw).
|
||||
# ---------------------------------------------------------------------------------------
|
||||
- name: sdl3
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
- -DSDL_SHARED=ON
|
||||
- -DSDL_STATIC=OFF
|
||||
- -DSDL_HIDAPI=ON # DualSense full fidelity over hidraw
|
||||
- -DSDL_TEST_LIBRARY=OFF
|
||||
- -DSDL_EXAMPLES=OFF
|
||||
sources:
|
||||
- type: archive
|
||||
url: https://github.com/libsdl-org/SDL/releases/download/release-3.4.10/SDL3-3.4.10.tar.gz
|
||||
# `sha256sum SDL3-3.4.10.tar.gz` (verified 2026-06-15). Bump url + sha together.
|
||||
sha256: 12b34280415ec8418c864408b93d008a20a6530687ee613d60bfbd20411f2785
|
||||
x-checker-data:
|
||||
type: anitya
|
||||
project-id: 4974
|
||||
stable-only: true
|
||||
url-template: https://github.com/libsdl-org/SDL/releases/download/release-$version/SDL3-$version.tar.gz
|
||||
cleanup:
|
||||
- /bin
|
||||
- /include
|
||||
- /lib/cmake
|
||||
- /lib/pkgconfig
|
||||
|
||||
# ---------------------------------------------------------------------------------------
|
||||
# The client. cargo-sources.json is the GENERATED offline crate cache:
|
||||
# python3 flatpak-cargo-generator.py Cargo.lock -o packaging/flatpak/cargo-sources.json
|
||||
# (run from the repo root; the CI step does exactly this). With it present the build is fully
|
||||
# offline (CARGO_NET_OFFLINE). For quick LOCAL iteration WITHOUT regenerating it, drop the
|
||||
# cargo-sources.json source and pass --build-args=--share=network to flatpak-builder
|
||||
# (non-reproducible; cargo fetches from crates.io during the build).
|
||||
# ---------------------------------------------------------------------------------------
|
||||
- name: punktfunk-client
|
||||
buildsystem: simple
|
||||
build-options:
|
||||
env:
|
||||
CARGO_HOME: /run/build/punktfunk-client/cargo
|
||||
CARGO_NET_OFFLINE: 'true'
|
||||
build-commands:
|
||||
- cargo --offline build --release --locked -p punktfunk-client-linux
|
||||
- install -Dm0755 target/release/punktfunk-client ${FLATPAK_DEST}/bin/punktfunk-client
|
||||
# Desktop entry (renamed to the app id; Exec is the in-sandbox binary).
|
||||
- install -Dm0644 packaging/flatpak/io.unom.Punktfunk.desktop
|
||||
${FLATPAK_DEST}/share/applications/io.unom.Punktfunk.desktop
|
||||
# AppStream metainfo (required for a well-formed flatpak / Software listings).
|
||||
- install -Dm0644 packaging/flatpak/io.unom.Punktfunk.metainfo.xml
|
||||
${FLATPAK_DEST}/share/metainfo/io.unom.Punktfunk.metainfo.xml
|
||||
# Scalable icon named for the app id (GNOME runtime renders SVG via librsvg).
|
||||
- install -Dm0644 packaging/flatpak/io.unom.Punktfunk.svg
|
||||
${FLATPAK_DEST}/share/icons/hicolor/scalable/apps/io.unom.Punktfunk.svg
|
||||
sources:
|
||||
# The repo checkout. For a Flathub/published build, replace with a pinned git source:
|
||||
# - type: git
|
||||
# url: https://git.unom.io/unom/punktfunk
|
||||
# tag: vX.Y.Z
|
||||
# commit: <sha>
|
||||
# For ON-DECK / CI builds we build the checked-out working tree in place:
|
||||
- type: dir
|
||||
path: ../..
|
||||
# Generated offline crate cache (see the comment block above). Remove for --share=network.
|
||||
- cargo-sources.json
|
||||
Reference in New Issue
Block a user