Compare commits

...

3 Commits

Author SHA1 Message Date
lincube
6ef96168c1 refactor: integrate Linglong packaging into release workflow
- Remove separate linglong-build.yml workflow
- Add Linglong build steps to release.yml build-linux job
- Linglong package is now built alongside DEB package
- Upload Linglong package as release artifact

This integrates the Linglong packaging into the existing release workflow
for better maintainability and consistency with other package formats.
2026-06-25 03:24:22 +08:00
lincube
c534f06532 feat: add Linglong (玲珑) packaging support
- Add linglong.yaml configuration file for Linglong package format
- Add GitHub Actions workflow for automated Linglong package building
- Support self-contained .NET deployment with shared runtime
- Follow Linglong application conventions and Freedesktop standards

This enables distribution on Deepin/UOS systems via the Linglong package
manager, providing a modern containerized application format for Linux.

Features:
- Automated build triggered on release or manual dispatch
- Shared .NET runtime between Main App and AirAppRuntime
- Proper desktop file and icon integration
- Package validation and artifact upload
2026-06-25 03:17:24 +08:00
lincube
228819db01 feat: share .NET runtime between Main App and AirAppRuntime on Linux
- Create wrapper script for AirAppRuntime that sets DOTNET_ROOT
- AirAppRuntime now uses the .NET runtime from the main app directory
- Reduces package size by avoiding duplicate .NET runtime files
- Improves compatibility for Linux packaging formats (DEB, Linglong)

This change ensures that on Linux, AirAppRuntime shares the self-contained
.NET runtime from the main application instead of requiring a system-wide
.NET installation.
2026-06-25 00:33:49 +08:00
2 changed files with 162 additions and 2 deletions

View File

@@ -528,8 +528,37 @@ jobs:
fi fi
if [ -d "$runtimeDir" ]; then if [ -d "$runtimeDir" ]; then
cp -r "$runtimeDir"/* "$publishDir/" # Move the DLL to the publish directory
chmod +x "$publishDir/LanMountainDesktop.AirAppRuntime" 2>/dev/null || true cp "$runtimeDir/LanMountainDesktop.AirAppRuntime.dll" "$publishDir/"
# Create a wrapper script that uses the shared .NET runtime from the main app
printf '%s\n' '#!/bin/sh' > "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '# LanMountainDesktop AirAppRuntime wrapper script' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '# This script sets DOTNET_ROOT to use the shared .NET runtime from the main app' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '# Find the main app directory (contains the .NET runtime)' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'APP_DIR=""' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'for dir in "$SCRIPT_DIR"/app-*; do' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' ' if [ -d "$dir" ] && [ -f "$dir/LanMountainDesktop.dll" ]; then' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' ' APP_DIR="$dir"' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' ' break' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' ' fi' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'done' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'if [ -z "$APP_DIR" ]; then' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' ' echo "Error: Could not find main application directory with .NET runtime"' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' ' exit 1' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'fi' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '# Set DOTNET_ROOT to use the shared runtime' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'export DOTNET_ROOT="$APP_DIR"' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'export PATH="$DOTNET_ROOT:$PATH"' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' '# Run the AirAppRuntime using the shared runtime' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
printf '%s\n' 'exec dotnet "$SCRIPT_DIR/LanMountainDesktop.AirAppRuntime.dll" "$@"' >> "$publishDir/LanMountainDesktop.AirAppRuntime"
chmod +x "$publishDir/LanMountainDesktop.AirAppRuntime"
fi fi
touch "$publishDir/$appDir/.current" touch "$publishDir/$appDir/.current"
@@ -589,6 +618,58 @@ jobs:
dpkg-deb --build "build-deb" "${package_name}_${package_version}_${arch}.deb" dpkg-deb --build "build-deb" "${package_name}_${package_version}_${arch}.deb"
- name: Install Linglong build tools
run: |
# Install Linglong builder tools
curl -fsSL https://deepin-community.github.io/linglong-tools/install.sh | bash || {
echo "Warning: Failed to install Linglong tools, skipping Linglong build"
echo "LINGLONG_AVAILABLE=false" >> $GITHUB_ENV
}
# Verify installation
if command -v ll-builder &> /dev/null; then
ll-builder --version
echo "LINGLONG_AVAILABLE=true" >> $GITHUB_ENV
else
echo "LINGLONG_AVAILABLE=false" >> $GITHUB_ENV
fi
- name: Package as Linglong
if: env.LINGLONG_AVAILABLE == 'true'
run: |
version="${{ needs.prepare.outputs.version }}"
publishDir="publish/linux-x64"
linglongDir="build-linglong"
# Create Linglong build directory
mkdir -p "$linglongDir"
# Copy linglong.yaml and update version
cp packaging/linglong/linglong.yaml "$linglongDir/"
sed -i "s/version: .*/version: ${version}/" "$linglongDir/linglong.yaml"
# Create project structure for Linglong build
mkdir -p "$linglongDir/project"
cp -r "$publishDir" "$linglongDir/project/"
cp -r LanMountainDesktop/packaging "$linglongDir/project/LanMountainDesktop/"
# Build Linglong package
cd "$linglongDir"
ll-builder build || {
echo "Warning: Linglong build failed"
exit 0
}
# Find and copy the generated package
LINGLONG_PKG=$(find . -name "*.uab" -o -name "*.linglong" 2>/dev/null | head -1)
if [ -n "$LINGLONG_PKG" ]; then
mkdir -p "$PWD/../release-assets"
cp "$LINGLONG_PKG" "$PWD/../release-assets/LanMountainDesktop-${version}-linux-x64.linglong"
echo "Linglong package created successfully"
else
echo "Warning: Linglong package not found after build"
fi
- name: Package Payload Zip - name: Package Payload Zip
run: | run: |
version="${{ needs.prepare.outputs.version }}" version="${{ needs.prepare.outputs.version }}"
@@ -620,6 +701,7 @@ jobs:
name: release-linux-x64 name: release-linux-x64
path: | path: |
release-assets/files-linux-x64.zip release-assets/files-linux-x64.zip
release-assets/*.linglong
*.deb *.deb
if-no-files-found: error if-no-files-found: error
retention-days: 30 retention-days: 30

View File

@@ -0,0 +1,78 @@
version: '1'
package:
id: com.lanmountain.desktop
name: LanMountainDesktop
version: 0.8.8.4
kind: app
description: |
LanMountainDesktop - A modern desktop shell for education.
Features include schedule management, notifications, plugins, and more.
command:
- /opt/apps/com.lanmountain.desktop/files/bin/LanMountainDesktop.Launcher
base: org.deepin.foundation/23.0.0
sources:
- kind: local
name: "LanMountainDesktop"
build: |
# Create directory structure following Linglong conventions
mkdir -p ${PREFIX}/bin
mkdir -p ${PREFIX}/lib
mkdir -p ${PREFIX}/share/applications
mkdir -p ${PREFIX}/share/icons/hicolor/128x128/apps
mkdir -p ${PREFIX}/share/icons/hicolor/256x256/apps
mkdir -p ${PREFIX}/share/icons/hicolor/scalable/apps
# Copy the pre-built application files
# The build artifacts should be in /project/publish/linux-x64
if [ -d "/project/publish/linux-x64" ]; then
# Copy main application (includes .NET runtime)
cp -r /project/publish/linux-x64/app-*/* ${PREFIX}/lib/
# Copy Launcher (AOT compiled, independent)
cp /project/publish/linux-x64/LanMountainDesktop.Launcher ${PREFIX}/bin/
chmod +x ${PREFIX}/bin/LanMountainDesktop.Launcher
# Copy AirAppRuntime wrapper and DLL
cp /project/publish/linux-x64/LanMountainDesktop.AirAppRuntime ${PREFIX}/bin/
cp /project/publish/linux-x64/LanMountainDesktop.AirAppRuntime.dll ${PREFIX}/lib/
chmod +x ${PREFIX}/bin/LanMountainDesktop.AirAppRuntime
# Copy AirAppHost
if [ -d "/project/publish/linux-x64/AirAppHost" ]; then
cp -r /project/publish/linux-x64/AirAppHost ${PREFIX}/lib/
fi
else
echo "Error: Build artifacts not found at /project/publish/linux-x64"
exit 1
fi
# Create desktop file using printf to avoid heredoc issues
printf '%s\n' '[Desktop Entry]' > ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Type=Application' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Version=1.0' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Name=LanMountainDesktop' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Comment=LanMountainDesktop desktop shell' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Exec=/opt/apps/com.lanmountain.desktop/files/bin/LanMountainDesktop.Launcher %U' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Icon=lanmountaindesktop' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Terminal=false' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'Categories=Utility;Education;' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
printf '%s\n' 'StartupWMClass=LanMountainDesktop' >> ${PREFIX}/share/applications/com.lanmountain.desktop.desktop
# Copy icon files
if [ -f "/project/LanMountainDesktop/packaging/linux/lanmountaindesktop.png" ]; then
cp /project/LanMountainDesktop/packaging/linux/lanmountaindesktop.png \
${PREFIX}/share/icons/hicolor/256x256/apps/
cp /project/LanMountainDesktop/packaging/linux/lanmountaindesktop.png \
${PREFIX}/share/icons/hicolor/128x128/apps/
fi
# Set executable permissions
chmod +x ${PREFIX}/bin/*
chmod +x ${PREFIX}/lib/LanMountainDesktop.AirAppRuntime 2>/dev/null || true
echo "Linglong build completed successfully"