From bcf7ec45e59a92bd7ea4b095d85eb0fce35307ca Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 8 Nov 2026 10:42:40 +0100 Subject: [PATCH 1/3] Linux build: download a fixed appimagetool version, with retries and a fallback The 0.30.0 release build failed on Linux only: GitHub answered "504 Gateway Timeout" for appimagetool's "continuous" download (twice, and also for 1.9.1), while 1.9.0 downloads fine. build_linux.sh now gets appimagetool 1.9.0 (APPIMAGETOOL_VERSION to change it), retries a few times, and falls back to the continuous build if that file can't be had. A fixed version also means every build is packed by the same tool. Co-Authored-By: Claude Opus 5.5 --- build_linux.sh | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/build_linux.sh b/build_linux.sh index 3043d42..22a8bb9 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -72,10 +72,29 @@ fi echo "[5/5] Packing the AppImage ..." ARCH="$(uname -m)" TOOL="build/appimagetool-$ARCH.AppImage" +# appimagetool: a fixed version (the same tool on every build), retried a few times; if GitHub can't +# deliver that file, the "continuous" build instead. (November 2026: GitHub answered 504 for the +# continuous and 1.9.1 files for hours, while 1.9.0 downloaded fine.) +APPIMAGETOOL_VERSION="${APPIMAGETOOL_VERSION:-1.9.0}" if [[ ! -x "$TOOL" ]]; then mkdir -p build - curl -fL -o "$TOOL" \ - "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$ARCH.AppImage" + BASE="https://github.com/AppImage/appimagetool/releases/download" + ok=0 + for tag in "$APPIMAGETOOL_VERSION" continuous; do + if curl -fL --retry 4 --retry-delay 10 --retry-all-errors -o "$TOOL.part" \ + "$BASE/$tag/appimagetool-$ARCH.AppImage"; then + mv "$TOOL.part" "$TOOL" + ok=1 + echo "appimagetool: $tag" + break + fi + echo "appimagetool $tag could not be downloaded, trying the next one ..." + done + rm -f "$TOOL.part" + if [[ $ok != 1 ]]; then + echo "Could not download appimagetool (GitHub). Try again later." >&2 + exit 1 + fi chmod +x "$TOOL" fi APPDIR=build/AppDir From 97821fbf585680913e4a13e25778335a96e02d4f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 8 Nov 2026 10:55:08 +0100 Subject: [PATCH 2/3] Linux build: keep trying appimagetool for a few minutes, and cache it between builds GitHub's release downloads answered 504 on and off (also for 1.9.0 on the next try, and also with a cache-busting query), so a few quick retries were not enough. build_linux.sh now tries for up to a few minutes, switching between 1.9.0 and the continuous build, and the CI keeps the tool in GitHub's Actions cache, so later builds don't download it at all. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/build.yml | 8 ++++++++ build_linux.sh | 30 +++++++++++++++++------------- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97a9528..763e123 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -248,6 +248,14 @@ jobs: libxcb-keysyms1 libxcb-shape0 libxcb-image0 libxcb-render-util0 libxcb-randr0 \ libxcb-xinerama0 libxcb-xkb1 libfontconfig1 libdbus-1-3 desktop-file-utils + # appimagetool (the AppImage packing tool) kept between builds: GitHub's release downloads + # sometimes answer 504 for minutes, which failed the 0.30.0 release build. + - name: Cache appimagetool + uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 + with: + path: build/appimagetool-x86_64.AppImage + key: appimagetool-1.9.0-x86_64 + - name: Build (tests + AppImage) run: ./build_linux.sh diff --git a/build_linux.sh b/build_linux.sh index 22a8bb9..2246f7a 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -72,27 +72,31 @@ fi echo "[5/5] Packing the AppImage ..." ARCH="$(uname -m)" TOOL="build/appimagetool-$ARCH.AppImage" -# appimagetool: a fixed version (the same tool on every build), retried a few times; if GitHub can't -# deliver that file, the "continuous" build instead. (November 2026: GitHub answered 504 for the -# continuous and 1.9.1 files for hours, while 1.9.0 downloaded fine.) +# appimagetool: a fixed version (the same tool on every build). GitHub's release downloads sometimes +# answer "504 Gateway Timeout" for minutes at a time (November 2026, the 0.30.0 release), so this +# tries for a few minutes, switching between the fixed version and the "continuous" build. In CI +# the tool is also kept in GitHub's cache (build.yml), so most builds don't download it at all. APPIMAGETOOL_VERSION="${APPIMAGETOOL_VERSION:-1.9.0}" if [[ ! -x "$TOOL" ]]; then mkdir -p build BASE="https://github.com/AppImage/appimagetool/releases/download" ok=0 - for tag in "$APPIMAGETOOL_VERSION" continuous; do - if curl -fL --retry 4 --retry-delay 10 --retry-all-errors -o "$TOOL.part" \ - "$BASE/$tag/appimagetool-$ARCH.AppImage"; then - mv "$TOOL.part" "$TOOL" - ok=1 - echo "appimagetool: $tag" - break - fi - echo "appimagetool $tag could not be downloaded, trying the next one ..." + for round in 1 2 3 4; do + for tag in "$APPIMAGETOOL_VERSION" continuous; do + if curl -fsSL --retry 3 --retry-delay 15 --retry-all-errors -o "$TOOL.part" \ + "$BASE/$tag/appimagetool-$ARCH.AppImage"; then + mv "$TOOL.part" "$TOOL" + ok=1 + echo "appimagetool: $tag" + break 2 + fi + echo "appimagetool $tag: not available right now (round $round of 4)" + done + sleep 20 done rm -f "$TOOL.part" if [[ $ok != 1 ]]; then - echo "Could not download appimagetool (GitHub). Try again later." >&2 + echo "Could not download appimagetool from GitHub. Try again later." >&2 exit 1 fi chmod +x "$TOOL" From 6d1dcb7c43da3708c1b846abe09999a0c8ae9a1c Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 8 Nov 2026 11:08:57 +0100 Subject: [PATCH 3/3] Linux build: fetch the AppImage runtime too, with the runtime inside appimagetool as fallback With appimagetool downloaded, the next run failed one step later: appimagetool fetches the AppImage runtime from GitHub itself, without retries, and got the same 504. build_linux.sh now fetches the runtime (two rounds) and, if GitHub can't deliver it, uses the runtime at the start of appimagetool (an AppImage itself: the first --appimage-offset bytes), and passes it with --runtime-file. Tested: an AppImage built this way runs and reports its update information. Both files are cached in CI. Co-Authored-By: Claude Opus 5.5 --- .github/workflows/build.yml | 12 ++++---- build_linux.sh | 60 +++++++++++++++++++++++-------------- 2 files changed, 45 insertions(+), 27 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 763e123..c84ae8b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -248,13 +248,15 @@ jobs: libxcb-keysyms1 libxcb-shape0 libxcb-image0 libxcb-render-util0 libxcb-randr0 \ libxcb-xinerama0 libxcb-xkb1 libfontconfig1 libdbus-1-3 desktop-file-utils - # appimagetool (the AppImage packing tool) kept between builds: GitHub's release downloads - # sometimes answer 504 for minutes, which failed the 0.30.0 release build. - - name: Cache appimagetool + # appimagetool and the AppImage runtime kept between builds: GitHub's release downloads + # sometimes answer 504 for a long time, which failed the 0.30.0 release build. + - name: Cache appimagetool and the AppImage runtime uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0 with: - path: build/appimagetool-x86_64.AppImage - key: appimagetool-1.9.0-x86_64 + path: | + build/appimagetool-x86_64.AppImage + build/runtime-x86_64 + key: appimagetool-1.9.0-runtime-x86_64 - name: Build (tests + AppImage) run: ./build_linux.sh diff --git a/build_linux.sh b/build_linux.sh index 2246f7a..5e42adf 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -72,35 +72,50 @@ fi echo "[5/5] Packing the AppImage ..." ARCH="$(uname -m)" TOOL="build/appimagetool-$ARCH.AppImage" -# appimagetool: a fixed version (the same tool on every build). GitHub's release downloads sometimes -# answer "504 Gateway Timeout" for minutes at a time (November 2026, the 0.30.0 release), so this -# tries for a few minutes, switching between the fixed version and the "continuous" build. In CI -# the tool is also kept in GitHub's cache (build.yml), so most builds don't download it at all. +# appimagetool (packs the AppImage) and the AppImage runtime (the small program at the start of every +# AppImage) come from GitHub's release downloads, which sometimes answer "504 Gateway Timeout" for +# a long time (November 2026: the 0.30.0 release). So: a fixed appimagetool version, tried for a few +# minutes; the runtime is fetched here too (appimagetool would fetch it itself, with no retries), and +# if GitHub can't deliver it, the runtime inside appimagetool (itself an AppImage) is used. In CI both +# are kept in GitHub's cache (build.yml), so most builds download neither. APPIMAGETOOL_VERSION="${APPIMAGETOOL_VERSION:-1.9.0}" -if [[ ! -x "$TOOL" ]]; then - mkdir -p build - BASE="https://github.com/AppImage/appimagetool/releases/download" - ok=0 - for round in 1 2 3 4; do - for tag in "$APPIMAGETOOL_VERSION" continuous; do - if curl -fsSL --retry 3 --retry-delay 15 --retry-all-errors -o "$TOOL.part" \ - "$BASE/$tag/appimagetool-$ARCH.AppImage"; then - mv "$TOOL.part" "$TOOL" - ok=1 - echo "appimagetool: $tag" - break 2 +RUNTIME="build/runtime-$ARCH" +BASE="https://github.com/AppImage" +mkdir -p build + +fetch() { # fetch FILE ROUNDS URL... : the first URL that answers, trying ROUNDS times + local out="$1" rounds="$2" round url + shift 2 + for ((round = 1; round <= rounds; round++)); do + for url in "$@"; do + if curl -fsSL --retry 2 --retry-delay 10 --retry-all-errors -o "$out.part" "$url"; then + mv "$out.part" "$out" + echo " downloaded ${url##*/download/}" + return 0 fi - echo "appimagetool $tag: not available right now (round $round of 4)" + echo " not available right now: ${url##*/download/} (round $round of $rounds)" done - sleep 20 + ((round < rounds)) && sleep 20 done - rm -f "$TOOL.part" - if [[ $ok != 1 ]]; then + rm -f "$out.part" + return 1 +} + +if [[ ! -x "$TOOL" ]]; then + fetch "$TOOL" 4 "$BASE/appimagetool/releases/download/$APPIMAGETOOL_VERSION/appimagetool-$ARCH.AppImage" \ + "$BASE/appimagetool/releases/download/continuous/appimagetool-$ARCH.AppImage" || { echo "Could not download appimagetool from GitHub. Try again later." >&2 exit 1 - fi + } chmod +x "$TOOL" fi +if [[ ! -s "$RUNTIME" ]]; then + if ! fetch "$RUNTIME" 2 "$BASE/type2-runtime/releases/download/continuous/runtime-$ARCH"; then + echo " using the runtime inside appimagetool instead" + head -c "$("$TOOL" --appimage-offset)" "$TOOL" > "$RUNTIME" + fi +fi + APPDIR=build/AppDir rm -rf "$APPDIR" mkdir -p "$APPDIR/usr/lib" @@ -118,7 +133,8 @@ UPDATE_INFO="${UPDATE_INFO:-gh-releases-zsync|sevagjb|PrintView3D|latest|PrintVi ZSYNC="PrintView3D-$ARCH.AppImage.zsync" rm -f "$ZSYNC" "dist/$ZSYNC" # APPIMAGE_EXTRACT_AND_RUN: works on machines without FUSE (containers, CI) -APPIMAGE_EXTRACT_AND_RUN=1 ARCH="$ARCH" "$TOOL" --no-appstream -u "$UPDATE_INFO" "$APPDIR" "$OUT" +APPIMAGE_EXTRACT_AND_RUN=1 ARCH="$ARCH" "$TOOL" --no-appstream --runtime-file "$RUNTIME" \ + -u "$UPDATE_INFO" "$APPDIR" "$OUT" chmod +x "$OUT" if [[ -f "$ZSYNC" ]]; then mv "$ZSYNC" "dist/$ZSYNC"