#!/usr/bin/env bash # Wraps the jpackage app-image produced by :desktopApp:packageReleaseAppImage # into a real Linux .AppImage. # # Compose Multiplatform's TargetFormat.AppImage is jpackage's "app-image": an # unpacked application directory (bin/, lib/...), NOT the single-file # AppImage bundle format. This script builds the AppDir scaffolding (AppRun, # .desktop entry, icon) around that directory and packs it with appimagetool. # # The output lands in main-release/appimage/ so the existing release upload # and attestation globs (main-release/*/*.AppImage) pick it up unchanged. # # Expects to run on a Linux host of the target architecture (x86_64/aarch64) # with APP_VERSION_NAME set (e.g. 2.8.0). appimagetool and the AppImage # runtime are downloaded pinned by version AND sha256 — bump the four hashes # together with the version pins below. set -euo pipefail VERSION="${APP_VERSION_NAME:?APP_VERSION_NAME must be set (e.g. 2.8.0)}" BINARIES_DIR="${BINARIES_DIR:-desktopApp/build/compose/binaries/main-release}" APPIMAGETOOL_VERSION="1.9.1" RUNTIME_VERSION="20251108" ARCH="$(uname -m)" case "$ARCH" in x86_64) APPIMAGETOOL_SHA256="ed4ce84f0d9caff66f50bcca6ff6f35aae54ce8135408b3fa33abfc3cb384eb0" RUNTIME_SHA256="2fca8b443c92510f1483a883f60061ad09b46b978b2631c807cd873a47ec260d" ;; aarch64) APPIMAGETOOL_SHA256="f0837e7448a0c1e4e650a93bb3e85802546e60654ef287576f46c71c126a9158" RUNTIME_SHA256="00cbdfcf917cc6c0ff6d3347d59e0ca1f7f45a6df1a428a0d6d8a78664d87444" ;; *) echo "::error::Unsupported architecture for AppImage: ${ARCH}" >&2 exit 1 ;; esac # --- Locate the jpackage app-image (directory name = CMP packageName; may contain spaces) --- app_dir="" count=0 for d in "${BINARIES_DIR}/app"/*/; do [ -d "$d" ] || continue app_dir="${d%/}" count=$((count + 1)) done if [ "$count" -ne 1 ]; then echo "::error::Expected exactly one app-image directory under ${BINARIES_DIR}/app, found ${count}" >&2 exit 1 fi app_name="$(basename "$app_dir")" launcher="${app_dir}/bin/${app_name}" if [ ! -x "$launcher" ]; then echo "::error::jpackage launcher not found or not executable: ${launcher}" >&2 exit 1 fi icon="${app_dir}/lib/${app_name}.png" if [ ! -f "$icon" ]; then # jpackage normally drops the icon at lib/.png; fall back to the source icon. icon="desktopApp/src/main/resources/icon.png" fi if [ ! -f "$icon" ]; then echo "::error::No icon found for the AppImage (looked in lib/ and desktopApp resources)" >&2 exit 1 fi # Desktop-entry id / output-name slug: "Meshtastic Desktop" -> meshtastic-desktop slug="$(printf '%s' "$app_name" | tr '[:upper:]' '[:lower:]' | tr ' ' '-')" # --- Assemble the AppDir --- out_dir="${BINARIES_DIR}/appimage" appdir="${out_dir}/${slug}.AppDir" rm -rf "$appdir" mkdir -p "$appdir" cp -a "${app_dir}/." "$appdir/" cat > "${appdir}/AppRun" < "${appdir}/${slug}.desktop" <