From c1c52aa0222aa65a51dcdf40da30fde7a9c065e7 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 26 Apr 2026 07:08:20 +0000 Subject: [PATCH 1/2] fix(deb): broaden libicu Depends so .deb installs across Debian/Ubuntu MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit jpackage runs `dpkg-shlibdeps` against the bundled JDK runtime's native libs (libfontmanager.so etc. link libicu) and pins Depends to the build host's libicu version. CI builds on ubuntu-24.04, so the .deb requires libicu74 — uninstallable on Ubuntu 22.04 (libicu70), Debian 12 (libicu72), Debian 11 (libicu67), and Debian 13 (libicu76). Neither jpackage nor the Compose Multiplatform DSL exposes a way to override the auto-generated Depends. Add scripts/relax-deb-libicu.sh which extracts the .deb with `dpkg-deb -R`, rewrites `libicuNN` (or any alternation thereof) to `libicu66 | libicu67 | libicu70 | libicu72 | libicu74 | libicu76 | libicu77`, and repacks. The script is idempotent and a no-op for .debs without a libicu Depends. Wire it into both release legs (desktopApp + amy CLI) in create-release.yml, and into the desktop test/build leg in build.yml so testers downloading the CI artifact hit the same fix. --- .github/workflows/build.yml | 10 +++++++ .github/workflows/create-release.yml | 18 ++++++++++++ scripts/relax-deb-libicu.sh | 41 ++++++++++++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100755 scripts/relax-deb-libicu.sh diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a120a8a5e..347c7b548 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -68,6 +68,16 @@ jobs: - name: Test + Build Desktop (gradle) run: ./gradlew :quartz:jvmTest :commons:jvmTest :nestsClient:jvmTest :cli:test :desktopApp:test :desktopApp:${{ matrix.desktop-task }} --no-daemon + # jpackage pins libicu to the build host's version (libicu74 on + # ubuntu-24.04). Rewrite the .deb so testers on other Debian/Ubuntu + # releases can install the uploaded artifact. + - name: Relax libicu dependency in .deb + if: matrix.desktop-task == 'packageDeb' + run: | + set -euo pipefail + chmod +x scripts/relax-deb-libicu.sh + scripts/relax-deb-libicu.sh desktopApp/build/compose/binaries/main/deb/*.deb + - name: Upload Desktop Distribution uses: actions/upload-artifact@v7 with: diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 0ac241bfb..e5ce7edcd 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -103,6 +103,15 @@ jobs: timeout_minutes: 15 command: ./gradlew --no-daemon :desktopApp:${{ matrix.tasks }} + # jpackage pins libicu to the build host's version (libicu74 on + # ubuntu-24.04). Rewrite the .deb so it installs across Debian/Ubuntu. + - name: Relax libicu dependency in .deb + if: matrix.family == 'linux' + run: | + set -euo pipefail + chmod +x scripts/relax-deb-libicu.sh + scripts/relax-deb-libicu.sh desktopApp/build/compose/binaries/main-release/deb/*.deb + - name: Build portable archives (windows + linux-portable) if: matrix.family == 'windows' || matrix.family == 'linux-portable' run: | @@ -248,6 +257,15 @@ jobs: timeout_minutes: 15 command: ./gradlew --no-daemon :cli:${{ matrix.tasks }} + # jpackage pins libicu to the build host's version (libicu74 on + # ubuntu-24.04). Rewrite the .deb so it installs across Debian/Ubuntu. + - name: Relax libicu dependency in .deb + if: matrix.family == 'linux' + run: | + set -euo pipefail + chmod +x scripts/relax-deb-libicu.sh + scripts/relax-deb-libicu.sh cli/build/jpackage/*.deb + - name: Collect + rename assets run: | set -euo pipefail diff --git a/scripts/relax-deb-libicu.sh b/scripts/relax-deb-libicu.sh new file mode 100755 index 000000000..9e0a25ee3 --- /dev/null +++ b/scripts/relax-deb-libicu.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +# Broaden the libicu Depends clause in a jpackage-built .deb so it installs +# across Debian/Ubuntu releases. +# +# jpackage shells out to `dpkg-shlibdeps` against the bundled JDK runtime's +# native libraries (libfontmanager.so, etc., which link libicu). That pins the +# Depends to whatever libicu the build host ships — libicu74 on ubuntu-24.04 — +# even though the bundled JRE works fine against any reasonably recent ICU. +# Without this rewrite, users on Ubuntu 22.04 (libicu70), Debian 12 (libicu72), +# Debian 11 (libicu67), or Debian 13 (libicu76) cannot install the package. +# +# Neither jpackage nor the Compose Multiplatform DSL exposes a way to override +# the auto-generated Depends, so we rewrite the .deb after the fact. +# +# Usage: relax-deb-libicu.sh [ ...] +set -euo pipefail + +# Spans Debian 11 → 13 and Ubuntu 20.04 → 26.04. Append new SONAMEs here when +# a new Debian/Ubuntu release ships a bumped libicu. +ALT='libicu66 | libicu67 | libicu70 | libicu72 | libicu74 | libicu76 | libicu77' + +for deb in "$@"; do + if [[ ! -f "$deb" ]]; then + echo "skip: not a file: $deb" >&2 + continue + fi + + work="$(mktemp -d)" + dpkg-deb -R "$deb" "$work/pkg" + control="$work/pkg/DEBIAN/control" + + if grep -qE 'libicu[0-9]+' "$control"; then + sed -i -E "s/libicu[0-9]+([[:space:]]*\\|[[:space:]]*libicu[0-9]+)*/${ALT}/g" "$control" + dpkg-deb -b "$work/pkg" "$deb" >/dev/null + echo "Relaxed libicu dep: $deb" + else + echo "No libicu dep, leaving as-is: $deb" + fi + + rm -rf "$work" +done From 450c740c62cf1641de9922ccabcab2a9d07dc366 Mon Sep 17 00:00:00 2001 From: nrobi144 Date: Mon, 27 Apr 2026 10:39:24 +0300 Subject: [PATCH 2/2] fix(packaging): add trap cleanup and xz compression to deb rewriter Address review findings: - Add trap for temp dir cleanup on error - Use -Zxz for max distro compatibility (older dpkg lacks zstd) - Use --root-owner-group for correct file ownership Co-Authored-By: Claude Opus 4.6 (1M context) --- scripts/relax-deb-libicu.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/relax-deb-libicu.sh b/scripts/relax-deb-libicu.sh index 9e0a25ee3..27f96c8f2 100755 --- a/scripts/relax-deb-libicu.sh +++ b/scripts/relax-deb-libicu.sh @@ -26,16 +26,18 @@ for deb in "$@"; do fi work="$(mktemp -d)" + trap 'rm -rf "$work"' EXIT dpkg-deb -R "$deb" "$work/pkg" control="$work/pkg/DEBIAN/control" if grep -qE 'libicu[0-9]+' "$control"; then sed -i -E "s/libicu[0-9]+([[:space:]]*\\|[[:space:]]*libicu[0-9]+)*/${ALT}/g" "$control" - dpkg-deb -b "$work/pkg" "$deb" >/dev/null + dpkg-deb --root-owner-group -Zxz -b "$work/pkg" "$deb" >/dev/null echo "Relaxed libicu dep: $deb" else echo "No libicu dep, leaving as-is: $deb" fi rm -rf "$work" + trap - EXIT done