#!/bin/bash ############################################################################# # Jellyfin Linux Package Build Automation Script # # Builds both Debian (.deb) and Red Hat (.rpm) packages from the current # publishing parameters. # # Usage: # ./build-linux-packages.sh # Build both packages # ./build-linux-packages.sh --deb-only # Build Debian only # ./build-linux-packages.sh --rpm-only # Build Red Hat only # ./build-linux-packages.sh --version X.Y.Z # Specify version # ############################################################################# set -e # Configuration SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Determine project root (script can be in root or in scripts/ subdirectory) if [ -f "$SCRIPT_DIR/SharedVersion.cs" ]; then PROJECT_ROOT="$SCRIPT_DIR" elif [ -f "$(dirname "$SCRIPT_DIR")/SharedVersion.cs" ]; then PROJECT_ROOT="$(dirname "$SCRIPT_DIR")" else echo "Error: Could not locate project root (SharedVersion.cs not found)" >&2 exit 1 fi # Parse arguments BUILD_DEB=true BUILD_RPM=true CUSTOM_VERSION="" while [[ $# -gt 0 ]]; do case $1 in --deb-only) BUILD_RPM=false shift ;; --rpm-only) BUILD_DEB=false shift ;; --version) CUSTOM_VERSION="$2" shift 2 ;; *) echo "Unknown option: $1" exit 1 ;; esac done # Extract version from SharedVersion.cs (AssemblyVersion attribute) if [ -z "$CUSTOM_VERSION" ]; then VERSION=$(grep -oP 'AssemblyVersion\("\K[^"]+' "$PROJECT_ROOT/SharedVersion.cs" | head -1) if [ -z "$VERSION" ]; then echo "Error: Could not extract version from SharedVersion.cs" >&2 exit 1 fi else VERSION="$CUSTOM_VERSION" fi # Directory setup PUBLISH_DIR="/tmp/jellyfin-publish-$$" BUILD_OUTPUT_DIR="${PROJECT_ROOT}/build/packages" TEMP_DIR="/tmp/jellyfin-build-$$" # Color output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Helper functions print_header() { echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║${NC} Jellyfin Linux Package Builder" echo -e "${BLUE}║${NC} Version: $VERSION" echo -e "${BLUE}║${NC} Building: $([ "$BUILD_DEB" = true ] && echo -n "Debian ") $([ "$BUILD_RPM" = true ] && echo -n "Red Hat")" echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}" } print_step() { echo -e "\n${BLUE}[$(date +'%H:%M:%S')]${NC} $1" } print_success() { echo -e "${GREEN}✓${NC} $1" } print_error() { echo -e "${RED}✗${NC} $1" } print_info() { echo -e "${YELLOW}ℹ${NC} $1" } cleanup() { if [ -d "$PUBLISH_DIR" ]; then rm -rf "$PUBLISH_DIR" fi if [ -d "$TEMP_DIR" ]; then rm -rf "$TEMP_DIR" fi } trap cleanup EXIT # Main execution print_header # Step 1: Verify prerequisites print_step "Checking prerequisites..." if ! command -v dotnet &> /dev/null; then print_error "dotnet CLI not found. Please install .NET SDK." exit 1 fi print_success ".NET SDK found" if ! command -v fpm &> /dev/null; then print_error "fpm not found. Installing..." if command -v apt-get &> /dev/null; then sudo apt-get update sudo apt-get install -y ruby-dev sudo gem install fpm elif command -v dnf &> /dev/null; then sudo dnf install -y ruby-devel sudo gem install fpm else print_error "Could not install fpm. Please install manually." exit 1 fi fi print_success "fpm found" # Step 2: Publish the application print_step "Publishing application for linux-x64..." cd "$PROJECT_ROOT" if ! dotnet restore Jellyfin.sln -r linux-x64 > /dev/null 2>&1; then print_error "dotnet restore failed" exit 1 fi print_success "Dependencies restored" if ! dotnet build Jellyfin.sln --configuration Release > /dev/null 2>&1; then print_error "dotnet build failed" exit 1 fi print_success "Solution built in Release configuration" if ! dotnet publish Jellyfin.Server/Jellyfin.Server.csproj \ --configuration Release \ --self-contained true \ --runtime linux-x64 \ --output "$PUBLISH_DIR" > /dev/null 2>&1; then print_error "dotnet publish failed" exit 1 fi print_success "Published to $PUBLISH_DIR" # Step 3: Create build output directory mkdir -p "$BUILD_OUTPUT_DIR" print_success "Output directory: $BUILD_OUTPUT_DIR" # Step 4: Build Debian package if [ "$BUILD_DEB" = true ]; then print_step "Building Debian package..." DEB_OUTPUT="$BUILD_OUTPUT_DIR/jellyfin-${VERSION}-amd64.deb" if fpm \ -s dir \ -t deb \ -n jellyfin \ -v "$VERSION" \ --architecture x86_64 \ --description "Jellyfin Media Server" \ --url "https://jellyfin.org" \ --license "GPL-2.0" \ --maintainer "Jellyfin Team " \ --depends "libssl3" \ --depends "libicu72" \ --depends "libfontconfig1" \ --after-install "${PROJECT_ROOT}/scripts/debian/postinst.sh" \ --before-remove "${PROJECT_ROOT}/scripts/debian/prerm.sh" \ --after-remove "${PROJECT_ROOT}/scripts/debian/postrm.sh" \ -C "$PUBLISH_DIR" \ -p "$DEB_OUTPUT" \ opt/=opt/jellyfin > /dev/null 2>&1; then print_success "Created: jellyfin-${VERSION}-amd64.deb" DEB_SIZE=$(du -h "$DEB_OUTPUT" | cut -f1) print_info "Size: $DEB_SIZE" else print_error "Failed to create Debian package" exit 1 fi fi # Step 5: Build Red Hat package if [ "$BUILD_RPM" = true ]; then print_step "Building Red Hat package..." RPM_OUTPUT="$BUILD_OUTPUT_DIR/jellyfin-${VERSION}-1.x86_64.rpm" if fpm \ -s dir \ -t rpm \ -n jellyfin \ -v "$VERSION" \ --architecture x86_64 \ --description "Jellyfin Media Server" \ --url "https://jellyfin.org" \ --license "GPL-2.0" \ --maintainer "Jellyfin Team " \ --depends "openssl-libs" \ --depends "libicu" \ --depends "fontconfig" \ --after-install "${PROJECT_ROOT}/scripts/redhat/post.sh" \ --before-remove "${PROJECT_ROOT}/scripts/redhat/preun.sh" \ --after-remove "${PROJECT_ROOT}/scripts/redhat/postun.sh" \ -C "$PUBLISH_DIR" \ -p "$RPM_OUTPUT" \ opt/=opt/jellyfin > /dev/null 2>&1; then print_success "Created: jellyfin-${VERSION}-1.x86_64.rpm" RPM_SIZE=$(du -h "$RPM_OUTPUT" | cut -f1) print_info "Size: $RPM_SIZE" else print_error "Failed to create Red Hat package" exit 1 fi fi # Summary echo echo -e "${BLUE}╔═══════════════════════════════════════════════════════════════╗${NC}" echo -e "${BLUE}║${NC} Build Complete!" echo -e "${BLUE}╠═══════════════════════════════════════════════════════════════╣${NC}" echo -e "${BLUE}║${NC} Packages available in:" echo -e "${BLUE}║${NC} ${GREEN}$BUILD_OUTPUT_DIR${NC}" echo -e "${BLUE}╠═══════════════════════════════════════════════════════════════╣${NC}" if [ "$BUILD_DEB" = true ]; then echo -e "${BLUE}║${NC} ${GREEN}✓${NC} Debian: jellyfin-${VERSION}-amd64.deb" fi if [ "$BUILD_RPM" = true ]; then echo -e "${BLUE}║${NC} ${GREEN}✓${NC} Red Hat: jellyfin-${VERSION}-1.x86_64.rpm" fi echo -e "${BLUE}╠═══════════════════════════════════════════════════════════════╣${NC}" echo -e "${BLUE}║${NC} Next steps:" echo -e "${BLUE}║${NC} Debian: sudo dpkg -i jellyfin-${VERSION}-amd64.deb" echo -e "${BLUE}║${NC} Red Hat: sudo dnf install jellyfin-${VERSION}-1.x86_64.rpm" echo -e "${BLUE}╚═══════════════════════════════════════════════════════════════╝${NC}"