diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3cbe2d90..05a15771 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -405,6 +405,8 @@ jobs: build-linux-x64: runs-on: ubuntu-latest permissions: + id-token: write + attestations: write contents: read steps: - uses: actions/checkout@v4 @@ -427,13 +429,16 @@ jobs: - name: Cache APT packages uses: awalsh128/cache-apt-pkgs-action@latest with: - packages: clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev + packages: clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick version: 1.1 - name: Install Linux dependencies run: | sudo apt-get update - sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev + sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick + + - name: Install fpm + run: sudo gem install fpm - name: Install dependencies run: flutter pub get @@ -446,21 +451,33 @@ jobs: cd build/linux/x64/release/bundle tar -czf $GITHUB_WORKSPACE/plezy-linux-x64.tar.gz * - - name: Upload x64 build - uses: actions/upload-artifact@v4 - with: - name: linux-x64-build - path: build/linux/x64/release/bundle/ + - name: Build Linux Packages + run: ARCH_SUFFIX=x64 OUTPUT_DIR=$GITHUB_WORKSPACE python3 linux/packaging/build-packages.py - - name: Upload x64 tarball + - name: Attest Linux x64 artifacts + uses: actions/attest-build-provenance@v2 + with: + subject-path: | + plezy-linux-x64.tar.gz + plezy-linux-x64.deb + plezy-linux-x64.rpm + plezy-linux-x64.pkg.tar.zst + + - name: Upload Linux x64 artifacts uses: actions/upload-artifact@v4 with: - name: linux-x64-tarball - path: plezy-linux-x64.tar.gz + name: linux-x64 + path: | + plezy-linux-x64.tar.gz + plezy-linux-x64.deb + plezy-linux-x64.rpm + plezy-linux-x64.pkg.tar.zst build-linux-arm64: runs-on: ubuntu-24.04-arm permissions: + id-token: write + attestations: write contents: read steps: - uses: actions/checkout@v4 @@ -483,13 +500,16 @@ jobs: - name: Cache APT packages uses: awalsh128/cache-apt-pkgs-action@latest with: - packages: clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev + packages: clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick version: 1.1 - name: Install Linux dependencies run: | sudo apt-get update - sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev + sudo apt-get install -y clang cmake ninja-build pkg-config libgtk-3-dev liblzma-dev libstdc++-12-dev libasound2-dev libmpv-dev mpv libx11-dev libxext-dev libxrandr-dev libxcursor-dev libxi-dev libxss-dev libpulse-dev libdbus-1-dev libdrm-dev libgbm-dev libegl-dev libgl-dev libwayland-dev ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick + + - name: Install fpm + run: sudo gem install fpm - name: Install dependencies run: flutter pub get @@ -508,100 +528,34 @@ jobs: cd ${{ steps.find-bundle.outputs.bundle_dir }} tar -czf $GITHUB_WORKSPACE/plezy-linux-arm64.tar.gz * - - name: Upload arm64 build - uses: actions/upload-artifact@v4 - with: - name: linux-arm64-build - path: ${{ steps.find-bundle.outputs.bundle_dir }}/ - - - name: Upload arm64 tarball - uses: actions/upload-artifact@v4 - with: - name: linux-arm64-tarball - path: plezy-linux-arm64.tar.gz - - package-linux: - needs: [build-linux-x64, build-linux-arm64] - runs-on: ubuntu-latest - permissions: - id-token: write - attestations: write - contents: read - steps: - - uses: actions/checkout@v4 - - - name: Download x64 build - uses: actions/download-artifact@v4 - with: - name: linux-x64-build - path: build-x64 - - - name: Download arm64 build - uses: actions/download-artifact@v4 - with: - name: linux-arm64-build - path: build-arm64 - - - name: Download x64 tarball - uses: actions/download-artifact@v4 - with: - name: linux-x64-tarball - - - name: Download arm64 tarball - uses: actions/download-artifact@v4 - with: - name: linux-arm64-tarball - - - name: Cache APT packages - uses: awalsh128/cache-apt-pkgs-action@latest - with: - packages: ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick - version: 1.1 - - - name: Install packaging dependencies - run: | - sudo apt-get update - sudo apt-get install -y ruby ruby-dev rubygems build-essential rpm libarchive-tools imagemagick - - - name: Install fpm - run: sudo gem install fpm - - name: Build Linux Packages run: | - X64_BUILD_DIR=$GITHUB_WORKSPACE/build-x64 \ - ARM64_BUILD_DIR=$GITHUB_WORKSPACE/build-arm64 \ + BUILD_DIR=${{ steps.find-bundle.outputs.bundle_dir }} \ + ARCH_SUFFIX=arm64 \ OUTPUT_DIR=$GITHUB_WORKSPACE \ python3 linux/packaging/build-packages.py - - name: Attest Linux artifacts + - name: Attest Linux arm64 artifacts uses: actions/attest-build-provenance@v2 with: subject-path: | - plezy-linux-x64.tar.gz plezy-linux-arm64.tar.gz - plezy-linux.deb - plezy-linux.rpm - plezy-linux.pkg.tar.zst + plezy-linux-arm64.deb + plezy-linux-arm64.rpm + plezy-linux-arm64.pkg.tar.zst - - name: Upload Linux tarballs + - name: Upload Linux arm64 artifacts uses: actions/upload-artifact@v4 with: - name: linux-tarballs + name: linux-arm64 path: | - plezy-linux-x64.tar.gz plezy-linux-arm64.tar.gz - - - name: Upload Linux Packages - uses: actions/upload-artifact@v4 - with: - name: linux-packages - path: | - plezy-linux.deb - plezy-linux.rpm - plezy-linux.pkg.tar.zst + plezy-linux-arm64.deb + plezy-linux-arm64.rpm + plezy-linux-arm64.pkg.tar.zst create-release: - needs: [build-android, build-ios, build-macos, package-windows, package-linux] + needs: [build-android, build-ios, build-macos, package-windows, build-linux-x64, build-linux-arm64] runs-on: ubuntu-latest permissions: contents: write @@ -626,9 +580,8 @@ jobs: artifacts/windows-x64-portable/plezy-windows-x64-portable.7z artifacts/windows-arm64-portable/plezy-windows-arm64-portable.7z artifacts/windows-installer/plezy-windows-installer.exe - artifacts/linux-tarballs/plezy-linux-x64.tar.gz - artifacts/linux-tarballs/plezy-linux-arm64.tar.gz - artifacts/linux-packages/* + artifacts/linux-x64/* + artifacts/linux-arm64/* draft: true prerelease: false generate_release_notes: true diff --git a/linux/packaging/after-install.sh b/linux/packaging/after-install.sh index 682188b3..fc162852 100644 --- a/linux/packaging/after-install.sh +++ b/linux/packaging/after-install.sh @@ -1,4 +1,8 @@ #!/bin/bash +# Ensure binaries are executable +chmod +x /usr/bin/plezy +chmod +x /opt/plezy/plezy + # Update icon cache if command -v gtk-update-icon-cache &> /dev/null; then gtk-update-icon-cache -f -t /usr/share/icons/hicolor || true diff --git a/linux/packaging/build-packages.py b/linux/packaging/build-packages.py index 3b75f174..f985c5b1 100755 --- a/linux/packaging/build-packages.py +++ b/linux/packaging/build-packages.py @@ -8,11 +8,9 @@ from pathlib import Path # Paths SCRIPT_DIR = Path(__file__).parent.resolve() PROJECT_ROOT = SCRIPT_DIR.parent.parent +BUILD_DIR = Path(os.environ["BUILD_DIR"]) if "BUILD_DIR" in os.environ else PROJECT_ROOT / "build/linux/x64/release/bundle" OUTPUT_DIR = Path(os.environ.get("OUTPUT_DIR", PROJECT_ROOT)) - -# Build directories: use env vars if set, otherwise fall back to default Flutter paths -X64_BUILD_DIR = Path(os.environ["X64_BUILD_DIR"]) if "X64_BUILD_DIR" in os.environ else PROJECT_ROOT / "build/linux/x64/release/bundle" -ARM64_BUILD_DIR = Path(os.environ["ARM64_BUILD_DIR"]) if "ARM64_BUILD_DIR" in os.environ else PROJECT_ROOT / "build/linux/arm64/release/bundle" +ARCH_SUFFIX = os.environ.get("ARCH_SUFFIX", "x64") # Package metadata METADATA = { @@ -27,11 +25,16 @@ METADATA = { # Icon sizes to generate ICON_SIZES = [16, 32, 48, 64, 128, 256, 512] +# Architecture mappings per package format +ARCH_MAP = { + "x64": {"deb": "amd64", "rpm": "x86_64", "pacman": "x86_64"}, + "arm64": {"deb": "arm64", "rpm": "aarch64", "pacman": "aarch64"}, +} + # Distro-specific configuration DISTROS = { "deb": { "type": "deb", - "arch": "all", "category": "video", "ext": "deb", "compression": ["--deb-compression", "xz", "--deb-priority", "optional"], @@ -45,7 +48,6 @@ DISTROS = { }, "rpm": { "type": "rpm", - "arch": "noarch", "category": "Multimedia", "ext": "rpm", "compression": ["--rpm-compression", "xzmt"], @@ -59,7 +61,6 @@ DISTROS = { }, "pacman": { "type": "pacman", - "arch": "any", "category": None, "ext": "pkg.tar.zst", "compression": ["--pacman-compression", "zstd"], @@ -106,18 +107,11 @@ def generate_icons(): def get_file_mappings() -> list[str]: """Get file mappings for fpm.""" - mappings = [] - - # Map each available architecture bundle - if X64_BUILD_DIR.exists(): - mappings.append(f"{X64_BUILD_DIR}/=/opt/plezy/x64/") - if ARM64_BUILD_DIR.exists(): - mappings.append(f"{ARM64_BUILD_DIR}/=/opt/plezy/arm64/") - - mappings.extend([ + mappings = [ + f"{BUILD_DIR}/=/opt/plezy/", f"{SCRIPT_DIR}/com.edde746.plezy.desktop=/usr/share/applications/com.edde746.plezy.desktop", f"{SCRIPT_DIR}/plezy.sh=/usr/bin/plezy", - ]) + ] for size in ICON_SIZES: mappings.append( @@ -130,9 +124,10 @@ def get_file_mappings() -> list[str]: def build_package(distro: str, version: str): """Build a package for the specified distro.""" config = DISTROS[distro] - output_file = OUTPUT_DIR / f"{METADATA['name']}-linux.{config['ext']}" + arch = ARCH_MAP[ARCH_SUFFIX][distro] + output_file = OUTPUT_DIR / f"{METADATA['name']}-linux-{ARCH_SUFFIX}.{config['ext']}" - print(f"Building .{config['ext']} package...") + print(f"Building .{config['ext']} package ({arch})...") cmd = [ "fpm", @@ -146,7 +141,7 @@ def build_package(distro: str, version: str): "--maintainer", METADATA["maintainer"], "--url", METADATA["url"], "--description", METADATA["description"], - "--architecture", config["arch"], + "--architecture", arch, ] if config["category"]: @@ -170,24 +165,14 @@ def build_package(distro: str, version: str): def main(): - # Verify at least one build exists - has_x64 = X64_BUILD_DIR.exists() - has_arm64 = ARM64_BUILD_DIR.exists() - - if not has_x64 and not has_arm64: - print(f"Error: No build directories found") - print(f" x64: {X64_BUILD_DIR}") - print(f" arm64: {ARM64_BUILD_DIR}") - print("Please run 'flutter build linux --release' first or set X64_BUILD_DIR/ARM64_BUILD_DIR") + # Verify build exists + if not BUILD_DIR.exists(): + print(f"Error: Build directory not found at {BUILD_DIR}") + print("Please run 'flutter build linux --release' first or set BUILD_DIR") exit(1) - if has_x64: - print(f"Found x64 build: {X64_BUILD_DIR}") - if has_arm64: - print(f"Found arm64 build: {ARM64_BUILD_DIR}") - version = get_version() - print(f"Building packages for {METADATA['name']} version {version}") + print(f"Building {ARCH_SUFFIX} packages for {METADATA['name']} version {version}") # Make scripts executable for script in ["plezy.sh", "after-install.sh", "after-remove.sh"]: @@ -201,7 +186,7 @@ def main(): build_package(distro, version) print("\nAll packages built successfully!") - for f in OUTPUT_DIR.glob(f"{METADATA['name']}-linux.*"): + for f in sorted(OUTPUT_DIR.glob(f"{METADATA['name']}-linux-{ARCH_SUFFIX}.*")): print(f" {f}") diff --git a/linux/packaging/com.edde746.plezy.desktop b/linux/packaging/com.edde746.plezy.desktop index da559558..7704f46c 100644 --- a/linux/packaging/com.edde746.plezy.desktop +++ b/linux/packaging/com.edde746.plezy.desktop @@ -2,7 +2,7 @@ Type=Application Name=Plezy Comment=A modern Plex client for desktop and mobile -Exec=/opt/plezy/plezy +Exec=plezy Icon=plezy Terminal=false Categories=AudioVideo;Video;Player; diff --git a/linux/packaging/plezy.sh b/linux/packaging/plezy.sh index f91fb452..29a0bcb0 100644 --- a/linux/packaging/plezy.sh +++ b/linux/packaging/plezy.sh @@ -1,7 +1,3 @@ #!/bin/bash -ARCH=$(uname -m) -case "$ARCH" in - x86_64) cd /opt/plezy/x64 && exec ./plezy "$@" ;; - aarch64) cd /opt/plezy/arm64 && exec ./plezy "$@" ;; - *) echo "Unsupported architecture: $ARCH" >&2; exit 1 ;; -esac +cd /opt/plezy +exec ./plezy "$@"