diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index acba93aa..502c4836 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -470,24 +470,22 @@ jobs: include: - target: x86_64-unknown-linux-gnu arch: x64 - sharun_arch: x86_64 runs-on: ubuntu-24.04 - target: aarch64-unknown-linux-gnu arch: arm64 - sharun_arch: aarch64 runs-on: ubuntu-24.04-arm env: - # Pinned to commit 2affcd6 of pkgforge-dev/Anylinux-AppImages - # (latest commit touching quick-sharun.sh / get-debloated-pkgs.sh) - ANYLINUX_REF: 2affcd69e3b3fccab4507dbdbaed5d1a04bedfa9 - # Pinned appimagetool release; quick-sharun honours APPIMAGETOOL_LINK. - APPIMAGETOOL_VERSION: "0.3.0" - # anylinux.c moved out of Anylinux-AppImages into its own repo on - # 2026-09-10 (Anylinux-sharun commit a84aa4b, "move and build helper - # libraries to this repository"). quick-sharun.sh at the ref above still - # defaults to the old `refs/heads/main` path, which now 404s -- so point - # it at the new home, pinned to a release tag rather than a branch. - ANYLINUX_SHARUN_VERSION: "3.2.1" + # quick-sharun + get-debloated-pkgs come from Anylinux-AppImages, tracking + # main rather than a pinned commit. Upstream moved anylinux.c out to its own + # repo (Anylinux-sharun) on 2026-09-10, and the commit we used to pin here + # still fetched it from the old refs/heads/main path -- which 404s, so the + # script's five silent retries could never succeed ("Failed to download 5 + # times!"). Current quick-sharun does not build the helper libs at all: it + # pulls them prebuilt from an Anylinux-sharun release, and sha256-pins that + # tarball (and appimagetool) inside the script itself, so tracking main keeps + # the script and everything it downloads in step. Set this to a commit SHA if + # a future upstream change ever needs to be held back. + ANYLINUX_REF: refs/heads/main # See build-windows: keep APP_VERSION consistent across Test and Build. RELEASE_VERSION: ${{ needs.generate-version.outputs.version }} steps: @@ -594,17 +592,15 @@ jobs: export OUTPATH="$PWD/dist" export OUTNAME="$OUT" export VERSION - # Pin appimagetool (quick-sharun downloads via this URL). - export APPIMAGETOOL_LINK="https://github.com/pkgforge-dev/appimagetool/releases/download/${APPIMAGETOOL_VERSION}/appimagetool-${{ matrix.sharun_arch }}-linux" - # anylinux.c now lives in Anylinux-sharun (see the env note). The - # script's default still points at the old repo's main branch, which - # 404s -- and its five retries just repeat a request that cannot - # succeed ("Failed to download 5 times!"), which reads like a network - # blip rather than a moved file. - export ANYLINUX_LIB_SOURCE="https://raw.githubusercontent.com/pkgforge-dev/Anylinux-sharun/${ANYLINUX_SHARUN_VERSION}/lib/anylinux.c" - curl -fsI "$ANYLINUX_LIB_SOURCE" >/dev/null \ - || { echo "::error::anylinux.c unreachable at Anylinux-sharun ${ANYLINUX_SHARUN_VERSION}; upstream may have moved it again"; exit 1; } - # GITHUB_REPOSITORY is set by Actions; appimagetool auto-emits zsync. + # appimagetool is deliberately NOT overridden here: quick-sharun + # sha256-checks it against the version it ships with, so pointing + # APPIMAGETOOL_LINK elsewhere fails that check. Same for the sharun + # helper-libs tarball (which is where anylinux.so now comes from). + # OUTNAME/VERSION/OUTPATH are still read by appimagetool, so the + # artifact name below is unchanged. + # Explicit UPINFO: the guessed default matches *x86_64.AppImage.zsync, + # never our -x64- names. Setting it also emits the .zsync. + export UPINFO="gh-releases-zsync|${GITHUB_REPOSITORY%/*}|${GITHUB_REPOSITORY#*/}|latest|Rusty-Backup-linux-${{ matrix.arch }}-*.AppImage.zsync" mkdir -p "$OUTPATH" ./quick-sharun /usr/bin/rusty-backup @@ -763,8 +759,9 @@ jobs: - name: Build Debian package run: | - cargo deb --target ${{ matrix.target }} --no-build - mv target/${{ matrix.target }}/debian/*.deb Rusty-Backup-linux-${{ matrix.arch }}-${{ needs.generate-version.outputs.version }}.deb + # -o: cargo-deb only mirrors into target//debian as a deprecated back-compat copy. + cargo deb --target ${{ matrix.target }} --no-build \ + -o Rusty-Backup-linux-${{ matrix.arch }}-${{ needs.generate-version.outputs.version }}.deb - name: Build RPM package run: | @@ -1229,10 +1226,11 @@ jobs: # cross-compiled on x64. There is no GitHub-hosted riscv64 runner, so unlike # the x64/arm64 AppImage jobs this can't build/package natively: we cross-link # the default feature set (GUI + CHD + optical) against a riscv64 GTK/GL sysroot - # pulled in via dpkg multiarch (ubuntu-ports), then ship a plain dynamically- - # linked tarball — NOT a self-contained AppImage; it uses the user's system - # GTK3 at runtime. libchdman-rs 0.288.10 publishes the riscv64gc prebuilt that - # makes the CHD core link. continue-on-error: best-effort, can't block release. + # pulled in via dpkg multiarch (ubuntu-ports), then ship a .deb, .rpm and plain + # tarball, all dynamically linked — NOT a self-contained AppImage; they use the + # user's system GTK3 at runtime. libchdman-rs 0.288.10 publishes the riscv64gc + # prebuilt that makes the CHD core link. continue-on-error: best-effort, can't + # block release. build-gui-linux-riscv64: name: Build Linux RISC-V 64 GUI (rusty-backup) # Skipped only when a manual run unticks "desktop"; every push builds it. @@ -1401,6 +1399,82 @@ jobs: name: Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }} path: Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}.tar.gz + - name: Install cargo packaging tools + # Host tools, so drop the job's riscv64 pkg-config env or any -sys crate + # they build would link against the riscv64 sysroot. + run: | + sudo apt-get install -y dpkg-dev rpm + for crate in cargo-deb cargo-generate-rpm; do + for attempt in 1 2 3; do + if env -u PKG_CONFIG_LIBDIR -u PKG_CONFIG_SYSROOT_DIR -u PKG_CONFIG_ALLOW_CROSS \ + cargo install --locked "$crate"; then + continue 2 + fi + echo "Install of $crate failed (attempt $attempt/3)" + sleep 15 + done + echo "::error::failed to install $crate after 3 attempts" + exit 1 + done + + # Same Cargo.toml metadata as the x64/arm64 packages; --target makes both + # tools read target/riscv64gc-unknown-linux-gnu/release/rusty-backup. + - name: Build Debian package + run: | + set -euo pipefail + DEB="Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}.deb" + # --no-strip: already stripped with the cross strip above; the host + # `strip` can't read a riscv64 ELF. + # -o: cargo-deb only mirrors into target//debian as a deprecated back-compat copy. + cargo deb --target riscv64gc-unknown-linux-gnu --no-build --no-strip -o "$DEB" + dpkg-deb -f "$DEB" Package Version Architecture Depends + # $auto runs dpkg-shlibdeps against the :riscv64 multiarch packages. + # When it fails cargo-deb only warns and ships a .deb whose Depends is + # just the static list, so check the resolved deps actually landed. + [ "$(dpkg-deb -f "$DEB" Architecture)" = riscv64 ] \ + || { echo "::error::$DEB is not Architecture: riscv64"; exit 1; } + DEPENDS=$(dpkg-deb -f "$DEB" Depends) + case "$DEPENDS" in + *libc6*) ;; + *) echo "::error::\$auto deps did not resolve (no libc6 in Depends: $DEPENDS)"; exit 1 ;; + esac + case "$DEPENDS" in + *-cross*) echo "::error::Depends names a host cross-toolchain package: $DEPENDS"; exit 1 ;; + esac + + - name: Build RPM package + run: | + set -euo pipefail + ELF=target/riscv64gc-unknown-linux-gnu/release/rusty-backup + RPM="Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}.rpm" + # Auto-requires runs the host ldd, which can't load a riscv64 ELF, so + # emit the same soname()(64bit) requires from the cross objdump instead. + # --set-metadata replaces the whole requires table: restate gtk3/openssl. + REQS=$(riscv64-linux-gnu-objdump -p "$ELF" \ + | awk '$1 == "NEEDED" { printf "\"%s()(64bit)\" = \"*\", ", $2 }') + [ -n "$REQS" ] || { echo "::error::no NEEDED entries in $ELF"; exit 1; } + # The target triple's first segment is riscv64gc; RPM distros say riscv64. + cargo generate-rpm --target riscv64gc-unknown-linux-gnu --arch riscv64 \ + --auto-req disabled \ + --set-metadata "requires = { ${REQS}gtk3 = \"*\", openssl = \"*\" }" + mv target/riscv64gc-unknown-linux-gnu/generate-rpm/*.rpm "$RPM" + rpm -qp --qf '%{NAME} %{VERSION} %{ARCH}\n' "$RPM" + rpm -qp --requires "$RPM" + [ "$(rpm -qp --qf '%{ARCH}' "$RPM")" = riscv64 ] \ + || { echo "::error::$RPM is not arch riscv64"; exit 1; } + + - name: Upload Debian package + uses: actions/upload-artifact@v7 + with: + name: Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}-deb + path: Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}.deb + + - name: Upload RPM package + uses: actions/upload-artifact@v7 + with: + name: Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}-rpm + path: Rusty-Backup-linux-riscv64-${{ needs.generate-version.outputs.version }}.rpm + # Turn the `appliance` choice input into a JSON arch list for the matrix # below. A manual dispatch honours none / i586 / i686 / both. A push to # main/master builds both arches automatically (the full Buildroot build is @@ -2221,6 +2295,7 @@ jobs: "Rusty-Backup-linux-arm64-${VER}.AppImage" "Rusty-Backup-linux-arm64-${VER}.deb" \ "Rusty-Backup-linux-arm64-${VER}.rpm" "Rusty-Backup-linux-arm64-${VER}.pkg.tar.zst" \ "Rusty-Backup-windows-arm64-${VER}.zip" "Rusty-Backup-linux-riscv64-${VER}.tar.gz" \ + "Rusty-Backup-linux-riscv64-${VER}.deb" "Rusty-Backup-linux-riscv64-${VER}.rpm" \ "rb-cli-windows-x64-${VER}.zip" "rb-cli-windows-x86-${VER}.zip" \ "rb-cli-macos-arm64-${VER}.zip" "rb-cli-macos-x64-${VER}.zip" \ "rb-cli-linux-x64-${VER}.tar.gz" "rb-cli-linux-arm64-${VER}.tar.gz" \ @@ -2254,10 +2329,10 @@ jobs: | **macOS 10.13+** | Intel (x64) | [.dmg](${BASE}/Rusty-Backup-macos-x64-${VER}.dmg) | [rb-cli](${BASE}/rb-cli-macos-x64-${VER}.zip) | | **Linux** (glibc >= 2.39) | x64 | [AppImage](${BASE}/Rusty-Backup-linux-x64-${VER}.AppImage) · [deb](${BASE}/Rusty-Backup-linux-x64-${VER}.deb) · [rpm](${BASE}/Rusty-Backup-linux-x64-${VER}.rpm) · [pkg](${BASE}/Rusty-Backup-linux-x64-${VER}.pkg.tar.zst) | [rb-cli](${BASE}/rb-cli-linux-x64-${VER}.tar.gz) | | **Linux** (glibc >= 2.39) | arm64 | [AppImage](${BASE}/Rusty-Backup-linux-arm64-${VER}.AppImage) · [deb](${BASE}/Rusty-Backup-linux-arm64-${VER}.deb) · [rpm](${BASE}/Rusty-Backup-linux-arm64-${VER}.rpm) · [pkg](${BASE}/Rusty-Backup-linux-arm64-${VER}.pkg.tar.zst) | [rb-cli](${BASE}/rb-cli-linux-arm64-${VER}.tar.gz) | - | **Linux** (glibc >= 2.39) | RISC-V 64-bit (\`riscv64gc\`) | [tar.gz](${BASE}/Rusty-Backup-linux-riscv64-${VER}.tar.gz) | [rb-cli](${BASE}/rb-cli-linux-riscv64-${VER}.tar.gz) | + | **Linux** (glibc >= 2.39) | RISC-V 64-bit (\`riscv64gc\`) | [deb](${BASE}/Rusty-Backup-linux-riscv64-${VER}.deb) · [rpm](${BASE}/Rusty-Backup-linux-riscv64-${VER}.rpm) · [tar.gz](${BASE}/Rusty-Backup-linux-riscv64-${VER}.tar.gz) | [rb-cli](${BASE}/rb-cli-linux-riscv64-${VER}.tar.gz) | | **MiSTer FPGA** (Cortex-A9, glibc 2.31) | armv7 hardfloat | _(GUI not built for this target)_ | [rb-cli-mini](${BASE}/rb-cli-mini-armv7-linux-${VER}.tar.gz) | - **Windows:** x86 = 32-bit (Windows 10, the last Windows with 32-bit support). · **macOS:** requires 10.13 High Sierra or later. · **Linux:** deb = Debian/Ubuntu, rpm = Fedora/RHEL/openSUSE, pkg = Arch/Manjaro; the packages and \`rb-cli\` are built against **glibc 2.39** (Ubuntu 24.04), while the **AppImage** is self-contained and runs on most distributions regardless of glibc. · **Windows ARM64 / RISC-V 64:** cross-compiled, build-only legs — the Windows ARM64 app is a portable zip and the RISC-V 64 app is a plain dynamically-linked tarball that uses your system GTK3 (not a self-contained AppImage like x64/arm64). · **MiSTer FPGA:** \`rb-cli-mini\` is a slim \`rb-cli\` cross-compiled for the MiSTer's armv7 hardfloat Intel Cyclone V SoC against Ubuntu 20.04 glibc 2.31 — same baseline as the MiSTer Buildroot rootfs and the upstream \`libchdman-rs\` armv7 prebuilt. The GUI is off; CHD, optical and the full-screen \`rb-cli tui\` terminal UI are in. Drop it onto the SD at \`/media/fat/Scripts/rb-cli\`. · Every **rb-cli** download contains a single \`rb-cli\` executable (\`rb-cli.exe\` on Windows). + **Windows:** x86 = 32-bit (Windows 10, the last Windows with 32-bit support). · **macOS:** requires 10.13 High Sierra or later. · **Linux:** deb = Debian/Ubuntu, rpm = Fedora/RHEL/openSUSE, pkg = Arch/Manjaro; the packages and \`rb-cli\` are built against **glibc 2.39** (Ubuntu 24.04), while the **AppImage** is self-contained and runs on most distributions regardless of glibc. · **Windows ARM64 / RISC-V 64:** cross-compiled, build-only legs — the Windows ARM64 app is a portable zip and the RISC-V 64 app ships as a deb, rpm or plain tarball, all dynamically linked against your system GTK3 (no self-contained AppImage like x64/arm64). · **MiSTer FPGA:** \`rb-cli-mini\` is a slim \`rb-cli\` cross-compiled for the MiSTer's armv7 hardfloat Intel Cyclone V SoC against Ubuntu 20.04 glibc 2.31 — same baseline as the MiSTer Buildroot rootfs and the upstream \`libchdman-rs\` armv7 prebuilt. The GUI is off; CHD, optical and the full-screen \`rb-cli tui\` terminal UI are in. Drop it onto the SD at \`/media/fat/Scripts/rb-cli\`. · Every **rb-cli** download contains a single \`rb-cli\` executable (\`rb-cli.exe\` on Windows). ### Command-line (\`rb-cli\`) for other CPU architectures