#!/usr/bin/env bash # scripts/make-appimage.sh: build a Sheaf AppImage (+ .zsync delta-update # file) from a prebuilt wails binary. Used by .tangled/workflows/release.yml; # runnable locally with `just appimage` (which needs appimagetool and zsync). # # bash scripts/make-appimage.sh [zsync-url] # # e.g. bash scripts/make-appimage.sh 1.0.0 build/bin/sheaf dist \ # "https://katsuricata.tngl.io/sheaf/latest/sheaf-latest-x86_64.AppImage.zsync" # # is baked into the AppImage as update information (what # AppImageUpdate reads). Pass it only for releases; a local build gets no # update info, which AppImageUpdate treats as "not updatable" — the correct # behaviour for a throwaway binary. # # Sheaf dynamically links the host's gtk3/webkit2gtk-4.1, so the AppImage is # a portable launcher + desktop integration, not a bundled-runtime container: # it runs on any distro shipping webkit2gtk-4.1, same contract as the raw # binary release. set -euo pipefail VERSION="${1:?version (e.g. 1.0.0)}" BINARY="${2:?path to built sheaf binary}" OUT_DIR="${3:?output directory for the .AppImage}" ZSYNC_URL="${4:-}" REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" APPIMAGETOOL="${APPIMAGETOOL:-appimagetool-x86_64.AppImage}" PKG_NAME="sheaf-${VERSION}-x86_64.AppImage" ROOT="$(mktemp -d)"; trap 'rm -rf "$ROOT"' EXIT APPDIR="$ROOT/Sheaf.AppDir"; mkdir -p "$APPDIR" # the hicolor PNG size set is generated from packaging/linux/sheaf.svg. Render # it now if a from-source consumer has not run scripts/render-icons.sh yet. if [ ! -f "$REPO_ROOT/build/icons/1024x1024/com.doubledecimal.sheaf.png" ]; then bash "$REPO_ROOT/scripts/render-icons.sh" fi # AppRun: the AppImage entry point. $APPDIR is set by the AppImage runtime; # the fallback keeps the file runnable when the AppDir is inspected directly. cat > "$APPDIR/AppRun" <<'EOF' #!/bin/sh exec "${APPDIR:-$(dirname "$(readlink -f "$0")")}/usr/bin/sheaf" "$@" EOF chmod 755 "$APPDIR/AppRun" install -Dm755 "$BINARY" "$APPDIR/usr/bin/sheaf" install -Dm644 "$REPO_ROOT/packaging/linux/com.doubledecimal.sheaf.desktop" \ "$APPDIR/com.doubledecimal.sheaf.desktop" install -Dm644 "$REPO_ROOT/packaging/linux/com.doubledecimal.sheaf.metainfo.xml" \ "$APPDIR/usr/share/metainfo/com.doubledecimal.sheaf.metainfo.xml" # icon: canonical SVG + per-size PNGs (rendered by scripts/render-icons.sh), # named for the reverse-DNS app-id. The scalable entry is what lets Qt/KWin # resolve the Wayland titlebar/taskbar icon at any size. The PNGs are fallback. install -Dm644 "$REPO_ROOT/packaging/linux/sheaf.svg" \ "$APPDIR/com.doubledecimal.sheaf.svg" install -Dm644 "$REPO_ROOT/packaging/linux/sheaf.svg" \ "$APPDIR/usr/share/icons/hicolor/scalable/apps/com.doubledecimal.sheaf.svg" for s in 16 32 48 64 128 256 512 1024; do install -Dm644 "$REPO_ROOT/build/icons/${s}x${s}/com.doubledecimal.sheaf.png" \ "$APPDIR/usr/share/icons/hicolor/${s}x${s}/apps/com.doubledecimal.sheaf.png" done # appimagetool's AppDir lint wants a 256x256 PNG at a conventional path. install -Dm644 "$REPO_ROOT/build/icons/256x256/com.doubledecimal.sheaf.png" \ "$APPDIR/usr/share/pixmaps/com.doubledecimal.sheaf.png" install -Dm644 "$REPO_ROOT/LICENSE.md" \ "$APPDIR/usr/share/licenses/sheaf/LICENSE.md" mkdir -p "$OUT_DIR" # appimagetool is itself an AppImage and needs FUSE; extract-and-run keeps it # working in containers/CI without it. ARCH is required when the tool's build # arch string does not match what it detects on the host. export ARCH=x86_64 APPIMAGE_EXTRACT_AND_RUN=1 UPDATE_ARGS=() if [ -n "$ZSYNC_URL" ]; then UPDATE_ARGS=(-u "zsync|$ZSYNC_URL") fi "$APPIMAGETOOL" --comp zstd "${UPDATE_ARGS[@]}" "$APPDIR" "$OUT_DIR/$PKG_NAME" # zsyncmake is bundled inside appimagetool's AppDir and only runs when the # update-info flag is passed. The release workflow wants the .zsync even for # local verification, so generate it unconditionally when zsyncmake exists. if [ -n "$ZSYNC_URL" ] && command -v zsyncmake >/dev/null 2>&1; then (cd "$OUT_DIR" && zsyncmake -u "$PKG_NAME" "$PKG_NAME") fi echo "built $OUT_DIR/$PKG_NAME" [ -z "$ZSYNC_URL" ] || echo "update info: zsync|$ZSYNC_URL"