Files
zoitechat/.github/workflows/appimage-build.yml
deepend 796c572292 Updated the AppImage workflow to copy Python dist-packages into the AppDir for both standard and multiarch layouts (/usr/lib/python3/dist-packages and /usr/lib/x86_64-linux-gnu/python3/dist-packages). This ensures Python runtime modules needed by the embedded plugin are actually bundled.
Updated AppRun Python environment setup to build PYTHONPATH dynamically from all bundled candidate directories instead of assuming only one path. This should address cases where the Python plugin fails to initialize in the AppImage due to missing import paths.
2026-02-22 10:56:46 -07:00

224 lines
8.4 KiB
YAML

name: AppImage Build
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
appimage_build:
runs-on: ubuntu-22.04
permissions:
contents: read
id-token: write
attestations: write
artifact-metadata: write
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: Install build dependencies
run: |
set -eux
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential pkg-config meson ninja-build cmake \
gettext \
libcanberra-dev libdbus-glib-1-dev libglib2.0-dev \
libgtk-3-dev \
libwayland-client0 libwayland-cursor0 libwayland-egl1 \
libxkbcommon0 \
libgtk-3-bin libglib2.0-bin shared-mime-info gsettings-desktop-schemas \
libluajit-5.1-dev libpci-dev libperl-dev libssl-dev libayatana-appindicator3-dev \
perl python3 python3-minimal python3-dev python3-cffi mono-devel desktop-file-utils \
patchelf file curl
- name: Configure
run: |
set -eux
rm -rf build
meson setup build \
--prefix=/usr \
-Dgtk3=true \
-Dtext-frontend=true \
-Dwith-perl=perl \
-Dwith-python=python3 \
-Dauto_features=enabled \
-Dappindicator=enabled
- name: Build
run: |
set -eux
ninja -C build
- name: Install to AppDir
run: |
set -eux
rm -rf AppDir
DESTDIR="${PWD}/AppDir" ninja -C build install
- name: Bundle scripting runtimes in AppDir
run: |
set -eux
python3_version="$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")')"
install -Dm755 "$(command -v python3)" "AppDir/usr/bin/python3"
if [ -x "/usr/bin/perl" ]; then
install -Dm755 /usr/bin/perl AppDir/usr/bin/perl
fi
install -d AppDir/usr/lib
cp -a "/usr/lib/python${python3_version}" "AppDir/usr/lib/"
if [ -d "/usr/lib/python3/dist-packages" ]; then
install -d AppDir/usr/lib/python3
cp -a /usr/lib/python3/dist-packages AppDir/usr/lib/python3/
fi
if [ -d "/usr/lib/x86_64-linux-gnu/python3/dist-packages" ]; then
install -d AppDir/usr/lib/x86_64-linux-gnu/python3
cp -a /usr/lib/x86_64-linux-gnu/python3/dist-packages AppDir/usr/lib/x86_64-linux-gnu/python3/
fi
if [ -d "/usr/lib/x86_64-linux-gnu/perl" ]; then
install -d AppDir/usr/lib/x86_64-linux-gnu
cp -a /usr/lib/x86_64-linux-gnu/perl AppDir/usr/lib/x86_64-linux-gnu/
fi
if [ -d "/usr/share/perl" ]; then
install -d AppDir/usr/share
cp -a /usr/share/perl AppDir/usr/share/
fi
if [ -d "/usr/share/perl5" ]; then
install -d AppDir/usr/share
cp -a /usr/share/perl5 AppDir/usr/share/
fi
if compgen -G '/usr/lib/x86_64-linux-gnu/libpython3*.so*' > /dev/null; then
install -d AppDir/usr/lib/x86_64-linux-gnu
cp -a /usr/lib/x86_64-linux-gnu/libpython3*.so* AppDir/usr/lib/x86_64-linux-gnu/
fi
- name: Verify bundled plugins
run: |
set -eux
# Include every built-in plugin except the Windows-only update plugin.
find AppDir/usr/lib -maxdepth 4 -type f -name '*.so' -path '*/zoitechat/plugins/*' -print | sort
for plugin in checksum fishlim lua perl python sysinfo; do
find "AppDir/usr/lib" -maxdepth 4 -type f -name "${plugin}.so" -path '*/zoitechat/plugins/*' -print -quit | grep -q .
done
- name: Build AppImage
env:
APPIMAGE_EXTRACT_AND_RUN: 1
DEPLOY_GTK_VERSION: 3
LDAI_NO_APPSTREAM: 1
run: |
set -eux
curl -fL --retry 3 -o linuxdeploy-x86_64.AppImage \
https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x linuxdeploy-x86_64.AppImage
curl -fL --retry 3 -o linuxdeploy-plugin-gtk \
https://raw.githubusercontent.com/linuxdeploy/linuxdeploy-plugin-gtk/master/linuxdeploy-plugin-gtk.sh
chmod +x linuxdeploy-plugin-gtk
export PATH="${PWD}:${PATH}"
install -Dm644 /etc/ssl/certs/ca-certificates.crt \
AppDir/etc/ssl/certs/ca-certificates.crt
cat > AppRun <<'EOF'
#!/bin/sh
set -eu
APPDIR="${APPDIR:-$(dirname "$(readlink -f "$0")")}"
export PATH="${PATH:-/usr/bin:/bin}:$APPDIR/usr/bin"
export LD_LIBRARY_PATH="$APPDIR/usr/lib:$APPDIR/usr/lib/x86_64-linux-gnu:${LD_LIBRARY_PATH:-}"
export XDG_DATA_DIRS="$APPDIR/usr/share:${XDG_DATA_DIRS:-/usr/local/share:/usr/share}"
if [ -d "$APPDIR/usr/lib/x86_64-linux-gnu/zoitechat/plugins" ]; then
export ZOITECHAT_LIBDIR="$APPDIR/usr/lib/x86_64-linux-gnu/zoitechat/plugins"
elif [ -d "$APPDIR/usr/lib/zoitechat/plugins" ]; then
export ZOITECHAT_LIBDIR="$APPDIR/usr/lib/zoitechat/plugins"
fi
if [ -d "$APPDIR/usr/share/glib-2.0/schemas" ]; then
export GSETTINGS_SCHEMA_DIR="$APPDIR/usr/share/glib-2.0/schemas${GSETTINGS_SCHEMA_DIR:+:$GSETTINGS_SCHEMA_DIR}"
fi
if [ -d "$APPDIR/usr/lib/x86_64-linux-gnu/gio/modules" ]; then
export GIO_EXTRA_MODULES="$APPDIR/usr/lib/x86_64-linux-gnu/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}"
elif [ -d "$APPDIR/usr/lib/gio/modules" ]; then
export GIO_EXTRA_MODULES="$APPDIR/usr/lib/gio/modules${GIO_EXTRA_MODULES:+:$GIO_EXTRA_MODULES}"
fi
export PYTHONHOME="$APPDIR/usr"
python_stdlib_dir="$(find "$APPDIR/usr/lib" -maxdepth 1 -type d -name 'python3.*' | head -n 1 || true)"
pythonpath_entries=""
if [ -n "$python_stdlib_dir" ] && [ -d "$python_stdlib_dir/dist-packages" ]; then
pythonpath_entries="$python_stdlib_dir/dist-packages"
fi
if [ -d "$APPDIR/usr/lib/python3/dist-packages" ]; then
pythonpath_entries="${pythonpath_entries:+$pythonpath_entries:}$APPDIR/usr/lib/python3/dist-packages"
fi
if [ -d "$APPDIR/usr/lib/x86_64-linux-gnu/python3/dist-packages" ]; then
pythonpath_entries="${pythonpath_entries:+$pythonpath_entries:}$APPDIR/usr/lib/x86_64-linux-gnu/python3/dist-packages"
fi
if [ -n "$pythonpath_entries" ]; then
export PYTHONPATH="$pythonpath_entries${PYTHONPATH:+:$PYTHONPATH}"
fi
# OpenSSL trust store override
export SSL_CERT_FILE="${SSL_CERT_FILE:-$APPDIR/etc/ssl/certs/ca-certificates.crt}"
export SSL_CERT_DIR="${SSL_CERT_DIR:-$APPDIR/etc/ssl/certs}"
export CURL_CA_BUNDLE="${CURL_CA_BUNDLE:-$SSL_CERT_FILE}"
# Prefer Wayland if the session provides it, but keep X11 fallback.
# Don't override if the user already set GDK_BACKEND explicitly.
if [ -z "${GDK_BACKEND:-}" ]; then
if [ -n "${WAYLAND_DISPLAY:-}" ] || [ "${XDG_SESSION_TYPE:-}" = "wayland" ]; then
export GDK_BACKEND="wayland,x11"
else
export GDK_BACKEND="x11"
fi
fi
exec "$APPDIR/usr/bin/zoitechat" "$@"
EOF
chmod +x AppRun
VERSION="$(git describe --tags --always)"
./linuxdeploy-x86_64.AppImage \
--appdir AppDir \
--desktop-file AppDir/usr/share/applications/net.zoite.Zoitechat.desktop \
--icon-file AppDir/usr/share/icons/hicolor/48x48/apps/net.zoite.Zoitechat.png \
--custom-apprun ./AppRun \
--plugin gtk \
--output appimage
appimage_path="$(ls -1 *.AppImage | grep -v linuxdeploy | head -n 1)"
mv "$appimage_path" "Zoitechat-${VERSION}-x86_64.AppImage"
- name: Attest AppImage (Build Provenance)
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: actions/attest-build-provenance@v3
with:
subject-path: Zoitechat-*-x86_64.AppImage
- name: Upload AppImage artifact
uses: actions/upload-artifact@v4
with:
name: zoitechat-appimage
path: Zoitechat-*-x86_64.AppImage