File ci.obscpio of Package AppImageLauncher

07070100000000000081a400000000000000000000000168cf694000000013000000000000000000000000000000000000001100000000ci/.dockerignore*
!install-deps.sh
07070100000001000081a400000000000000000000000168cf6940000002ab000000000000000000000000000000000000000e00000000ci/DockerfileFROM ubuntu:focal

# tell scripts that we're building in an automated release scenario
ENV CI=1

# we re-use the DOCKER_PLATFORM to tell the build scripts about the build target architecture without the need to use uname
# the build scripts will have to map the architecture to names Debian/RPM/AppImage support
ARG DOCKER_PLATFORM
ENV DOCKER_PLATFORM="${DOCKER_PLATFORM}"

# we need to provide some writable $HOME for the (random) used ID we use in the build script
RUN install -d -m 0777 /home/user
ENV HOME=/home/user

# let the install script do the heavy lifting (easier than replicating the complex behavior in a Dockerfile)
COPY install-deps.sh /
RUN bash -xe install-deps.sh
07070100000002000081ed00000000000000000000000168cf6940000009ef000000000000000000000000000000000000001900000000ci/build-docker-image.sh#! /bin/bash

if [[ "$DOCKER_PLATFORM" == "" ]]; then
    echo "Usage: env $DOCKER_PLATFORM=... bash $0"
    exit 1
fi

set -euo pipefail

# the other script sources this script, therefore we have to support that use case
if [[ "${BASH_SOURCE[*]}" != "" ]]; then
    this_dir="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"
else
    this_dir="$(readlink -f "$(dirname "$0")")"
fi

# we need a "docker-container" type builder to make use of all the buildx features regarding caching and multi-arch
# support
builder_name="appimagelauncher-builder"
if ! docker buildx inspect "$builder_name" &>/dev/null; then
    echo "Docker builder $builder_name not found, creating"
    docker buildx create --name="$builder_name" --driver=docker-container --bootstrap
else
    echo "Using existing Docker builder $builder_name found"
fi

image=ghcr.io/theassassin/appimagelauncher-build
branch="$(git rev-parse --abbrev-ref HEAD | tr -c 'A-Za-z0-9-' '_')"
# append platform to Docker image tag since we can't push separate (multi-arch) images to the same name without
# creating the manifest manually
# see https://github.com/docker/build-push-action/issues/671
platform_suffix="$(echo -n "$DOCKER_PLATFORM" | tr -c 'A-Za-z0-9-' '_')"

current_branch_tag="${image}:${branch}_${platform_suffix}"
master_branch_tag="${image}:master_${platform_suffix}"

docker_command=(
    docker buildx build
    --builder "$builder_name"
    --load  # --output=type=docker
    --pull
    --platform "$DOCKER_PLATFORM"
    --build-arg DOCKER_PLATFORM="$DOCKER_PLATFORM"

    # cache from the current branch's image
    --cache-from type=registry,ref="$current_branch_tag"

    # we can always cache from the master branch's image
    --cache-from type=registry,ref="$master_branch_tag"

    --tag "$current_branch_tag"
)

# if we are building on GitHub actions, we can also push the resulting image
# we skip pull request builds, though; regular branch builds will push the built images (if possible)
# also, skip Dependabot builds, it is not allowed to push images
if [[ "${GITHUB_ACTIONS:-}" != "" ]] && [[ "${GITHUB_EVENT_NAME:-}" != "pull_request" ]] && [[ "${GITHUB_ACTOR:-}" != "dependabot"* ]]; then
    echo "Going to push built image"
    docker_command+=(
        --cache-to type=inline
        --push
    )
fi

docker_command+=(
   "$this_dir"
)

# using inline cache to speed up builds by fetching the image from the GitHub registry first
# this should speed up local builds as well
# if the image hasn't changed, this should be a no-op
"${docker_command[@]}"
07070100000003000081ed00000000000000000000000168cf6940000005bc000000000000000000000000000000000000001600000000ci/build-in-docker.sh#! /bin/bash

if [[ "$DOCKER_PLATFORM" == "" ]]; then
    echo "Usage: env DOCKER_PLATFORM=... bash $0"
    exit 1
fi

set -x
set -euo pipefail

cd "$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")"

# sets variables $image, $dockerfile
source build-docker-image.sh

DOCKER_OPTS=()
# fix for https://stackoverflow.com/questions/51195528/rcc-error-in-resource-qrc-cannot-find-file-png
if [ "${CI:-}" != "" ]; then
    DOCKER_OPTS+=("--security-opt" "seccomp:unconfined")
fi

# only if there's more than 3G of free space in RAM, we can build in a RAM disk
if [[ "${GITHUB_ACTIONS:-}" != "" ]]; then
    echo "Building on GitHub actions, which does not support --tmpfs flag -> building on regular disk"
elif [[ "$(env LC_ALL=C free -m  | grep "Mem:" | awk '{print $4}')" -gt 3072 ]]; then
    echo "Host system has enough free memory -> building in RAM disk"
    DOCKER_OPTS+=("--tmpfs" "/docker-ramdisk:exec,mode=777")
else
    echo "Host system does not have enough free memory -> building on regular disk"
fi

[[ -t 0 ]] && DOCKER_OPTS+=("-t")

# run the build with the current user to
#   a) make sure root is not required for builds
#   b) allow the build scripts to "mv" the binaries into the /out directory
uid="$(id -u)"
# run build
docker run -e BUILD_LITE -e DIST -e ARCH -e GITHUB_RUN_NUMBER -e GITHUB_RUN_ID --rm -i --user "$uid" -w /ws -e CI=1 \
     "${DOCKER_OPTS[@]}" \
     -v "$(readlink -f ..):/ws" \
     "$current_branch_tag" \
     bash ci/build.sh

07070100000004000081ed00000000000000000000000168cf694000001785000000000000000000000000000000000000000c00000000ci/build.sh#! /bin/bash

set -euo pipefail

# use RAM disk if possible
if [ -d /dev/shm ] && mount | grep /dev/shm | grep -v -q noexec; then
    TEMP_BASE=/dev/shm
elif [ -d /docker-ramdisk ]; then
    TEMP_BASE=/docker-ramdisk
else
    TEMP_BASE=/tmp
fi

BUILD_DIR="$(mktemp -d -p "$TEMP_BASE" AppImageLauncher-build-XXXXXX)"

cleanup () {
    if [ -d "$BUILD_DIR" ]; then
        rm -rf "$BUILD_DIR"
    fi
}

trap cleanup EXIT

# store repo root as variable
REPO_ROOT="$(readlink -f "$(dirname "${BASH_SOURCE[0]}")"/..)"
OLD_CWD="$(readlink -f .)"

pushd "$BUILD_DIR"

# list available versions of Qt to be able to choose the right one for the build
cat <<\EOF
##########################
# Available Qt versions: #
##########################
EOF
qtchooser -list-versions
echo

# the Docker images provide a clang/clang++ symlink to the actual clang[++] binaries
# see install-deps.sh for more information
cmake_args=(
    "-DCMAKE_C_COMPILER=clang"
    "-DCMAKE_CXX_COMPILER=clang++"
    "-DCMAKE_INSTALL_PREFIX=/usr"
    "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
    "-DBUILD_TESTING=OFF"
    "-DCMAKE_BUILD_TYPE=RelWithDebInfo"
    # TODO: we don't necessarily want to hardcode this here
    "-DBINFMT_INTERPRETER_PATH_PREPEND_LD_P_NATIVE_PACKAGES_PREFIX=/opt/appimagelauncher.AppDir/"
)

if [[ "${BUILD_LITE:-}" == "" ]]; then
    cmake_args+=("-DENABLE_UPDATE_HELPER=ON")
else
    cmake_args+=("-DBUILD_LITE=ON")
fi

export QT_SELECT=qt5

cmake "$REPO_ROOT" "${cmake_args[@]}"

make -j$(nproc)

# prepare AppDir
make install DESTDIR=AppDir

ARCH="$(dpkg --print-architecture)"

# "translate" to linuxdeploy/AppImage architecture
# note: linuxdeploy and AppImage differ in i386/i686, but we don't support that any more anyway
case "$ARCH" in
    amd64)
        ARCH=x86_64
        ;;
    arm64)
        ARCH=aarch64
        ;;
esac

# build release formats
curl -LO https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-"$ARCH".AppImage
curl -LO https://github.com/linuxdeploy/linuxdeploy-plugin-qt/releases/download/continuous/linuxdeploy-plugin-qt-"$ARCH".AppImage

VERSION=$(src/cli/ail-cli --version | awk '{print $3}')

gha_build="${GITHUB_RUN_NUMBER:-}"

if [[ "$gha_build" != "" ]]; then
    VERSION="${VERSION}-gha${gha_build}"
else
    VERSION="${VERSION}-local"
fi

# should be overwritten for every output plugin below, this is a fallback only
export LINUXDEPLOY_OUTPUT_APP_NAME=appimagelauncher

LINUXDEPLOY_OUTPUT_VERSION="${VERSION}~$(cd "$REPO_ROOT" && git rev-parse --short HEAD)"
export LINUXDEPLOY_OUTPUT_VERSION

export APPIMAGE_EXTRACT_AND_RUN=1

linuxdeploy_extra_args=()

if [[ "${BUILD_LITE:-}" == "" ]]; then
    # configure linuxdeploy-plugin-native_packages
    export LDNP_PACKAGE_NAME=appimagelauncher

    export LDNP_BUILD="deb rpm"
    export LDNP_DESCRIPTION=""
    export LDNP_SHORT_DESCRIPTION=""

    case "$ARCH" in
        x86_64)
            rpm_build_arch=x86_64
            deb_build_arch=amd64
            ;;
        i?86)
            rpm_build_arch=i386
            deb_build_arch=i386
            ;;
        aarch64)
            rpm_build_arch=aarch64
            deb_build_arch=arm64
            ;;
        armhf)
            deb_build_arch=armhf
            rpm_build_arch=armv7hl
            ;;
        *)
            echo "Unsupported architecture: $ARCH"
            exit 2
            ;;
    esac

    # common meta info
    export LDNP_META_URL="https://github.com/TheAssassin/AppImageLauncher"
    export LDNP_META_BUG_URL="https://github.com/TheAssassin/AppImageLauncher/issues"
    export LDNP_META_VENDOR="TheAssassin"

    export LDNP_META_DEB_DEPENDS="systemd, libgl1, libfontconfig1, libharfbuzz0b, libfribidi0"
    export LDNP_META_DEB_ARCHITECTURE="$deb_build_arch"
    export LDNP_META_DEB_PRE_DEPENDS="bash"
    export LDNP_DEB_EXTRA_DEBIAN_FILES="${BUILD_DIR}/cmake/debian/postinst;${BUILD_DIR}/cmake/debian/postrm"

    export LDNP_META_RPM_REQUIRES="systemd libGL.so.1 libfontconfig.so.1 libfreetype.so.6 libfribidi.so.0 libgpg-error.so.0 libharfbuzz.so.0"
    export LDNP_META_RPM_BUILD_ARCH="$rpm_build_arch"
    export LDNP_RPM_SCRIPTLET_POST="${BUILD_DIR}/cmake/debian/postinst"
    export LDNP_RPM_SCRIPTLET_PREUN="${BUILD_DIR}/cmake/debian/postrm"

    # updater is not available for the lite build
    linuxdeploy_extra_args+=(
        -e "$(find AppDir/usr/lib/*/appimagelauncher/update | head -n1)"
        --output native_packages
    )

    # tools like pipx would have side effects on the build host and it's generally a bit overkill for our purpose
    if which python3.13 &> /dev/null; then
        # python3.13, installed from the deadsnakes PPA for the Docker builds
        python3() {
            python3.13 "$@"
        }
    fi
    python3 -m venv venv
    venv/bin/pip install git+https://github.com/linuxdeploy/linuxdeploy-plugin-native_packages
    export PATH="$PWD/venv/bin:$PATH"
else
    linuxdeploy_extra_args+=(
        --custom-apprun "$REPO_ROOT"/resources/appimagelauncher-lite-AppRun.sh
        --output appimage
    )

    LDAI_OUTPUT="$(echo appimagelauncher-lite-"$VERSION"-"$ARCH".AppImage | tr '~' -)"
    export LDAI_OUTPUT

    # since we extracted common parts from the installer built into the AppRun script, we have to copy the "library" script
    # before building an AppImage
    install "$REPO_ROOT"/resources/appimagelauncher-lite-installer-common.sh "$(readlink -f AppDir/)"
fi

chmod -v +x linuxdeploy*-"$ARCH".AppImage

# workaround for QEMU
for appimage in *.AppImage; do
    dd if=/dev/zero bs=1 count=3 seek=8 conv=notrunc of="$appimage"
done

ldd AppDir/usr/bin/AppImageLauncherSettings

./linuxdeploy-"$ARCH".AppImage -v0 \
    --appdir "$(readlink -f AppDir)" \
    --plugin qt \
    -d AppDir/usr/share/applications/appimagelauncher.desktop \
    -e "$(find AppDir/usr/lib/*/appimagelauncher/remove | head -n1)" \
    "${linuxdeploy_extra_args[@]}"

if [[ "${BUILD_LITE:-}" == "" ]]; then
    mv "$LDNP_PACKAGE_NAME"*.{rpm,deb} "$OLD_CWD"
else
    mv "$LDAI_OUTPUT" "$OLD_CWD"
fi
07070100000005000081ed00000000000000000000000168cf694000000ff2000000000000000000000000000000000000001300000000ci/install-deps.sh#! /bin/bash

set -euo pipefail

if [[ "$DOCKER_PLATFORM" == "" ]]; then
    echo "Usage: env DOCKER_PLATFORM=... bash $0"
    exit 2
fi

if [[ "$CI" == "" ]]; then
    echo "Caution: this script is supposed to run inside a (disposable) CI environment"
    echo "It will alter a system, and should not be run on workstations or alike"
    echo "You can export CI=1 to prevent this error from being shown again"
    exit 3
fi

case "$DOCKER_PLATFORM" in
    linux/amd64|linux/arm/v7|linux/arm64/v8)
        ;;
    *)
        echo "Error: unsupported architecture: $DOCKER_PLATFORM"
        exit 4
        ;;
esac

set -x

# this array collects all the packages we want to install
# running as few operations as possible is a runtime optimization
packages=()

# install 32-bit build dependencies and multilib/cross compilers for binfmt-bypass's 32-bit preload library
# must be done before apt-get update, otherwise the packages cannot be found during installation
if [[ "$DOCKER_PLATFORM" == "linux/amd64" ]]; then
    dpkg --add-architecture i386
    packages+=(
        libc6-dev:i386
    )
elif [[ "$DOCKER_PLATFORM" == "linux/arm64/v8" ]]; then
    dpkg --add-architecture armhf
    packages+=(
        libc6-dev:armhf
    )
fi

# allow setup of PPA
apt-get update
apt-get install -y software-properties-common

# we depend on the deadsnakes PPA to provide a sufficiently recent Python to linuxdeploy-plugin-native_packages
add-apt-repository -y ppa:deadsnakes/ppa

packages=(
    libcurl4-openssl-dev
    libfuse-dev
    desktop-file-utils
    libglib2.0-dev
    libcairo2-dev
    libssl-dev
    ca-certificates
    libbsd-dev
    qttools5-dev-tools
    make
    build-essential
    git
    automake
    autoconf
    libtool
    patch
    wget
    curl
    vim-common
    desktop-file-utils
    pkg-config
    libarchive-dev
    libboost-filesystem-dev
    librsvg2-dev
    librsvg2-bin
    libssl-dev
    rpm
    rpm2cpio
    liblzma-dev

    # cross-compiling for 32-bit is only really easy with clang, where we can specify the target as a compiler option
    # clang -target arm-linux-gnueabihf ...
    clang

    qtbase5-dev
    qt5-qmake
    qtdeclarative5-dev

    # libappimage
    libgcrypt-dev
    argagg-dev
    nlohmann-json3-dev
    libgpgme-dev
    libzstd-dev

    # linuxdeploy-plugin-native_packages
    # see also above re. deadsnakes PPA
    python3.13-venv
)

# headless install
export DEBIAN_FRONTEND=noninteractive

apt-get -y --no-install-recommends install "${packages[@]}"

# install more recent CMake and patchelf
cmake_arch="$(dpkg --print-architecture)"

case "$cmake_arch" in
    amd64)
        cmake_arch=x86_64
        ;;
    arm64)
        cmake_arch=aarch64
        ;;
    armhf)
        patchelf_arch=armv7l
        ;;
esac

patchelf_arch="${patchelf_arch:-$cmake_arch}"

curl -L https://artifacts.assassinate-you.net/prebuilt-cmake/cmake-v3.29.6-ubuntu-focal-"${cmake_arch}".tar.gz | \
    tar xz --strip-components=1 -C /usr

curl -L https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-"$patchelf_arch".tar.gz | tar xz -C/usr/local

  # g{cc,++}-multilib usually install these dependencies for us
  # however, as the multilib stuff is not available for ARM, we have to install these dev packages ourselves
  # we can't really predict the names of the packages (they differ on different distros/releases)
  # therefore, we have to install the other dependencies first to be able to query them with dpkg -l
if [[ "$DOCKER_PLATFORM" == "linux/arm64/v8" ]] || [[ "$DOCKER_PLATFORM" == "linux/amd64" ]]; then
    if [[ "$DOCKER_PLATFORM" == "linux/amd64" ]]; then
        arch_32bit=i386
    elif [[ "$DOCKER_PLATFORM" == "linux/arm64/v8" ]]; then
        arch_32bit=armhf
    else
        echo "Cannot determine 32-bit architecture matching 64-bit architecture $ARCH"
        exit 6
    fi

    apt-get install -y \
        "$(dpkg -l | grep libgcc | grep dev | awk '{print $2}' | cut -d: -f1 | uniq)":"$arch_32bit" \
        "$(dpkg -l | grep libstdc++ | grep dev | awk '{print $2}' | cut -d: -f1 | uniq)":"$arch_32bit"
fi
07070100000006000041ed00000000000000000000000168cf694000000000000000000000000000000000000000000000000300000000ci07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000b00000000TRAILER!!!
openSUSE Build Service is sponsored by