From 7e78204336f9ea195ca9ae11800a40d3f0780b19 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 14 Jul 2026 14:06:37 +0000 Subject: [PATCH] feat: ship a Flatpak bundle of the desktop app on release CI The linux-portable release leg now wraps the createReleaseDistributable tree it already builds into a single-file Flatpak bundle and attaches it to the GH Release as amethyst-desktop--linux-x64.flatpak. Packaging fixes to the existing (previously unwired) Flathub manifest: - add the missing 512x512 icon (copy of desktopApp icon.png) and install it under hicolor/512x512 instead of the never-present 256px path - drop the openjdk module + sdk-extension: the jpackage tree bundles its own trimmed JRE, so /app/jre was pure bloat - grant --socket=x11 instead of wayland/fallback-x11: Compose Desktop renders via AWT/skiko (X11-only on Linux, XWayland on Wayland), so fallback-x11 left the app socketless on Wayland sessions CI wiring: - install flatpak tooling + the freedesktop runtime/sdk (version greped from the manifest so the pin can't drift), retried like other fetches - inject the AppStream entry for the tagged version at build time (the checked-in metainfo deliberately carries none) - flatpak-builder with --disable-rofiles-fuse (GH runners) and a --state-dir under desktopApp/build so the repo tree stays clean - collect via the existing asset-name.sh contract (new flatpak ext) Verified end-to-end locally: built the bundle from the manifest with a stubbed jpackage tree, installed it, and ran the exported command inside the sandbox (freedesktop 24.08, args forwarded through the wrapper). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01GYfNxhPZC3WRrn82Dm2Cb4 --- .github/workflows/create-release.yml | 51 ++++++++++- .gitignore | 5 + BUILDING.md | 16 +++- desktopApp/packaging/flatpak/README.md | 86 ++++++++++++------ .../com.vitorpamplona.amethyst.Desktop.yml | 24 ++--- .../com.vitorpamplona.amethyst.Desktop.png | Bin 0 -> 16645 bytes scripts/asset-name.sh | 4 +- 7 files changed, 144 insertions(+), 42 deletions(-) create mode 100644 desktopApp/packaging/flatpak/icons/512/com.vitorpamplona.amethyst.Desktop.png diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 8442a8942b..4236fa6955 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -44,7 +44,7 @@ jobs: - { os: ubuntu-latest, arch: x64, family: linux, tasks: "packageReleaseDeb packageReleaseRpm" } - { os: ubuntu-latest, arch: x64, family: linux-portable, tasks: "createReleaseAppImage createReleaseDistributable" } runs-on: ${{ matrix.os }} - timeout-minutes: 45 + timeout-minutes: 60 # linux-portable leg also downloads the freedesktop runtime + builds the Flatpak bundle defaults: run: shell: bash @@ -101,6 +101,25 @@ jobs: fi chmod +x desktopApp/packaging/appimage/appimagetool-x86_64.AppImage + # Flatpak tooling + the freedesktop runtime/sdk the manifest pins + # (runtime-version is greped from the manifest so this never drifts). + # Retried: the runtime download from Flathub is ~1 GB and flatpak + # install resumes cleanly on re-run. + - name: Install Flatpak tooling + runtimes (linux-portable only) + if: matrix.family == 'linux-portable' + uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v4.0.0 + with: + max_attempts: 3 + timeout_minutes: 15 + command: | + set -euo pipefail + sudo apt-get update && sudo apt-get install -y flatpak flatpak-builder + flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + FDO_VER=$(grep -E "^runtime-version:" desktopApp/packaging/flatpak/com.vitorpamplona.amethyst.Desktop.yml | cut -d"'" -f2) + flatpak install --user --noninteractive flathub \ + "org.freedesktop.Platform//${FDO_VER}" \ + "org.freedesktop.Sdk//${FDO_VER}" + # macOS only: import the Developer ID Application cert into a throwaway # keychain so jpackage's codesign pass can find it. Soft — if the # MAC_CERTIFICATE_P12 secret isn't set (forks, or before Apple creds are @@ -161,6 +180,36 @@ jobs: ( cd "$APP" && tar czf "../../../../portable/amethyst-desktop-${VER}-linux-x64.tar.gz" Amethyst/ ) fi + # Flatpak bundle: wraps the same createReleaseDistributable tree the + # AppImage uses. The manifest (desktopApp/packaging/flatpak/) copies the + # prebuilt jpackage tree into /app — no Gradle runs inside the sandbox. + # build-bundle emits a single-file .flatpak whose baked-in runtime-repo + # lets the user's flatpak fetch the freedesktop runtime from Flathub on + # install. --disable-rofiles-fuse: GH runners lack a usable rofiles-fuse. + - name: Build Flatpak bundle (linux-portable only) + if: matrix.family == 'linux-portable' + run: | + set -euo pipefail + VER="${{ steps.ver.outputs.version }}" + PKG="desktopApp/packaging/flatpak" + APP_ID="com.vitorpamplona.amethyst.Desktop" + OUT="desktopApp/build/flatpak" + # Inject the AppStream entry for this build (the checked-in + # metainfo deliberately carries none — CI is the source of truth). + sed -i "s||\n |" \ + "${PKG}/${APP_ID}.metainfo.xml" + mkdir -p "$OUT" + flatpak-builder --user --force-clean --disable-rofiles-fuse \ + --state-dir="${OUT}/.flatpak-builder" \ + --repo="${OUT}/repo" \ + "${OUT}/build-dir" \ + "${PKG}/${APP_ID}.yml" + flatpak build-bundle "${OUT}/repo" \ + "${OUT}/Amethyst-${VER}-x86_64.flatpak" \ + "$APP_ID" \ + --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo + ls -la "$OUT" + - name: Collect + rename assets run: | set -euo pipefail diff --git a/.gitignore b/.gitignore index 45f5f1d139..2616f94e70 100644 --- a/.gitignore +++ b/.gitignore @@ -180,6 +180,11 @@ desktopApp/src/jvmMain/appResources/*/ffmpeg/* desktopApp/packaging/appimage/appimagetool-x86_64.AppImage desktopApp/packaging/appimage/squashfs-root/ +# flatpak-builder state/cache from local builds (CI uses --state-dir under desktopApp/build/) +.flatpak-builder/ +desktopApp/packaging/flatpak/build-dir/ +desktopApp/packaging/flatpak/repo/ + # Git worktrees .worktrees/ .claude/worktrees/ diff --git a/BUILDING.md b/BUILDING.md index 54b6021e97..e719e3aad2 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -37,7 +37,9 @@ Platform-specific: - **macOS**: Xcode Command Line Tools (`xcode-select --install`) - **Windows**: WiX Toolset 3.x on PATH (for MSI). `winget install WiXToolset.WiXToolset` - **Linux (all)**: nothing extra for `.deb`; `rpm` + `fakeroot` for `.rpm`; - `appimagetool` + `desktop-file-utils` for AppImage + `appimagetool` + `desktop-file-utils` for AppImage; `flatpak` + + `flatpak-builder` for the Flatpak bundle (see + [`desktopApp/packaging/flatpak/README.md`](desktopApp/packaging/flatpak/README.md)) Install Linux RPM tooling: @@ -109,6 +111,7 @@ are **not** required to build Amethyst from the committed sources. | Linux `.deb` | `./gradlew :desktopApp:packageReleaseDeb` | `desktopApp/build/compose/binaries/main-release/deb/amethyst_*.deb` | | Linux `.rpm` | `./gradlew :desktopApp:packageReleaseRpm` | `desktopApp/build/compose/binaries/main-release/rpm/amethyst-*.rpm` | | Linux AppImage | `./gradlew :desktopApp:createReleaseAppImage` | `desktopApp/build/appimage/Amethyst-*-x86_64.AppImage` | +| Linux Flatpak | `flatpak-builder` over `createReleaseDistributable` output — see [`desktopApp/packaging/flatpak/README.md`](desktopApp/packaging/flatpak/README.md) | `desktopApp/build/flatpak/Amethyst-*-x86_64.flatpak` (CI) | | Windows `.zip` portable | See below (inline `7z`) | — | | Linux `.tar.gz` portable | See below (inline `tar`) | — | @@ -148,7 +151,7 @@ Where: | `` | Tag stripped of leading `vX.YY.ZZ` | | `` | `macos`, `windows`, `linux` | | `` | `x64`, `arm64` | -| `` | `dmg`, `msi`, `zip`, `deb`, `rpm`, `AppImage`, `tar.gz` | +| `` | `dmg`, `msi`, `zip`, `deb`, `rpm`, `AppImage`, `flatpak`, `tar.gz` | Single source of truth: [`scripts/asset-name.sh`](scripts/asset-name.sh). Package manager manifests (Homebrew cask, Winget) depend on this exact scheme — @@ -160,6 +163,7 @@ Examples: - `amethyst-desktop-1.12.1-macos-arm64.dmg` - `amethyst-desktop-1.12.1-windows-x64.msi` - `amethyst-desktop-1.12.1-linux-x64.AppImage` +- `amethyst-desktop-1.12.1-linux-x64.flatpak` --- @@ -625,12 +629,18 @@ State is shared across install channels (DMG, Homebrew, MSI, Winget, .deb, expose downgrade migration risks — **prefer a single install channel per machine**. +**Exception: Flatpak.** The sandbox redirects XDG dirs into +`~/.var/app/com.vitorpamplona.amethyst.Desktop/`, so a Flatpak install keeps +its own separate state and does not see (or risk downgrading) state written +by any other channel. + | OS | App location | State directories | |---|---|---| | macOS | `/Applications/Amethyst.app` | `~/Library/Application Support/Amethyst`
`~/Library/Preferences/com.vitorpamplona.amethyst.desktop.plist`
`~/Library/Caches/Amethyst` | | Windows | `%LOCALAPPDATA%\Amethyst` or `C:\Program Files\Amethyst` | `%APPDATA%\Amethyst`
`%LOCALAPPDATA%\Amethyst` | | Linux (deb/rpm) | `/opt/amethyst` | `~/.config/amethyst`
`~/.local/share/amethyst`
`~/.cache/amethyst` | | Linux (AppImage/tar.gz) | user-chosen | Same as above | +| Linux (Flatpak) | `/var/lib/flatpak` or `~/.local/share/flatpak` | `~/.var/app/com.vitorpamplona.amethyst.Desktop/` | Uninstall: @@ -639,6 +649,8 @@ Uninstall: - .deb: `sudo apt remove amethyst` - .rpm: `sudo dnf remove amethyst` - AppImage / tar.gz: delete the file / extracted directory +- Flatpak: `flatpak uninstall com.vitorpamplona.amethyst.Desktop` (add + `--delete-data` to also remove `~/.var/app/…`) - macOS `.dmg`: drag from `/Applications` to Trash, then delete state dirs manually --- diff --git a/desktopApp/packaging/flatpak/README.md b/desktopApp/packaging/flatpak/README.md index 12bf3f3c7a..c732506f48 100644 --- a/desktopApp/packaging/flatpak/README.md +++ b/desktopApp/packaging/flatpak/README.md @@ -1,44 +1,65 @@ -# Flathub packaging for Amethyst Desktop +# Flatpak packaging for Amethyst Desktop -This directory contains the Flatpak manifest and associated metadata for -publishing Amethyst Desktop on Flathub. +This directory contains the Flatpak manifest and associated metadata. It is +used two ways: + +1. **Release CI** (`.github/workflows/create-release.yml`, `linux-portable` + leg) builds a single-file bundle from it on every tag and attaches it to + the GitHub Release as `amethyst-desktop--linux-x64.flatpak`. +2. **Flathub submission** (future) — the same manifest is the starting + point, but Flathub requires building from downloadable sources instead of + the local `type: dir` tree, so it will need a source rewrite at + submission time. ## Files -- `com.vitorpamplona.amethyst.Desktop.yml` — Flatpak manifest -- `com.vitorpamplona.amethyst.Desktop.metainfo.xml` — AppStream metadata - (categories, license, screenshots — needs screenshots added before - submission) +- `com.vitorpamplona.amethyst.Desktop.yml` — Flatpak manifest. It packages + the **prebuilt** jpackage tree from + `./gradlew :desktopApp:createReleaseDistributable` (which bundles its own + trimmed JRE — that's why there is no openjdk module/sdk-extension). +- `com.vitorpamplona.amethyst.Desktop.metainfo.xml` — AppStream metadata. + Release CI injects the `` entry for the version being built + (the checked-in file deliberately carries none); screenshots still need + to be added before any Flathub submission. - `com.vitorpamplona.amethyst.Desktop.desktop` — XDG desktop entry -- `icons/256/com.vitorpamplona.amethyst.Desktop.png` — TODO: copy a 256x256 - PNG icon from `desktopApp/src/jvmMain/resources/icon.png` before - submission - -## Build prerequisites - -- `./gradlew :desktopApp:createReleaseDistributable` — produces - `desktopApp/build/compose/binaries/main-release/app/Amethyst/` -- `flatpak install org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 org.freedesktop.Sdk.Extension.openjdk21//24.08` +- `icons/512/com.vitorpamplona.amethyst.Desktop.png` — 512x512 icon (copy of + `desktopApp/src/jvmMain/resources/icon.png`) ## Local build ```bash +# 1. Build the app tree the manifest packages +./gradlew :desktopApp:createReleaseDistributable + +# 2. Tooling + Flathub remote (one-time) +sudo apt-get install -y flatpak flatpak-builder # or distro equivalent +flatpak remote-add --user --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo + +# 3. Build + install locally cd desktopApp/packaging/flatpak -flatpak-builder --user --install --force-clean build-dir com.vitorpamplona.amethyst.Desktop.yml +flatpak-builder --user --install --install-deps-from=flathub --force-clean \ + build-dir com.vitorpamplona.amethyst.Desktop.yml flatpak run com.vitorpamplona.amethyst.Desktop ``` -## Submission to Flathub +To produce the distributable single-file bundle instead (what CI ships): -Follow https://docs.flathub.org/docs/for-app-authors/submission +```bash +flatpak-builder --user --install-deps-from=flathub --force-clean \ + --repo=repo build-dir com.vitorpamplona.amethyst.Desktop.yml +flatpak build-bundle repo amethyst.flatpak com.vitorpamplona.amethyst.Desktop \ + --runtime-repo=https://dl.flathub.org/repo/flathub.flatpakrepo +``` -1. Fork `flathub/flathub` on GitHub. -2. Branch from `new-pr` (NOT `master`). -3. Copy this manifest + AppStream + desktop into a new directory matching - the app id. -4. Open a PR titled "Add com.vitorpamplona.amethyst.Desktop". -5. After merge, a per-app repo is created with write access for ongoing - updates. +Installing the bundle: `flatpak install --user ./amethyst.flatpak`. The +`--runtime-repo` baked in above lets flatpak fetch the freedesktop runtime +from Flathub automatically on the user's machine. + +## Sandbox notes + +- `--socket=x11` (not wayland/fallback-x11): Compose Desktop renders through + AWT/skiko, which is X11-only on Linux and runs under XWayland on Wayland + sessions. ## Codec coverage @@ -47,6 +68,19 @@ Follow https://docs.flathub.org/docs/for-app-authors/submission - HLS, H.264, AAC, MP3, Opus: covered by the GStreamer plugin set in `org.freedesktop.Platform 24.08` itself. +## Submission to Flathub + +Follow https://docs.flathub.org/docs/for-app-authors/submission + +1. Fork `flathub/flathub` on GitHub. +2. Branch from `new-pr` (NOT `master`). +3. Copy this manifest + AppStream + desktop into a new directory matching + the app id, and rework the `type: dir` source into a + buildable-from-source or downloadable-artifact form per Flathub policy. +4. Open a PR titled "Add com.vitorpamplona.amethyst.Desktop". +5. After merge, a per-app repo is created with write access for ongoing + updates. + ## License metadata The manifest declares the binary as diff --git a/desktopApp/packaging/flatpak/com.vitorpamplona.amethyst.Desktop.yml b/desktopApp/packaging/flatpak/com.vitorpamplona.amethyst.Desktop.yml index 8ed6f86207..79f44e226b 100644 --- a/desktopApp/packaging/flatpak/com.vitorpamplona.amethyst.Desktop.yml +++ b/desktopApp/packaging/flatpak/com.vitorpamplona.amethyst.Desktop.yml @@ -8,8 +8,6 @@ app-id: com.vitorpamplona.amethyst.Desktop runtime: org.freedesktop.Platform runtime-version: '24.08' sdk: org.freedesktop.Sdk -sdk-extensions: - - org.freedesktop.Sdk.Extension.openjdk21 command: amethyst-desktop add-extensions: @@ -26,8 +24,11 @@ cleanup-commands: finish-args: - --share=network - --share=ipc - - --socket=fallback-x11 - - --socket=wayland + # Compose Desktop renders through AWT/skiko, which is X11-only on Linux + # (runs under XWayland on Wayland sessions). fallback-x11 + wayland would + # leave the app without a usable display socket on Wayland sessions, so + # grant x11 unconditionally. + - --socket=x11 - --socket=pulseaudio - --device=dri - --filesystem=xdg-download @@ -37,12 +38,10 @@ finish-args: # GStreamer plugin/cache paths (org.freedesktop.Platform exposes them by default). - --env=GST_PLUGIN_SYSTEM_PATH=/usr/lib/x86_64-linux-gnu/gstreamer-1.0 +# No openjdk module / sdk-extension: the jpackage tree copied below already +# bundles its own trimmed JRE under Amethyst/lib/runtime/, so installing a +# second JRE at /app/jre would only bloat the bundle. modules: - - name: openjdk - buildsystem: simple - build-commands: - - /usr/lib/sdk/openjdk21/install.sh - - name: amethyst-desktop buildsystem: simple build-commands: @@ -53,7 +52,7 @@ modules: - install -Dm755 amethyst-desktop.sh /app/bin/amethyst-desktop - install -Dm644 com.vitorpamplona.amethyst.Desktop.metainfo.xml -t /app/share/metainfo/ - install -Dm644 com.vitorpamplona.amethyst.Desktop.desktop -t /app/share/applications/ - - install -Dm644 icons/256/com.vitorpamplona.amethyst.Desktop.png -t /app/share/icons/hicolor/256x256/apps/ + - install -Dm644 icons/512/com.vitorpamplona.amethyst.Desktop.png -t /app/share/icons/hicolor/512x512/apps/ sources: # Built artifact from `./gradlew :desktopApp:createReleaseDistributable`. # Path matches Compose Multiplatform 1.11's output layout. @@ -73,5 +72,6 @@ modules: - type: file path: com.vitorpamplona.amethyst.Desktop.desktop - - type: file - path: icons/256/com.vitorpamplona.amethyst.Desktop.png + - type: dir + path: icons + dest: icons diff --git a/desktopApp/packaging/flatpak/icons/512/com.vitorpamplona.amethyst.Desktop.png b/desktopApp/packaging/flatpak/icons/512/com.vitorpamplona.amethyst.Desktop.png new file mode 100644 index 0000000000000000000000000000000000000000..ffe89a16f0378d0e21e8ab3e1c8b2d46b4cf0b52 GIT binary patch literal 16645 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 = tag stripped of leading 'v' (e.g. "1.08.0") # = macos | windows | linux # = x64 | arm64 -# = dmg | msi | zip | deb | rpm | AppImage | tar.gz +# = dmg | msi | zip | deb | rpm | AppImage | flatpak | tar.gz # # Consumed by: .github/workflows/create-release.yml, .github/workflows/bump-*.yml, # BUILDING.md, local release runbooks. @@ -26,6 +26,7 @@ # amethyst-desktop-1.08.0-linux-x64.deb # amethyst-desktop-1.08.0-linux-x64.rpm # amethyst-desktop-1.08.0-linux-x64.AppImage +# amethyst-desktop-1.08.0-linux-x64.flatpak # amethyst-desktop-1.08.0-linux-x64.tar.gz # amy-1.08.0-macos-arm64.tar.gz # amy-1.08.0-macos-x64.tar.gz @@ -74,6 +75,7 @@ collect_assets() { desktopApp/build/compose/binaries/main-release/deb/*.deb \ desktopApp/build/compose/binaries/main-release/rpm/*.rpm \ desktopApp/build/appimage/*.AppImage \ + desktopApp/build/flatpak/*.flatpak \ desktopApp/build/portable/*.tar.gz \ desktopApp/build/portable/*.zip \ ; do