| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 | #!/usr/bin/env bash# build - build Jellyfin binaries or packagesset -o errexitset -o pipefail# The list of possible package actions (except 'clean')declare -a actions=( 'build' 'package' 'sign' 'publish' )# The list of possible platforms, based on directories under 'deployment/'declare -a platforms=( $(    find deployment/ -maxdepth 1 -mindepth 1 -type d -exec basename {} \; | sort) )# The list of standard dependencies required by all build scripts; individual# action scripts may specify their own dependenciesdeclare -a dependencies=( 'tar' 'zip' )usage() {    echo -e "build - build Jellyfin binaries or packages"    echo -e ""    echo -e "Usage:"    echo -e " $ build --list-platforms"    echo -e " $ build --list-actions <platform>"    echo -e " $ build [-k/--keep-artifacts] [-b/--web-branch <web_branch>] <platform> <action>"    echo -e ""    echo -e "The 'keep-artifacts' option preserves build artifacts, e.g. Docker images for system package builds."    echo -e "The web_branch defaults to the same branch name as the current main branch or can be 'local' to not touch the submodule branching."    echo -e "To build all platforms, use 'all'."    echo -e "To perform all build actions, use 'all'."    echo -e "Build output files are collected at '../jellyfin-build/<platform>'."}# Show usage on stderr with exit 1 on arglessif [[ -z $1 ]]; then    usage >&2    exit 1fi# Show usage if -h or --help are specified in the argsif [[ $@ =~ '-h' || $@ =~ '--help' ]]; then    usage    exit 0fi# List all available platforms then exitif [[ $1 == '--list-platforms' ]]; then    echo -e "Available platforms:"    for platform in ${platforms[@]}; do        echo -e "  ${platform}"    done    exit 0fi# List all available actions for a given platform then exitif [[ $1 == '--list-actions' ]]; then    platform="$2"    if [[ ! " ${platforms[@]} " =~ " ${platform} " ]]; then        echo "ERROR: Platform ${platform} does not exist."        exit 1    fi    echo -e "Available actions for platform ${platform}:"    for action in ${actions[@]}; do        if [[ -f deployment/${platform}/${action}.sh ]]; then            echo -e "  ${action}"        fi    done    exit 0fi# Parse keep-artifacts optionif [[ $1 == '-k' || $1 == '--keep-artifacts' ]]; then    keep_artifacts="y"    shift 1else    keep_artifacts="n"fi# Parse branch optionif [[ $1 == '-b' || $1 == '--web-branch' ]]; then	web_branch="$2"	shift 2else    web_branch="$( git branch 2>/dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/\1/' )"fi# Parse platform optionif [[ -n $1 ]]; then    cli_platform="$1"    shiftelse    echo "ERROR: A platform must be specified. Use 'all' to specify all platforms."    exit 1fiif [[ ${cli_platform} == 'all' ]]; then    declare -a platform=( ${platforms[@]} )else    if [[ ! " ${platforms[@]} " =~ " ${cli_platform} " ]]; then        echo "ERROR: Platform ${cli_platform} is invalid. Use the '--list-platforms' option to list available platforms."        exit 1    else        declare -a platform=( "${cli_platform}" )    fifi# Parse action optionif [[ -n $1 ]]; then    cli_action="$1"    shiftelse    echo "ERROR: An action must be specified. Use 'all' to specify all actions."    exit 1fiif [[ ${cli_action} == 'all' ]]; then    declare -a action=( ${actions[@]} )else    if [[ ! " ${actions[@]} " =~ " ${cli_action} " ]]; then        echo "ERROR: Action ${cli_action} is invalid. Use the '--list-actions <platform>' option to list available actions."        exit 1    else        declare -a action=( "${cli_action}" )    fifi# Verify required utilities are installedmissing_deps=()for utility in ${dependencies[@]}; do    if ! which ${utility} &>/dev/null; then        missing_deps+=( ${utility} )    fidone# Error if we're missing anythingif [[ ${#missing_deps[@]} -gt 0 ]]; then    echo -e "ERROR: This script requires the following missing utilities:"    for utility in ${missing_deps[@]}; do        echo -e "  ${utility}"    done    exit 1fi# Parse platform-specific dependenciesfor target_platform in ${platform[@]}; do    # Read platform-specific dependencies    if [[ -f deployment/${target_platform}/dependencies.txt ]]; then        platform_dependencies="$( grep -v '^#' deployment/${target_platform}/dependencies.txt )"        # Verify required utilities are installed        missing_deps=()        for utility in ${platform_dependencies[@]}; do            if ! which ${utility} &>/dev/null; then                missing_deps+=( ${utility} )            fi        done        # Error if we're missing anything        if [[ ${#missing_deps[@]} -gt 0 ]]; then            echo -e "ERROR: The ${target_platform} platform requires the following utilities:"            for utility in ${missing_deps[@]}; do                echo -e "  ${utility}"            done            exit 1        fi    fidoneif [[ ${web_branch} != 'local' ]]; then    # Initialize submodules    git submodule update --init --recursive    # configure branch    pushd MediaBrowser.WebDashboard/jellyfin-web    if ! git diff-index --quiet HEAD --; then        popd        echo        echo "ERROR: Your 'jellyfin-web' submodule working directory is not clean!"        echo "This script will overwrite your unstaged and unpushed changes."        echo "Please do development on 'jellyfin-web' outside of the submodule."        exit 1    fi    git fetch --all    # If this is an official branch name, fetch it from origin    official_branches_regex="^master$|^dev$|^release-.*$|^hotfix-.*$"    if [[ ${web_branch} =~ ${official_branches_regex} ]]; then        git checkout origin/${web_branch} || {            echo "ERROR: 'jellyfin-web' branch 'origin/${web_branch}' is invalid."            exit 1        }    # Otherwise, just check out the local branch (for testing, etc.)    else        git checkout ${web_branch} || {            echo "ERROR: 'jellyfin-web' branch '${web_branch}' is invalid."            exit 1        }    fi    popdfi# Execute each platform and action in order, if said action is enabledpushd deployment/for target_platform in ${platform[@]}; do    echo -e "> Processing platform ${target_platform}"    date_start=$( date +%s )    pushd ${target_platform}    cleanup() {        echo -e ">> Processing action clean"        if [[ -f clean.sh && -x clean.sh ]]; then            ./clean.sh ${keep_artifacts}        fi    }    trap cleanup EXIT INT    for target_action in ${action[@]}; do        echo -e ">> Processing action ${target_action}"        if [[ -f ${target_action}.sh && -x ${target_action}.sh ]]; then            ./${target_action}.sh        fi    done    if [[ -d pkg-dist/ ]]; then        echo -e ">> Collecting build artifacts"        target_dir="../../../bin/${target_platform}"        mkdir -p ${target_dir}        mv pkg-dist/* ${target_dir}/    fi    cleanup    date_end=$( date +%s )    echo -e "> Completed platform ${target_platform} in $( expr ${date_end} - ${date_start} ) seconds."    popddonepopd
 |