From f7926a287f7dc10df0dcfe8f943f61e6c536679b Mon Sep 17 00:00:00 2001 From: lincube Date: Thu, 25 Jun 2026 16:18:06 +0800 Subject: [PATCH] feat: add AppImage and Flatpak packaging support - Add AppImage build using linuxdeploy - Add Flatpak build using flatpak-builder - Create AppRun script for .NET runtime sharing - Create Flatpak manifest and desktop file - Integrate both formats into release workflow - Upload .AppImage and .flatpak as release artifacts This provides comprehensive Linux packaging support: - DEB: For Debian/Ubuntu systems - Linglong: For Deepin/UOS systems - AppImage: Universal Linux format (download and run) - Flatpak: Universal Linux format (sandboxed) All formats share the same .NET runtime for efficiency. --- .github/workflows/release.yml | 160 ++++++++++++++++++ packaging/linux/AppImage/AppRun | 22 +++ .../Flatpak/com.lanmountain.desktop.desktop | 10 ++ .../linux/Flatpak/com.lanmountain.desktop.yml | 54 ++++++ 4 files changed, 246 insertions(+) create mode 100644 packaging/linux/AppImage/AppRun create mode 100644 packaging/linux/Flatpak/com.lanmountain.desktop.desktop create mode 100644 packaging/linux/Flatpak/com.lanmountain.desktop.yml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fb0b1de..16a6fcf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -670,6 +670,164 @@ jobs: echo "Warning: Linglong package not found after build" fi + - name: Build AppImage + run: | + version="${{ needs.prepare.outputs.version }}" + publishDir="publish/linux-x64" + appimageDir="build-appimage" + release_dir="$PWD/release-assets" + + mkdir -p "$appimageDir" "$release_dir" + + # Download linuxdeploy + wget -q "https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage" -O linuxdeploy + chmod +x linuxdeploy + + # Prepare AppDir structure + mkdir -p "$appimageDir/AppDir/usr/bin" + mkdir -p "$appimageDir/AppDir/usr/share/applications" + mkdir -p "$appimageDir/AppDir/usr/share/icons/hicolor/256x256/apps" + + # Copy application files + cp -r "$publishDir"/* "$appimageDir/AppDir/usr/bin/" + + # Create desktop file + cat > "$appimageDir/AppDir/LanMountainDesktop.desktop" << EOF + [Desktop Entry] + Type=Application + Version=1.0 + Name=LanMountainDesktop + Comment=LanMountainDesktop desktop shell + Exec=LanMountainDesktop.Launcher %U + Icon=lanmountaindesktop + Terminal=false + Categories=Utility;Education; + StartupWMClass=LanMountainDesktop + EOF + + # Copy icon + cp LanMountainDesktop/packaging/linux/lanmountaindesktop.png "$appimageDir/AppDir/" + cp LanMountainDesktop/packaging/linux/lanmountaindesktop.png \ + "$appimageDir/AppDir/usr/share/icons/hicolor/256x256/apps/" + + # Create AppRun script + cat > "$appimageDir/AppDir/AppRun" << 'APPRUN' + #!/bin/bash + SELF=$(readlink -f "$0") + HERE="${SELF%/*}" + + # Find the app directory with .NET runtime + APP_DIR="" + for dir in "$HERE/usr/bin"/app-*; do + if [ -d "$dir" ] && [ -f "$dir/LanMountainDesktop.dll" ]; then + APP_DIR="$dir" + break + fi + done + + if [ -n "$APP_DIR" ]; then + export DOTNET_ROOT="$APP_DIR" + export PATH="$DOTNET_ROOT:$PATH" + fi + + exec "$HERE/usr/bin/LanMountainDesktop.Launcher" "$@" + APPRUN + chmod +x "$appimageDir/AppDir/AppRun" + + # Build AppImage + cd "$appimageDir" + ../linuxdeploy --appdir AppDir --output appimage || { + echo "Warning: AppImage build failed" + exit 0 + } + + # Move to release assets + mv LanMountainDesktop-*.AppImage "$release_dir/" 2>/dev/null || \ + echo "Warning: AppImage not found after build" + + - name: Build Flatpak + run: | + version="${{ needs.prepare.outputs.version }}" + publishDir="publish/linux-x64" + flatpakDir="build-flatpak" + release_dir="$PWD/release-assets" + + mkdir -p "$flatpakDir" "$release_dir" + + # Install Flatpak tools + sudo apt-get update + sudo apt-get install -y flatpak flatpak-builder + + # Add Flathub repository + flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo || true + + # Create Flatpak manifest + cat > "$flatpakDir/com.lanmountain.desktop.yml" << EOF + app-id: com.lanmountain.desktop + runtime: org.freedesktop.Platform + runtime-version: '23.08' + sdk: org.freedesktop.Sdk + command: LanMountainDesktop.Launcher + + finish-args: + - --share=ipc + - --socket=x11 + - --socket=wayland + - --socket=pulseaudio + - --share=network + - --device=dri + - --filesystem=home + + modules: + - name: LanMountainDesktop + buildsystem: simple + build-commands: + - mkdir -p /app/bin + - cp -r * /app/bin/ + - install -Dm755 LanMountainDesktop.Launcher /app/bin/LanMountainDesktop.Launcher + - install -Dm644 LanMountainDesktop.desktop /app/share/applications/com.lanmountain.desktop.desktop + - install -Dm644 lanmountaindesktop.png /app/share/icons/hicolor/256x256/apps/com.lanmountain.desktop.png + sources: + - type: dir + path: . + EOF + + # Prepare source directory + mkdir -p "$flatpakDir/source" + cp -r "$publishDir"/* "$flatpakDir/source/" + + # Create desktop file + cat > "$flatpakDir/source/LanMountainDesktop.desktop" << EOF + [Desktop Entry] + Type=Application + Version=1.0 + Name=LanMountainDesktop + Comment=LanMountainDesktop desktop shell + Exec=LanMountainDesktop.Launcher %U + Icon=com.lanmountain.desktop + Terminal=false + Categories=Utility;Education; + StartupWMClass=LanMountainDesktop + EOF + + # Copy icon + cp LanMountainDesktop/packaging/linux/lanmountaindesktop.png \ + "$flatpakDir/source/" + + # Build Flatpak + cd "$flatpakDir" + flatpak-builder --force-clean --repo=repo build com.lanmountain.desktop.yml || { + echo "Warning: Flatpak build failed" + exit 0 + } + + # Create Flatpak bundle + flatpak build-bundle repo "$release_dir/LanMountainDesktop-${version}-linux-x64.flatpak" \ + com.lanmountain.desktop || { + echo "Warning: Flatpak bundle creation failed" + exit 0 + } + - name: Package Payload Zip run: | version="${{ needs.prepare.outputs.version }}" @@ -702,6 +860,8 @@ jobs: path: | release-assets/files-linux-x64.zip release-assets/*.linglong + release-assets/*.AppImage + release-assets/*.flatpak *.deb if-no-files-found: error retention-days: 30 diff --git a/packaging/linux/AppImage/AppRun b/packaging/linux/AppImage/AppRun new file mode 100644 index 0000000..8004e39 --- /dev/null +++ b/packaging/linux/AppImage/AppRun @@ -0,0 +1,22 @@ +#!/bin/bash +# AppImage entry point for LanMountainDesktop + +SELF=$(readlink -f "$0") +HERE="${SELF%/*}" + +# Find the app directory with .NET runtime +APP_DIR="" +for dir in "$HERE/usr/bin"/app-*; do + if [ -d "$dir" ] && [ -f "$dir/LanMountainDesktop.dll" ]; then + APP_DIR="$dir" + break + fi +done + +if [ -n "$APP_DIR" ]; then + export DOTNET_ROOT="$APP_DIR" + export PATH="$DOTNET_ROOT:$PATH" +fi + +# Launch the application +exec "$HERE/usr/bin/LanMountainDesktop.Launcher" "$@" diff --git a/packaging/linux/Flatpak/com.lanmountain.desktop.desktop b/packaging/linux/Flatpak/com.lanmountain.desktop.desktop new file mode 100644 index 0000000..d508797 --- /dev/null +++ b/packaging/linux/Flatpak/com.lanmountain.desktop.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Type=Application +Version=1.0 +Name=LanMountainDesktop +Comment=LanMountainDesktop desktop shell +Exec=LanMountainDesktop.Launcher %U +Icon=com.lanmountain.desktop +Terminal=false +Categories=Utility;Education; +StartupWMClass=LanMountainDesktop diff --git a/packaging/linux/Flatpak/com.lanmountain.desktop.yml b/packaging/linux/Flatpak/com.lanmountain.desktop.yml new file mode 100644 index 0000000..cfcf6df --- /dev/null +++ b/packaging/linux/Flatpak/com.lanmountain.desktop.yml @@ -0,0 +1,54 @@ +app-id: com.lanmountain.desktop +runtime: org.freedesktop.Platform +runtime-version: '23.08' +sdk: org.freedesktop.Sdk +command: LanMountainDesktop.Launcher + +finish-args: + # X11 + XShm access + - --share=ipc + - --socket=x11 + # Wayland access + - --socket=wayland + # GPU acceleration + - --device=dri + # Audio access + - --socket=pulseaudio + # Network access + - --share=network + # Home directory access + - --filesystem=home + # D-Bus access for desktop integration + - --talk-name=org.freedesktop.Notifications + - --talk-name=org.kde.StatusNotifierWatcher + +modules: + - name: LanMountainDesktop + buildsystem: simple + build-commands: + # Create directory structure + - mkdir -p /app/bin + - mkdir -p /app/lib + - mkdir -p /app/share/applications + - mkdir -p /app/share/icons/hicolor/256x256/apps + + # Copy application files + - cp -r publish/linux-x64/app-*/* /app/lib/ + - cp publish/linux-x64/LanMountainDesktop.Launcher /app/bin/ + - cp publish/linux-x64/LanMountainDesktop.AirAppRuntime /app/bin/ + - cp publish/linux-x64/LanMountainDesktop.AirAppRuntime.dll /app/lib/ + + # Copy AirAppHost if exists + - if [ -d "publish/linux-x64/AirAppHost" ]; then cp -r publish/linux-x64/AirAppHost /app/lib/; fi + + # Set permissions + - chmod +x /app/bin/* + + # Install desktop file + - install -Dm644 packaging/linux/Flatpak/com.lanmountain.desktop.desktop /app/share/applications/com.lanmountain.desktop.desktop + + # Install icon + - install -Dm644 packaging/linux/lanmountaindesktop.png /app/share/icons/hicolor/256x256/apps/com.lanmountain.desktop.png + sources: + - type: dir + path: ../../..