mirror of
https://github.com/vitorpamplona/amethyst.git
synced 2026-07-22 07:48:27 +00:00
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-<version>-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 <release> 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 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GYfNxhPZC3WRrn82Dm2Cb4
This commit is contained in:
51
.github/workflows/create-release.yml
vendored
51
.github/workflows/create-release.yml
vendored
@@ -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 <release> entry for this build (the checked-in
|
||||
# metainfo deliberately carries none — CI is the source of truth).
|
||||
sed -i "s|<releases>|<releases>\n <release version=\"${VER}\" date=\"$(date -u +%F)\" />|" \
|
||||
"${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
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -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/
|
||||
|
||||
16
BUILDING.md
16
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:
|
||||
| `<version>` | Tag stripped of leading `vX.YY.ZZ` |
|
||||
| `<family>` | `macos`, `windows`, `linux` |
|
||||
| `<arch>` | `x64`, `arm64` |
|
||||
| `<ext>` | `dmg`, `msi`, `zip`, `deb`, `rpm`, `AppImage`, `tar.gz` |
|
||||
| `<ext>` | `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`<br>`~/Library/Preferences/com.vitorpamplona.amethyst.desktop.plist`<br>`~/Library/Caches/Amethyst` |
|
||||
| Windows | `%LOCALAPPDATA%\Amethyst` or `C:\Program Files\Amethyst` | `%APPDATA%\Amethyst`<br>`%LOCALAPPDATA%\Amethyst` |
|
||||
| Linux (deb/rpm) | `/opt/amethyst` | `~/.config/amethyst`<br>`~/.local/share/amethyst`<br>`~/.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
|
||||
|
||||
---
|
||||
|
||||
@@ -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-<version>-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 `<release>` 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
|
||||
|
||||
@@ -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
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 16 KiB |
@@ -8,7 +8,7 @@
|
||||
# <version> = tag stripped of leading 'v' (e.g. "1.08.0")
|
||||
# <family> = macos | windows | linux
|
||||
# <arch> = x64 | arm64
|
||||
# <ext> = dmg | msi | zip | deb | rpm | AppImage | tar.gz
|
||||
# <ext> = 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
|
||||
|
||||
Reference in New Issue
Block a user