Add a Linux riscv64 release build (deb, rpm, tar.gz) (#102)
* Add Linux riscv64 release build and switch runners to Ubuntu 26.04 - release.yml: new linux-riscv64 job cross-compiled on ubuntu-26.04 against ports.ubuntu.com riscv64 libs, tar.gz only, artcraft-launcher --version smoke-tested under QEMU. Updated flatpak runner matrix to ubuntu-26.04. Draft-release job now requires linux-riscv64 and checks the tarball. - packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE / EMULATOR support. - platform.rs: add Arch::Riscv64 variant, map linux-riscv64 token, and prioritize tarball format for riscv64 on Linux. - web.rs: detect riscv64 architecture in visitor user agent. - README and AGENTS.md: document the riscv64 tarball. * linux: build deb and rpm packages for riscv64 * ci: configure actionlint to recognize ubuntu-26.04 runner labels * Keep riscv64 and Flatpak release jobs on Ubuntu 24.04 24.04 is what PhotoCraft's linux-riscv64 job uses, so the riscv64 binaries need glibc 2.39 (as the README says) rather than 26.04's newer glibc, and the release pipeline keeps runner images it has already proven on. Drop the actionlint label config that 26.04 needed, revert the default_kinds and download_kinds matches to match on the OS alone, simplify the riscv UA check, and rustfmt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Brandon Thomas <echelon@gmail.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
633f09c7cc
commit
e8614afa3f
|
|
@ -335,9 +335,75 @@ jobs:
|
|||
path: dist/release/*
|
||||
if-no-files-found: error
|
||||
|
||||
linux-riscv64:
|
||||
name: Linux riscv64
|
||||
needs: version
|
||||
# Cross-compiled on x86_64 (no hosted RISC-V runners) against the runner's own Ubuntu release
|
||||
# from ports.ubuntu.com, so the binaries need that release's glibc (24.04: 2.39). 22.04's
|
||||
# riscv64 ports lag its amd64 updates, which breaks the multiarch install. deb, rpm, and
|
||||
# tar.gz; artcraft-launcher --version is smoke-tested under QEMU. Follows PhotoCraft's job.
|
||||
runs-on: ubuntu-24.04
|
||||
# No `environment: release`: this job reads no secrets, so a branch dry run can run it.
|
||||
env:
|
||||
ARTCRAFT_LAUNCHER_VERSION: ${{ needs.version.outputs.version }}
|
||||
ARTCRAFT_LAUNCHER_BUILD_DATE: ${{ needs.version.outputs.date }}
|
||||
NFPM_VERSION: 2.47.0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
with:
|
||||
targets: riscv64gc-unknown-linux-gnu
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
key: release-linux-riscv64
|
||||
- name: Apply version override
|
||||
if: inputs.version != ''
|
||||
run: cargo xtask version set "$ARTCRAFT_LAUNCHER_VERSION"
|
||||
- name: Install cross-compilation dependencies
|
||||
run: |
|
||||
. /etc/os-release
|
||||
sudo dpkg --add-architecture riscv64
|
||||
# Pin the existing (archive.ubuntu.com) sources to amd64; riscv64 comes from ports.
|
||||
if [ -f /etc/apt/sources.list.d/ubuntu.sources ]; then
|
||||
sudo sed -i '/^Types: deb/a Architectures: amd64' /etc/apt/sources.list.d/ubuntu.sources
|
||||
fi
|
||||
if [ -f /etc/apt/sources.list ]; then
|
||||
sudo sed -i 's/^deb /deb [arch=amd64] /g' /etc/apt/sources.list
|
||||
sudo sed -i 's/^deb-src /deb-src [arch=amd64] /g' /etc/apt/sources.list
|
||||
fi
|
||||
for suite in "$VERSION_CODENAME" "$VERSION_CODENAME-updates" "$VERSION_CODENAME-security"; do
|
||||
echo "deb [arch=riscv64] http://ports.ubuntu.com/ubuntu-ports $suite main universe restricted multiverse"
|
||||
done | sudo tee /etc/apt/sources.list.d/riscv64.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends \
|
||||
gcc-riscv64-linux-gnu binutils-riscv64-linux-gnu libc6-dev-riscv64-cross libc6-dev:riscv64 qemu-user \
|
||||
libxkbcommon-dev:riscv64 libwayland-dev:riscv64 libx11-dev:riscv64 libxrandr-dev:riscv64 \
|
||||
libxi-dev:riscv64 libgl1-mesa-dev:riscv64 \
|
||||
desktop-file-utils appstream
|
||||
curl -fsSL -o "$RUNNER_TEMP/nfpm.deb" \
|
||||
"https://github.com/goreleaser/nfpm/releases/download/v${NFPM_VERSION}/nfpm_${NFPM_VERSION}_amd64.deb"
|
||||
sudo dpkg -i "$RUNNER_TEMP/nfpm.deb"
|
||||
- name: Build and package (deb, rpm, tar.gz)
|
||||
env:
|
||||
CARGO_TARGET_RISCV64GC_UNKNOWN_LINUX_GNU_LINKER: riscv64-linux-gnu-gcc
|
||||
PKG_CONFIG_SYSROOT_DIR: /
|
||||
PKG_CONFIG_PATH: /usr/lib/riscv64-linux-gnu/pkgconfig:/usr/share/pkgconfig
|
||||
PKG_CONFIG_ALLOW_CROSS: "1"
|
||||
CROSS_ARCH: riscv64
|
||||
CROSS_TARGET: riscv64gc-unknown-linux-gnu
|
||||
CROSS_COMPILE: riscv64-linux-gnu-
|
||||
EMULATOR: qemu-riscv64
|
||||
QEMU_LD_PREFIX: /usr/riscv64-linux-gnu
|
||||
run: packaging/linux/package.sh --formats "deb rpm tar"
|
||||
- uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: release-linux-riscv64
|
||||
path: dist/release/*
|
||||
if-no-files-found: error
|
||||
|
||||
release:
|
||||
name: Draft GitHub Release
|
||||
needs: [version, macos, windows, linux, flatpak, freebsd, web]
|
||||
needs: [version, macos, windows, linux, linux-riscv64, flatpak, freebsd, web]
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
permissions:
|
||||
|
|
@ -364,8 +430,13 @@ jobs:
|
|||
for a in x64 x86 arm64; do
|
||||
expected+=("artcraft-launcher-$VERSION-windows-$a.msi" "artcraft-launcher-$VERSION-windows-$a-portable.zip")
|
||||
done
|
||||
for a in x86_64 aarch64 riscv64; do
|
||||
for ext in deb rpm tar.gz; do
|
||||
expected+=("artcraft-launcher-$VERSION-linux-$a.$ext")
|
||||
done
|
||||
done
|
||||
for a in x86_64 aarch64; do
|
||||
for ext in AppImage AppImage.zsync deb rpm tar.gz flatpak; do
|
||||
for ext in AppImage AppImage.zsync flatpak; do
|
||||
expected+=("artcraft-launcher-$VERSION-linux-$a.$ext")
|
||||
done
|
||||
done
|
||||
|
|
|
|||
|
|
@ -119,7 +119,7 @@ Release assets (keep these names exact; the launcher's own self-update and the R
|
|||
|---|---|
|
||||
| Windows | `artcraft-launcher-<ver>-windows-{x64,x86,arm64}.msi`, `…-windows-{x64,x86,arm64}-portable.zip` |
|
||||
| macOS | `artcraft-launcher-<ver>-macos-universal.dmg` |
|
||||
| Linux | `artcraft-launcher-<ver>-linux-{x86_64,aarch64}.{AppImage,AppImage.zsync,deb,rpm,tar.gz,flatpak}` |
|
||||
| Linux | `artcraft-launcher-<ver>-linux-{x86_64,aarch64}.{AppImage,AppImage.zsync,deb,rpm,tar.gz,flatpak}`, `artcraft-launcher-<ver>-linux-riscv64.{deb,rpm,tar.gz}` |
|
||||
| FreeBSD | `artcraft-launcher-<ver>-freebsd-x86_64.tar.gz` |
|
||||
| Web | `artcraft-launcher-web-<ver>.zip` |
|
||||
|
||||
|
|
|
|||
|
|
@ -145,6 +145,8 @@ Download the build for your computer from the [latest release](https://github.co
|
|||
| `artcraft-launcher-<ver>-linux-{x86_64,aarch64}.flatpak` | Flatpak bundle: `flatpak install --user artcraft-launcher-…flatpak`. Inside the sandbox the launcher can download apps but has limited power to install them on the host; prefer the AppImage, .deb or .rpm |
|
||||
| `artcraft-launcher-<ver>-linux-{x86_64,aarch64}.tar.gz` | Plain tree (`bin/`, `share/`) for everyone else and for scripts |
|
||||
|
||||
RISC-V (riscv64): `artcraft-launcher-<ver>-linux-riscv64.{deb,rpm,tar.gz}`, built against Ubuntu 24.04 (needs glibc 2.39+).
|
||||
|
||||
The tray icon uses the StatusNotifierItem standard: KDE, Xfce, Cinnamon and most other desktops show it; on GNOME install the AppIndicator extension.
|
||||
|
||||
**FreeBSD** (14, x86_64)
|
||||
|
|
|
|||
|
|
@ -212,7 +212,13 @@ fn visitor_platform() -> Option<Platform> {
|
|||
} else {
|
||||
return None;
|
||||
};
|
||||
let arch = if ua.contains("aarch64") || ua.contains("arm64") || ua.contains("armv8") { Arch::Arm64 } else { Arch::X64 };
|
||||
let arch = if ua.contains("aarch64") || ua.contains("arm64") || ua.contains("armv8") {
|
||||
Arch::Arm64
|
||||
} else if ua.contains("riscv") {
|
||||
Arch::Riscv64
|
||||
} else {
|
||||
Arch::X64
|
||||
};
|
||||
Some(Platform { os, arch })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ pub enum Arch {
|
|||
X64,
|
||||
X86,
|
||||
Arm64,
|
||||
Riscv64,
|
||||
}
|
||||
|
||||
impl Arch {
|
||||
|
|
@ -42,6 +43,7 @@ impl Arch {
|
|||
Self::X64 => "x64",
|
||||
Self::X86 => "x86",
|
||||
Self::Arm64 => "ARM64",
|
||||
Self::Riscv64 => "RISC-V",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -118,6 +120,8 @@ impl Platform {
|
|||
Arch::X86
|
||||
} else if cfg!(target_arch = "aarch64") {
|
||||
Arch::Arm64
|
||||
} else if cfg!(target_arch = "riscv64") {
|
||||
Arch::Riscv64
|
||||
} else {
|
||||
return None;
|
||||
};
|
||||
|
|
@ -138,9 +142,11 @@ impl Platform {
|
|||
(Os::Windows, Arch::X64) => &["windows-x64", "windows-x86"],
|
||||
(Os::Windows, Arch::X86) => &["windows-x86"],
|
||||
(Os::Windows, Arch::Arm64) => &["windows-arm64", "windows-x64", "windows-x86"],
|
||||
(Os::Windows, _) => &[],
|
||||
(Os::MacOs, _) => &["macos-universal", "macos-aarch64", "macos-arm64", "macos-x86_64"],
|
||||
(Os::Linux, Arch::X64) => &["linux-x86_64"],
|
||||
(Os::Linux, Arch::Arm64) => &["linux-aarch64"],
|
||||
(Os::Linux, Arch::Riscv64) => &["linux-riscv64"],
|
||||
(Os::Linux, Arch::X86) => &[],
|
||||
(Os::FreeBsd, Arch::X64) => &["freebsd-x86_64"],
|
||||
(Os::FreeBsd, _) => &[],
|
||||
|
|
@ -234,6 +240,7 @@ mod tests {
|
|||
"photocraft-0.5.0-linux-aarch64.AppImage",
|
||||
"photocraft-0.5.0-linux-aarch64.AppImage.zsync",
|
||||
"photocraft-0.5.0-linux-aarch64.deb",
|
||||
"photocraft-0.5.0-linux-riscv64.tar.gz",
|
||||
"photocraft-0.5.0-linux-x86_64.AppImage",
|
||||
"photocraft-0.5.0-linux-x86_64.tar.gz",
|
||||
"photocraft-0.5.0-macos-universal.dmg",
|
||||
|
|
@ -268,6 +275,7 @@ mod tests {
|
|||
assert_eq!(pick(Os::Windows, Arch::Arm64, &[PackageKind::Msi]).as_deref(), Some("photocraft-0.5.0-windows-x64.msi"));
|
||||
assert_eq!(pick(Os::Linux, Arch::Arm64, &[PackageKind::AppImage]).as_deref(), Some("photocraft-0.5.0-linux-aarch64.AppImage"));
|
||||
assert_eq!(pick(Os::Linux, Arch::Arm64, &[PackageKind::TarGz]), None);
|
||||
assert_eq!(pick(Os::Linux, Arch::Riscv64, &[PackageKind::TarGz]).as_deref(), Some("photocraft-0.5.0-linux-riscv64.tar.gz"));
|
||||
assert_eq!(pick(Os::FreeBsd, Arch::X64, &[PackageKind::TarGz]).as_deref(), Some("photocraft-0.5.0-freebsd-x86_64.tar.gz"));
|
||||
// Preference order across kinds.
|
||||
assert_eq!(
|
||||
|
|
@ -275,5 +283,21 @@ mod tests {
|
|||
Some("photocraft-0.5.0-windows-x64-portable.zip")
|
||||
);
|
||||
assert_eq!(pick(Os::Windows, Arch::X86, &[PackageKind::PortableZip, PackageKind::Msi]).as_deref(), Some("photocraft-0.5.0-windows-x86.msi"));
|
||||
|
||||
let p_riscv = Platform { os: Os::Linux, arch: Arch::Riscv64 };
|
||||
assert_eq!(
|
||||
pick_asset(&r, &["photocraft"], p_riscv, p_riscv.default_kinds()).map(|(a, _)| a.name.clone()).as_deref(),
|
||||
Some("photocraft-0.5.0-linux-riscv64.tar.gz")
|
||||
);
|
||||
assert_eq!(
|
||||
pick_asset(&r, &["photocraft"], p_riscv, p_riscv.download_kinds()).map(|(a, _)| a.name.clone()).as_deref(),
|
||||
Some("photocraft-0.5.0-linux-riscv64.tar.gz")
|
||||
);
|
||||
let r_riscv_deb =
|
||||
release(&["photocraft-0.5.0-linux-riscv64.tar.gz", "photocraft-0.5.0-linux-riscv64.deb", "photocraft-0.5.0-linux-riscv64.rpm"]);
|
||||
assert_eq!(
|
||||
pick_asset(&r_riscv_deb, &["photocraft"], p_riscv, p_riscv.download_kinds()).map(|(a, _)| a.name.clone()).as_deref(),
|
||||
Some("photocraft-0.5.0-linux-riscv64.deb")
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1080,7 +1080,8 @@ mod tests {
|
|||
/// installs is there.
|
||||
fn release(version: &str) -> Release {
|
||||
let suffixes = ["-portable.zip", ".tar.gz", ".msi", ".dmg", ".AppImage", ".deb", ".rpm", ".flatpak"];
|
||||
let tokens = ["windows-x64", "windows-x86", "windows-arm64", "macos-universal", "linux-x86_64", "linux-aarch64", "freebsd-x86_64"];
|
||||
let tokens =
|
||||
["windows-x64", "windows-x86", "windows-arm64", "macos-universal", "linux-x86_64", "linux-aarch64", "linux-riscv64", "freebsd-x86_64"];
|
||||
let assets = tokens
|
||||
.iter()
|
||||
.flat_map(|t| suffixes.iter().map(move |s| format!("{APP}-{version}-{t}{s}")))
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/env bash
|
||||
# Build and package ArtCraft Launcher for Linux (<arch> is x86_64 or aarch64):
|
||||
# Build and package ArtCraft Launcher for Linux (<arch> is x86_64, aarch64 or riscv64):
|
||||
#
|
||||
# $DIST/artcraft-launcher-<version>-linux-<arch>.AppImage any distro with glibc >= the build host's
|
||||
# $DIST/artcraft-launcher-<version>-linux-<arch>.AppImage.zsync delta updates (needs zsyncmake)
|
||||
|
|
@ -13,6 +13,10 @@
|
|||
# (downloaded into $CARGO_TARGET_DIR if missing). Build on an old distro (CI: Ubuntu 22.04,
|
||||
# glibc 2.35) so the binaries run on newer ones. Optional: desktop-file-validate, appstreamcli,
|
||||
# zsyncmake (the zsync package) for the AppImage's .zsync.
|
||||
#
|
||||
# Cross builds (CI: riscv64, deb/rpm/tar.gz): set CROSS_ARCH (riscv64), CROSS_TARGET (the Rust
|
||||
# triple), CROSS_COMPILE (binutils prefix, for strip) and optionally EMULATOR (e.g. qemu-riscv64)
|
||||
# to smoke-test the CLI.
|
||||
set -euo pipefail
|
||||
# shellcheck source=../env.sh
|
||||
. "$(dirname "${BASH_SOURCE[0]}")/../env.sh"
|
||||
|
|
@ -26,13 +30,14 @@ while [ $# -gt 0 ]; do
|
|||
case "$1" in
|
||||
--skip-build) SKIP_BUILD=1; shift ;;
|
||||
--formats) FORMATS="$2"; shift 2 ;;
|
||||
-h | --help) sed -n '2,15p' "$0"; exit 0 ;;
|
||||
-h | --help) sed -n '2,19p' "$0"; exit 0 ;;
|
||||
*) echo "unknown argument: $1" >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
ARCH="$(uname -m)"
|
||||
ARCH="${CROSS_ARCH:-$(uname -m)}"
|
||||
case "$ARCH" in
|
||||
riscv64) DEB_ARCH=riscv64 ;;
|
||||
x86_64) DEB_ARCH=amd64 ;;
|
||||
aarch64 | arm64) ARCH=aarch64; DEB_ARCH=arm64 ;;
|
||||
*) echo "unsupported architecture $ARCH" >&2; exit 2 ;;
|
||||
|
|
@ -43,16 +48,20 @@ BASENAME="$PKG-$VERSION-linux-$ARCH"
|
|||
echo "==> ArtCraft Launcher $VERSION for Linux $ARCH ($FORMATS)"
|
||||
|
||||
if [ "$SKIP_BUILD" = 0 ]; then
|
||||
(cd "$ROOT" && cargo build --release --locked -p "$PKG")
|
||||
if [ -n "${CROSS_TARGET:-}" ]; then
|
||||
(cd "$ROOT" && cargo build --release --locked -p "$PKG" --target "$CROSS_TARGET")
|
||||
else
|
||||
(cd "$ROOT" && cargo build --release --locked -p "$PKG")
|
||||
fi
|
||||
fi
|
||||
BIN="$CARGO_TARGET_DIR/release"
|
||||
BIN="$CARGO_TARGET_DIR/${CROSS_TARGET:+$CROSS_TARGET/}release"
|
||||
WORK="$CARGO_TARGET_DIR/linux-package"
|
||||
STAGE="$WORK/root"
|
||||
rm -rf "$WORK"
|
||||
|
||||
# ---- stage an FHS tree (shared by every format) -------------------------------------------------
|
||||
install -Dm755 "$BIN/$PKG" "$STAGE/usr/bin/$PKG"
|
||||
strip "$STAGE/usr/bin/$PKG" 2>/dev/null || true
|
||||
"${CROSS_COMPILE:-}strip" "$STAGE/usr/bin/$PKG" 2>/dev/null || true
|
||||
install -Dm644 "$HERE/$APP_ID.desktop" "$STAGE/usr/share/applications/$APP_ID.desktop"
|
||||
mkdir -p "$STAGE/usr/share/metainfo"
|
||||
sed -e "s/@VERSION@/$VERSION/g" -e "s/@DATE@/$ARTCRAFT_LAUNCHER_BUILD_DATE/g" \
|
||||
|
|
@ -139,5 +148,10 @@ if has appimage; then
|
|||
fi
|
||||
fi
|
||||
|
||||
if [ -z "${CROSS_TARGET:-}" ]; then
|
||||
"$STAGE/usr/bin/$PKG" --version
|
||||
elif [ -n "${EMULATOR:-}" ]; then
|
||||
"$EMULATOR" "$STAGE/usr/bin/$PKG" --version
|
||||
fi
|
||||
echo "==> done"
|
||||
ls -lh "$DIST"
|
||||
|
|
|
|||
Loading…
Reference in New Issue