From c41acd7e6c7f17cf060f81a700230135caabe862 Mon Sep 17 00:00:00 2001 From: Sunil Kumar Date: Thu, 28 May 2026 19:17:49 +0530 Subject: [PATCH] ci(release): add linux arm64 desktop artifacts (#2675) Signed-off-by: sunilkumarvalmiki --- .github/workflows/build-desktop.yml | 13 ++++-- .github/workflows/release-production.yml | 4 ++ scripts/fixtures/latest.json | 4 ++ scripts/install.sh | 19 ++++---- scripts/release/publish-updater-manifest.sh | 8 +++- .../release/strip-appimage-graphics-libs.sh | 46 +++++++++++++++++-- scripts/test_install.sh | 11 ++--- scripts/validate-release-assets.sh | 4 +- 8 files changed, 80 insertions(+), 29 deletions(-) diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 2b6732b25..e4804852e 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -85,8 +85,7 @@ on: type: boolean default: false skip_pretests: - description: - Metadata-only flag propagated by caller workflows when they + description: Metadata-only flag propagated by caller workflows when they intentionally bypass the upstream pretest phase. This reusable build workflow does not execute pretests itself, but it logs the policy so the build run captures whether the normal release gate was relaxed for @@ -124,6 +123,10 @@ jobs: args: --target x86_64-unknown-linux-gnu --bundles deb appimage target: x86_64-unknown-linux-gnu artifact_suffix: ubuntu + - platform: ubuntu-24.04-arm + args: --target aarch64-unknown-linux-gnu --bundles deb appimage + target: aarch64-unknown-linux-gnu + artifact_suffix: ubuntu-arm64 - platform: windows-latest args: --target x86_64-pc-windows-msvc target: x86_64-pc-windows-msvc @@ -162,7 +165,7 @@ jobs: with: targets: ${{ matrix.settings.platform == 'macos-latest' && 'aarch64-apple-darwin,x86_64-apple-darwin' || '' }} - name: Install Tauri dependencies (ubuntu only) - if: matrix.settings.platform == 'ubuntu-24.04' + if: startsWith(matrix.settings.platform, 'ubuntu-') run: | sudo apt-get update sudo apt-get install -y \ @@ -458,7 +461,7 @@ jobs: # ensures this still runs when `cargo tauri build` failed at bundling # (the binary itself is produced before bundling starts). - name: Dump linked libraries of built binary (ubuntu debug) - if: always() && matrix.settings.platform == 'ubuntu-24.04' + if: always() && startsWith(matrix.settings.platform, 'ubuntu-') shell: bash env: PROFILE: ${{ inputs.build_profile }} @@ -487,7 +490,7 @@ jobs: # untouched. Re-signs the AppImage + updater tarball when signing # is enabled. - name: Strip host graphics libs from AppImage - if: matrix.settings.platform == 'ubuntu-24.04' + if: startsWith(matrix.settings.platform, 'ubuntu-') shell: bash env: MATRIX_TARGET: ${{ matrix.settings.target }} diff --git a/.github/workflows/release-production.yml b/.github/workflows/release-production.yml index 3a550e043..256e704ac 100644 --- a/.github/workflows/release-production.yml +++ b/.github/workflows/release-production.yml @@ -668,6 +668,10 @@ jobs: // Linux desktop installer consumed by scripts/install.sh and // advertised in latest.json as linux-x86_64. /OpenHuman_.*_amd64\.AppImage$/, + // Linux arm64 desktop installer consumed by scripts/install.sh + // and advertised in latest.json as linux-aarch64. + /OpenHuman_.*_(arm64|aarch64)\.AppImage$/, + /OpenHuman_.*_(arm64|aarch64)\.deb$/, // Auto-updater manifest — without this, installed clients can't // discover new releases via plugins.updater.endpoints. /^latest\.json$/, diff --git a/scripts/fixtures/latest.json b/scripts/fixtures/latest.json index 6a24b103c..1a52cec4a 100644 --- a/scripts/fixtures/latest.json +++ b/scripts/fixtures/latest.json @@ -5,6 +5,10 @@ "url": "https://example.invalid/openhuman_0.0.0-test_amd64.AppImage", "signature": "" }, + "linux-aarch64": { + "url": "https://example.invalid/openhuman_0.0.0-test_arm64.AppImage", + "signature": "" + }, "darwin-aarch64": { "url": "https://example.invalid/openhuman_0.0.0-test_aarch64.dmg", "signature": "" diff --git a/scripts/install.sh b/scripts/install.sh index c073bf820..2bf8b4959 100644 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -143,22 +143,14 @@ case "${ARCH_RAW}" in ;; esac -if [ "${OS}" = "linux" ] && [ "${ARCH}" != "x86_64" ]; then - if [ "${DRY_RUN}" = true ]; then - log_warn "Linux installer currently supports x86_64 only; no install asset resolved for ${ARCH}." - echo "DRY RUN: skipping install for ${OS}/${ARCH} - no compatible asset is published." - exit 0 - fi - log_err "Linux installer currently supports x86_64 only." - exit 1 -fi - if [ "${OS}" = "darwin" ] && [ "${ARCH}" = "aarch64" ]; then PLATFORM_KEY="darwin-aarch64" elif [ "${OS}" = "darwin" ] && [ "${ARCH}" = "x86_64" ]; then PLATFORM_KEY="darwin-x86_64" elif [ "${OS}" = "linux" ] && [ "${ARCH}" = "x86_64" ]; then PLATFORM_KEY="linux-x86_64" +elif [ "${OS}" = "linux" ] && [ "${ARCH}" = "aarch64" ]; then + PLATFORM_KEY="linux-aarch64" fi log_ok "Detected platform: ${OS}/${ARCH}" @@ -344,7 +336,12 @@ def choose_asset(): break elif os_name == "linux" and arch == "x86_64": for n in names: - if n.endswith(".AppImage"): + if re.search(r"amd64\.AppImage$", n): + chosen = n + break + elif os_name == "linux" and arch == "aarch64": + for n in names: + if re.search(r"(arm64|aarch64)\.AppImage$", n): chosen = n break if not chosen: diff --git a/scripts/release/publish-updater-manifest.sh b/scripts/release/publish-updater-manifest.sh index 91f7772d5..8e474172e 100755 --- a/scripts/release/publish-updater-manifest.sh +++ b/scripts/release/publish-updater-manifest.sh @@ -87,21 +87,24 @@ read_sig() { # darwin-aarch64 — macOS Apple Silicon # darwin-x86_64 — macOS Intel # linux-x86_64 — Linux glibc x64 (AppImage) +# linux-aarch64 — Linux glibc arm64 (AppImage) # windows-x86_64 — Windows x64 (NSIS setup) # # Naming conventions emitted by tauri-bundler with createUpdaterArtifacts: # darwin : __.app.tar.gz -# linux : __amd64.AppImage +# linux : __amd64.AppImage / __arm64.AppImage # windows : __x64-setup.exe MAC_AARCH64=$(find_asset "^OpenHuman(_| ).*aarch64(-apple-darwin)?\.app\.tar\.gz$") MAC_X86_64=$(find_asset "^OpenHuman(_| ).*(x64|x86_64)(-apple-darwin)?\.app\.tar\.gz$") LIN_X86_64=$(find_asset "^OpenHuman(_| ).*amd64\.AppImage$") +LIN_AARCH64=$(find_asset "^OpenHuman(_| ).*(arm64|aarch64)\.AppImage$") WIN_X86_64=$(find_asset "^OpenHuman(_| ).*x64-setup\.exe$") echo "[updater] Resolved updater bundles:" echo " darwin-aarch64 = ${MAC_AARCH64:-}" echo " darwin-x86_64 = ${MAC_X86_64:-}" echo " linux-x86_64 = ${LIN_X86_64:-}" +echo " linux-aarch64 = ${LIN_AARCH64:-}" echo " windows-x86_64 = ${WIN_X86_64:-}" PUB_DATE=$(date -u +"%Y-%m-%dT%H:%M:%S.000Z") @@ -132,12 +135,13 @@ add_platform() { add_platform "darwin-aarch64" "$MAC_AARCH64" add_platform "darwin-x86_64" "$MAC_X86_64" add_platform "linux-x86_64" "$LIN_X86_64" +add_platform "linux-aarch64" "$LIN_AARCH64" add_platform "windows-x86_64" "$WIN_X86_64" # Require every platform advertised by the public installers. A partial # latest.json leaves install.sh resolving a documented platform to nothing. missing_platforms=$(jq -r ' - ["darwin-aarch64", "darwin-x86_64", "linux-x86_64", "windows-x86_64"] + ["darwin-aarch64", "darwin-x86_64", "linux-x86_64", "linux-aarch64", "windows-x86_64"] - (.platforms | keys) | join(", ") ' "$MANIFEST") diff --git a/scripts/release/strip-appimage-graphics-libs.sh b/scripts/release/strip-appimage-graphics-libs.sh index e9dab17d2..e2e4faa00 100755 --- a/scripts/release/strip-appimage-graphics-libs.sh +++ b/scripts/release/strip-appimage-graphics-libs.sh @@ -50,7 +50,23 @@ EXCLUDE_PATTERNS=( # Default to a pinned release tag rather than the mutable `continuous` asset so # CI builds are reproducible and resistant to upstream replacement. Override via # APPIMAGETOOL_URL (and bump APPIMAGETOOL_SHA256 alongside it). -APPIMAGETOOL_URL="${APPIMAGETOOL_URL:-https://github.com/AppImage/appimagetool/releases/download/1.9.0/appimagetool-x86_64.AppImage}" +default_appimagetool_url() { + local target_arch="${APPIMAGE_TARGET_ARCH:-${MATRIX_TARGET:-$(uname -m)}}" + case "$target_arch" in + x86_64*|amd64*) + echo "https://github.com/AppImage/appimagetool/releases/download/1.9.0/appimagetool-x86_64.AppImage" + ;; + aarch64*|arm64*) + echo "https://github.com/AppImage/appimagetool/releases/download/1.9.0/appimagetool-aarch64.AppImage" + ;; + *) + echo "[strip-libs] ERROR: unsupported appimagetool architecture: $target_arch" >&2 + return 1 + ;; + esac +} + +APPIMAGETOOL_URL="${APPIMAGETOOL_URL:-$(default_appimagetool_url)}" APPIMAGETOOL_SHA256="${APPIMAGETOOL_SHA256:-}" ensure_appimagetool() { @@ -94,12 +110,31 @@ appimage_loader_name() { x86_64*|amd64*) echo "ld-linux-x86-64.so.2" ;; + aarch64*|arm64*) + echo "ld-linux-aarch64.so.1" + ;; *) return 1 ;; esac } +appimagetool_arch() { + local target_arch="${APPIMAGE_TARGET_ARCH:-${MATRIX_TARGET:-$(uname -m)}}" + case "$target_arch" in + x86_64*|amd64*) + echo "x86_64" + ;; + aarch64*|arm64*) + echo "aarch64" + ;; + *) + echo "[strip-libs] ERROR: unsupported AppImage repack architecture: $target_arch" >&2 + return 1 + ;; + esac +} + host_dynamic_loader() { local loader_name="$1" local candidates=() @@ -355,10 +390,13 @@ strip_one_appimage() { for candidate in \ "$appdir/usr/lib" \ "$appdir/usr/lib/x86_64-linux-gnu" \ + "$appdir/usr/lib/aarch64-linux-gnu" \ "$appdir/shared/lib" \ "$appdir/shared/lib/x86_64-linux-gnu" \ + "$appdir/shared/lib/aarch64-linux-gnu" \ "$appdir/lib" \ - "$appdir/lib/x86_64-linux-gnu"; do + "$appdir/lib/x86_64-linux-gnu" \ + "$appdir/lib/aarch64-linux-gnu"; do [ -d "$candidate" ] && lib_roots+=("$candidate") done @@ -392,9 +430,11 @@ strip_one_appimage() { echo "[strip-libs] Removed $removed file(s), added $added_loader loader file(s); repacking AppImage." local rebuilt="$workdir/$name" + local appimage_arch + appimage_arch="$(appimagetool_arch)" ( cd "$workdir" - ARCH=x86_64 "$APPIMAGETOOL_BIN" --appimage-extract-and-run \ + ARCH="$appimage_arch" "$APPIMAGETOOL_BIN" --appimage-extract-and-run \ --no-appstream squashfs-root "$rebuilt" >/dev/null ) mv "$rebuilt" "$original" diff --git a/scripts/test_install.sh b/scripts/test_install.sh index d0f4bba43..d4cf94f6c 100755 --- a/scripts/test_install.sh +++ b/scripts/test_install.sh @@ -20,13 +20,10 @@ if [[ "$resolved" != "$expected" ]]; then exit 1 fi -# Also test a missing platform produces exit code 3. -set +e -resolve_asset_url "$FIXTURE" "linux" "aarch64" >/dev/null 2>&1 -missing_platform_rc=$? -set -e -if [[ "$missing_platform_rc" -ne 3 ]]; then - echo "FAIL: expected exit code 3 for missing platform linux-aarch64, got $missing_platform_rc" +resolved_arm64=$(resolve_asset_url "$FIXTURE" "linux" "aarch64") +expected_arm64="https://example.invalid/openhuman_0.0.0-test_arm64.AppImage" +if [[ "$resolved_arm64" != "$expected_arm64" ]]; then + echo "FAIL: expected $expected_arm64, got $resolved_arm64" exit 1 fi diff --git a/scripts/validate-release-assets.sh b/scripts/validate-release-assets.sh index 76a57f4c6..d0d90de17 100755 --- a/scripts/validate-release-assets.sh +++ b/scripts/validate-release-assets.sh @@ -58,6 +58,7 @@ SUPPORTED = [ "darwin-aarch64", "darwin-x86_64", "linux-x86_64", + "linux-aarch64", "windows-x86_64", ] @@ -67,7 +68,8 @@ SUPPORTED = [ ASSET_PATTERNS = { "darwin-aarch64": r"aarch64.*\.app\.tar\.gz$|aarch64\.dmg$", "darwin-x86_64": r"(x86_64-apple-darwin|x64).*\.app\.tar\.gz$|x64\.dmg$", - "linux-x86_64": r"\.AppImage$", + "linux-x86_64": r"amd64\.AppImage$", + "linux-aarch64": r"(arm64|aarch64)\.AppImage$", "windows-x86_64": r"x64.*\.msi$|x64.*setup\.exe$", }