diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 97a9528..c84ae8b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -248,6 +248,16 @@ jobs: libxcb-keysyms1 libxcb-shape0 libxcb-image0 libxcb-render-util0 libxcb-randr0 \ libxcb-xinerama0 libxcb-xkb1 libfontconfig1 libdbus-1-3 desktop-file-utils + # 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 + 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 3043d42..5e42adf 100755 --- a/build_linux.sh +++ b/build_linux.sh @@ -72,12 +72,50 @@ fi echo "[5/5] Packing the AppImage ..." ARCH="$(uname -m)" TOOL="build/appimagetool-$ARCH.AppImage" +# 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}" +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 " not available right now: ${url##*/download/} (round $round of $rounds)" + done + ((round < rounds)) && sleep 20 + done + rm -f "$out.part" + return 1 +} + if [[ ! -x "$TOOL" ]]; then - mkdir -p build - curl -fL -o "$TOOL" \ - "https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-$ARCH.AppImage" + 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 + } 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" @@ -95,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"