Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
173 changes: 140 additions & 33 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -94,30 +94,166 @@ jobs:
name: agent-linux-amd64
path: artifacts/agent

- name: Download appimagetool
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y libwebkit2gtk-4.1-dev libgtk-3-dev libgdk-pixbuf2.0-bin

- name: Download tools
run: |
curl -L -o appimagetool https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
chmod +x appimagetool
curl -L -o linuxdeploy https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-x86_64.AppImage
chmod +x appimagetool linuxdeploy

- name: Prepare AppDirs
run: |
generate_desktop() {
local binary_name="$1"
local display_name="$2"
local desktop_id="$3"
local output="$4"
cat > "$output" << DESKTOP_EOF
[Desktop Entry]
Name=${display_name}
Comment=Deploy games to Steam Deck and Linux devices
Exec=${binary_name}
Icon=${desktop_id}
Type=Application
Categories=Game;Development;
Terminal=false
DESKTOP_EOF
}

# Hub AppDir
mkdir -p hub.AppDir/usr/bin
cp artifacts/hub/capydeploy-hub-tauri hub.AppDir/usr/bin/
chmod +x hub.AppDir/usr/bin/capydeploy-hub-tauri
cp apps/hub-tauri/src-tauri/icons/icon.png hub.AppDir/capydeploy-hub.png
generate_desktop "capydeploy-hub-tauri" "CapyDeploy Hub" "capydeploy-hub" "hub.AppDir/capydeploy-hub.desktop"

# Agent AppDir
mkdir -p agent.AppDir/usr/bin
cp artifacts/agent/capydeploy-agent-tauri agent.AppDir/usr/bin/
chmod +x agent.AppDir/usr/bin/capydeploy-agent-tauri
cp apps/agents/agent-tauri/src-tauri/icons/icon.png agent.AppDir/capydeploy-agent.png
generate_desktop "capydeploy-agent-tauri" "CapyDeploy Agent" "capydeploy-agent" "agent.AppDir/capydeploy-agent.desktop"

- name: Bundle libraries
env:
APPIMAGE_EXTRACT_AND_RUN: "1"
run: |
# Bundle shared libraries with linuxdeploy
./linuxdeploy --appdir hub.AppDir \
--executable hub.AppDir/usr/bin/capydeploy-hub-tauri \
--desktop-file hub.AppDir/capydeploy-hub.desktop \
--icon-file hub.AppDir/capydeploy-hub.png

./linuxdeploy --appdir agent.AppDir \
--executable agent.AppDir/usr/bin/capydeploy-agent-tauri \
--desktop-file agent.AppDir/capydeploy-agent.desktop \
--icon-file agent.AppDir/capydeploy-agent.png

# Bundle WebKit helpers and patch hardcoded paths in the .so
# WEBKIT_EXEC_PATH only works in developer builds, so we binary-patch
# the .so to use relative paths (././ instead of /usr).
WEBKIT_DIR=""
for candidate in /usr/libexec/webkit2gtk-4.1 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.1; do
if [ -d "$candidate" ]; then
WEBKIT_DIR="$candidate"
break
fi
done
if [ -z "$WEBKIT_DIR" ]; then
WKP=$(find /usr -name "WebKitWebProcess" -path "*webkit2gtk*" 2>/dev/null | head -1)
if [ -n "$WKP" ]; then
WEBKIT_DIR=$(dirname "$WKP")
fi
fi

- name: Generate AppRun script
for appdir in hub.AppDir agent.AppDir; do
WEBKIT_HARDCODED=$(strings "$appdir/usr/lib/libwebkit2gtk-4.1.so.0" 2>/dev/null | grep -m1 '/webkit2gtk-4.1$')
if [ -n "$WEBKIT_DIR" ] && [ -n "$WEBKIT_HARDCODED" ]; then
WEBKIT_RELATIVE="././${WEBKIT_HARDCODED#/usr}"
echo "Patching $appdir WebKit path: $WEBKIT_HARDCODED -> $WEBKIT_RELATIVE"
LC_ALL=C sed -i "s|$WEBKIT_HARDCODED|$WEBKIT_RELATIVE|g" "$appdir/usr/lib/libwebkit2gtk-4.1.so.0"
# Copy helpers to the relative path the patched .so expects
HELPERS_DEST="$appdir${WEBKIT_HARDCODED#/usr}"
mkdir -p "$HELPERS_DEST"
cp "$WEBKIT_DIR/WebKitWebProcess" "$HELPERS_DEST/"
cp "$WEBKIT_DIR/WebKitNetworkProcess" "$HELPERS_DEST/"
if [ -d "$WEBKIT_DIR/injected-bundle" ]; then
cp -r "$WEBKIT_DIR/injected-bundle" "$HELPERS_DEST/"
fi
else
echo "::warning::WebKit helpers or library not found for $appdir"
fi
done

# Bundle GLib compiled schemas
if [ -f "/usr/share/glib-2.0/schemas/gschemas.compiled" ]; then
echo "Bundling GLib schemas..."
for appdir in hub.AppDir agent.AppDir; do
mkdir -p "$appdir/usr/share/glib-2.0/schemas"
cp /usr/share/glib-2.0/schemas/gschemas.compiled "$appdir/usr/share/glib-2.0/schemas/"
done
fi

# Bundle GIO modules (TLS support)
GIO_DIR=$(pkg-config --variable=giomoduledir gio-2.0 2>/dev/null || echo "/usr/lib/x86_64-linux-gnu/gio/modules")
if [ -d "$GIO_DIR" ]; then
echo "Bundling GIO modules from $GIO_DIR..."
for appdir in hub.AppDir agent.AppDir; do
mkdir -p "$appdir/usr/lib/gio/modules"
cp "$GIO_DIR"/*.so "$appdir/usr/lib/gio/modules/"
done
fi

# Bundle GDK pixbuf loaders
PIXBUF_DIR="/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0"
if compgen -G "$PIXBUF_DIR/loaders/*.so" > /dev/null 2>&1; then
echo "Bundling GDK pixbuf loaders..."
for appdir in hub.AppDir agent.AppDir; do
mkdir -p "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders"
cp "$PIXBUF_DIR/loaders"/*.so "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/"
if command -v gdk-pixbuf-query-loaders &>/dev/null; then
GDK_PIXBUF_MODULEDIR="$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" \
gdk-pixbuf-query-loaders > "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
fi
done
fi

- name: Generate AppRun scripts
run: |
generate_apprun() {
local binary_name="$1"
local desktop_name="$2"
local display_name="$3"
local find_pattern="$4"
local output="$5"
# Remove linuxdeploy's AppRun (symlink to binary) to avoid overwriting the binary
rm -f "$output"
cat > "$output" << APPRUN_EOF
#!/bin/bash
SELF=\$(readlink -f "\$0")
HERE=\${SELF%/*}
APPIMAGE="\${APPIMAGE:-\$SELF}"
APP_NAME="${binary_name}"
APP_NAME="${display_name}"
BINARY_NAME="${binary_name}"
DESKTOP_NAME="${desktop_name}"
INSTALL_DIR="\$HOME/.local/bin"
DESKTOP_DIR="\$HOME/.local/share/applications"
ICON_DIR="\$HOME/.local/share/icons"

# Bundled library paths
export LD_LIBRARY_PATH="\${HERE}/usr/lib:\${LD_LIBRARY_PATH}"
export GIO_MODULE_DIR="\${HERE}/usr/lib/gio/modules"
export GDK_PIXBUF_MODULE_FILE="\${HERE}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
export GSETTINGS_SCHEMA_DIR="\${HERE}/usr/share/glib-2.0/schemas"

# WebKit helpers use paths patched to be relative (././ prefix),
# so we must cd to the AppDir root for them to resolve correctly.
cd "\${HERE}"

install_app() {
echo "Installing \$APP_NAME..."
mkdir -p "\$INSTALL_DIR" "\$DESKTOP_DIR" "\$ICON_DIR"
Expand Down Expand Up @@ -205,36 +341,7 @@ jobs:
chmod +x "$output"
}

generate_desktop() {
local binary_name="$1"
local display_name="$2"
local output="$3"
cat > "$output" << DESKTOP_EOF
[Desktop Entry]
Name=${display_name}
Comment=Deploy games to Steam Deck and Linux devices
Exec=${binary_name}
Icon=${binary_name}
Type=Application
Categories=Game;Development;
Terminal=false
DESKTOP_EOF
}

# Hub AppDir
mkdir -p hub.AppDir/usr/bin
cp artifacts/hub/capydeploy-hub-tauri hub.AppDir/usr/bin/
chmod +x hub.AppDir/usr/bin/capydeploy-hub-tauri
cp apps/hub-tauri/src-tauri/icons/icon.png hub.AppDir/capydeploy-hub.png
generate_desktop "capydeploy-hub" "CapyDeploy Hub" "hub.AppDir/capydeploy-hub.desktop"
generate_apprun "capydeploy-hub-tauri" "capydeploy-hub" "CapyDeploy Hub" "*capydeploy*hub*.AppImage" "hub.AppDir/AppRun"

# Agent AppDir
mkdir -p agent.AppDir/usr/bin
cp artifacts/agent/capydeploy-agent-tauri agent.AppDir/usr/bin/
chmod +x agent.AppDir/usr/bin/capydeploy-agent-tauri
cp apps/agents/agent-tauri/src-tauri/icons/icon.png agent.AppDir/capydeploy-agent.png
generate_desktop "capydeploy-agent" "CapyDeploy Agent" "agent.AppDir/capydeploy-agent.desktop"
generate_apprun "capydeploy-agent-tauri" "capydeploy-agent" "CapyDeploy Agent" "*capydeploy*agent*.AppImage" "agent.AppDir/AppRun"

- name: Build AppImages
Expand Down
119 changes: 119 additions & 0 deletions build_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@ generate_appimage() {
echo -e " ${GREEN}Downloaded${NC}"
fi

# Download linuxdeploy if needed (for bundling shared libraries)
local linuxdeploy="$TOOLS_DIR/linuxdeploy-$appimage_arch.AppImage"
if [ ! -f "$linuxdeploy" ]; then
echo " Downloading linuxdeploy..."
mkdir -p "$TOOLS_DIR"
curl -L -o "$linuxdeploy" \
"https://github.com/linuxdeploy/linuxdeploy/releases/download/continuous/linuxdeploy-$appimage_arch.AppImage"
chmod +x "$linuxdeploy"
echo -e " ${GREEN}Downloaded${NC}"
fi

# Create AppDir
rm -rf "$appdir"
mkdir -p "$appdir/usr/bin"
Expand All @@ -124,7 +135,105 @@ Categories=Game;Development;
Terminal=false
DESKTOP

# Bundle shared libraries with linuxdeploy
echo " Bundling shared libraries..."
APPIMAGE_EXTRACT_AND_RUN=1 "$linuxdeploy" \
--appdir "$appdir" \
--executable "$appdir/usr/bin/$binary_name" \
--desktop-file "$appdir/$desktop_id.desktop" \
--icon-file "$appdir/$desktop_id.png"

# Bundle WebKit helper processes and patch hardcoded paths
# WebKit hardcodes the helper path at compile time and WEBKIT_EXEC_PATH
# only works in developer builds. We must binary-patch the .so to use
# relative paths (././ instead of /usr) and cd to AppDir before exec.
local webkit_hardcoded
webkit_hardcoded=$(strings "$appdir/usr/lib/libwebkit2gtk-4.1.so.0" 2>/dev/null | grep -m1 '/webkit2gtk-4.1$')
local webkit_dir=""
for candidate in /usr/libexec/webkit2gtk-4.1 /usr/lib/x86_64-linux-gnu/webkit2gtk-4.1 /usr/lib64/webkit2gtk-4.1; do
if [ -d "$candidate" ]; then
webkit_dir="$candidate"
break
fi
done
if [ -z "$webkit_dir" ]; then
local wkp
wkp=$(find /usr -name "WebKitWebProcess" -path "*webkit2gtk*" 2>/dev/null | head -1)
if [ -n "$wkp" ]; then
webkit_dir=$(dirname "$wkp")
fi
fi
if [ -n "$webkit_dir" ] && [ -n "$webkit_hardcoded" ]; then
local webkit_relative="././${webkit_hardcoded#/usr}"
echo " Patching WebKit path: $webkit_hardcoded -> $webkit_relative"
LC_ALL=C sed -i "s|$webkit_hardcoded|$webkit_relative|g" "$appdir/usr/lib/libwebkit2gtk-4.1.so.0"
# Copy helpers to the relative path that the patched .so expects
local helpers_dest="$appdir${webkit_hardcoded#/usr}"
mkdir -p "$helpers_dest"
cp "$webkit_dir/WebKitWebProcess" "$helpers_dest/"
cp "$webkit_dir/WebKitNetworkProcess" "$helpers_dest/"
# Copy injected bundle if present
if [ -d "$webkit_dir/injected-bundle" ]; then
cp -r "$webkit_dir/injected-bundle" "$helpers_dest/"
fi
echo " Bundling WebKit helpers from $webkit_dir"
else
echo -e " ${YELLOW}[WARN]${NC} WebKit helpers or library not found"
fi

# Bundle GLib compiled schemas
if [ -f "/usr/share/glib-2.0/schemas/gschemas.compiled" ]; then
echo " Bundling GLib schemas..."
mkdir -p "$appdir/usr/share/glib-2.0/schemas"
cp /usr/share/glib-2.0/schemas/gschemas.compiled "$appdir/usr/share/glib-2.0/schemas/"
fi

# Bundle GIO modules (TLS support)
local gio_dir
gio_dir=$(pkg-config --variable=giomoduledir gio-2.0 2>/dev/null)
if [ -z "$gio_dir" ] || [ ! -d "$gio_dir" ]; then
for candidate in /usr/lib/x86_64-linux-gnu/gio/modules /usr/lib64/gio/modules; do
if [ -d "$candidate" ]; then
gio_dir="$candidate"
break
fi
done
fi
if [ -n "$gio_dir" ] && [ -d "$gio_dir" ]; then
echo " Bundling GIO modules from $gio_dir..."
mkdir -p "$appdir/usr/lib/gio/modules"
cp "$gio_dir"/*.so "$appdir/usr/lib/gio/modules/"
fi

# Bundle GDK pixbuf loaders
local pixbuf_module_dir
pixbuf_module_dir=$(pkg-config --variable=gdk_pixbuf_moduledir gdk-pixbuf-2.0 2>/dev/null)
local pixbuf_dir=""
if [ -n "$pixbuf_module_dir" ] && [ -d "$pixbuf_module_dir" ]; then
pixbuf_dir=$(dirname "$pixbuf_module_dir")
else
for candidate in /usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0 /usr/lib64/gdk-pixbuf-2.0/2.10.0; do
if [ -d "$candidate" ]; then
pixbuf_dir="$candidate"
break
fi
done
fi
if [ -n "$pixbuf_dir" ] && compgen -G "$pixbuf_dir/loaders/*.so" > /dev/null 2>&1; then
echo " Bundling GDK pixbuf loaders..."
mkdir -p "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders"
cp "$pixbuf_dir/loaders"/*.so "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders/"
if command -v gdk-pixbuf-query-loaders &>/dev/null; then
GDK_PIXBUF_MODULEDIR="$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders" \
gdk-pixbuf-query-loaders > "$appdir/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
fi
fi

echo -e " ${GREEN}Libraries bundled${NC}"

# Create AppRun with install/uninstall support
# Remove linuxdeploy's AppRun (symlink to binary) to avoid overwriting the binary
rm -f "$appdir/AppRun"
cat > "$appdir/AppRun" << 'APPRUN'
#!/bin/bash
SELF=$(readlink -f "$0")
Expand All @@ -137,6 +246,16 @@ INSTALL_DIR="$HOME/.local/bin"
DESKTOP_DIR="$HOME/.local/share/applications"
ICON_DIR="$HOME/.local/share/icons"

# Bundled library paths
export LD_LIBRARY_PATH="${HERE}/usr/lib:${LD_LIBRARY_PATH}"
export GIO_MODULE_DIR="${HERE}/usr/lib/gio/modules"
export GDK_PIXBUF_MODULE_FILE="${HERE}/usr/lib/gdk-pixbuf-2.0/2.10.0/loaders.cache"
export GSETTINGS_SCHEMA_DIR="${HERE}/usr/share/glib-2.0/schemas"

# WebKit helpers use paths patched to be relative (././ prefix),
# so we must cd to the AppDir root for them to resolve correctly.
cd "${HERE}"

install_app() {
echo "Installing $APP_NAME..."

Expand Down