Release prep 0.7.0: Linux riscv64 tarball + version bump (#2965)

* Release prep 0.7.0: add Linux riscv64 tar.gz to the release; bump to 0.7.0

- release.yml: new linux-riscv64 job, ported from GridCraft: cross-compiled on ubuntu-24.04
  against ports.ubuntu.com riscv64 libs, tar.gz only, photocraft-cli --version smoke-tested
  under QEMU. The draft-release job now needs it, so SHA256SUMS.txt covers it.
- packaging/linux/package.sh: CROSS_ARCH / CROSS_TARGET / CROSS_COMPILE / EMULATOR support.
- linux_libs: search /usr/lib/riscv64-linux-gnu on riscv64 (was the x86_64 triplet).
- README and docs/releasing.md list the riscv64 tarball.
- Version 0.6.0 -> 0.7.0 (cargo xtask version set), Cargo.lock refreshed; contributors refreshed.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

* canvas: crisp elliptical marquee ants again in an unrotated view

#2732 (a27d7175) built the elliptical marquee's live ants in document space and snapped every
vertex to the half-pixel grid on its own. Near the edge midpoints the nearly flat arcs became
1 px stairs, whose antialiased steps are grey, so the ants no longer contrast on white or black:
drag_preview_canvas's marquee test fails on main (ubuntu and windows). In an axis-aligned view
(rotation a multiple of 90 degrees) draw the ellipse inscribed in the snapped screen box again,
as before #2732; rotated views keep the mapped ellipse.

Co-Authored-By: Claude Opus 5.5 <[email protected]>

---------

Co-authored-by: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Brandon ThomasandClaude Opus 5.5 authored and GitHub committed 2026-10-10 21:36:30 -04:00
1 parent 953390a36e
commit 7926161595
9 files changed
+811 -242

No files matched your search

+71 -1
View File
@@ -372,9 +372,79 @@ 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. tar.gz only; the
# CLI is smoke-tested under QEMU. Same recipe as GridCraft's linux-riscv64 job.
runs-on: ubuntu-24.04
# No `environment: release`: this job reads no secrets, so a branch dry run can run it.
env:
PHOTOCRAFT_VERSION: ${{ needs.version.outputs.version }}
PHOTOCRAFT_BUILD_DATE: ${{ needs.version.outputs.date }}
steps:
- uses: actions/checkout@v4
- name: Check out craft-fonts (embedded fonts)
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
with:
repository: storytold/craft-fonts
ref: ${{ env.CRAFT_FONTS_REF }}
path: craft-fonts
- 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 "$PHOTOCRAFT_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
- name: Build and package (tar.gz)
env:
CRAFT_FONTS_DIR: ${{ github.workspace }}/craft-fonts
CRAFT_FONTS_REQUIRED: "1"
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 tar
- uses: actions/upload-artifact@v4
with:
name: release-linux-riscv64
path: dist/release/*.tar.gz
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:
Generated
+29 -29
View File
@@ -4173,7 +4173,7 @@ dependencies = [
[[package]]
name = "photocraft"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"arboard",
"async-io",
@@ -4214,7 +4214,7 @@ dependencies = [
[[package]]
name = "photocraft-affinity"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"crc32fast",
"flate2",
@@ -4224,7 +4224,7 @@ dependencies = [
[[package]]
name = "photocraft-algo"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-color",
"photocraft-geom",
@@ -4237,7 +4237,7 @@ dependencies = [
[[package]]
name = "photocraft-automation"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"base64",
"cap-std",
@@ -4259,7 +4259,7 @@ dependencies = [
[[package]]
name = "photocraft-cli"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-automation",
"photocraft-codecs",
@@ -4273,7 +4273,7 @@ dependencies = [
[[package]]
name = "photocraft-cms"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"moxcms",
"rayon",
@@ -4281,7 +4281,7 @@ dependencies = [
[[package]]
name = "photocraft-codecs"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"exr",
"flate2",
@@ -4302,7 +4302,7 @@ dependencies = [
[[package]]
name = "photocraft-color"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-cms",
"serde",
@@ -4310,7 +4310,7 @@ dependencies = [
[[package]]
name = "photocraft-compose"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"criterion",
"photocraft-color",
@@ -4325,7 +4325,7 @@ dependencies = [
[[package]]
name = "photocraft-doc"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-color",
"photocraft-geom",
@@ -4336,7 +4336,7 @@ dependencies = [
[[package]]
name = "photocraft-engine"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"blake3",
"exr",
@@ -4369,7 +4369,7 @@ dependencies = [
[[package]]
name = "photocraft-format"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"blake3",
"flate2",
@@ -4388,14 +4388,14 @@ dependencies = [
[[package]]
name = "photocraft-geom"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"serde",
]
[[package]]
name = "photocraft-gpu"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"half",
"log",
@@ -4412,14 +4412,14 @@ dependencies = [
[[package]]
name = "photocraft-heif"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"heic-rs",
]
[[package]]
name = "photocraft-io"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"blake3",
"crc32fast",
@@ -4448,14 +4448,14 @@ dependencies = [
[[package]]
name = "photocraft-ops"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-doc",
]
[[package]]
name = "photocraft-paint"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-color",
"photocraft-geom",
@@ -4466,7 +4466,7 @@ dependencies = [
[[package]]
name = "photocraft-plugins"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-color",
"photocraft-geom",
@@ -4481,7 +4481,7 @@ dependencies = [
[[package]]
name = "photocraft-psd"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"flate2",
"photocraft-psd",
@@ -4492,7 +4492,7 @@ dependencies = [
[[package]]
name = "photocraft-raster"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-color",
"photocraft-geom",
@@ -4502,7 +4502,7 @@ dependencies = [
[[package]]
name = "photocraft-raw"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"flate2",
"image",
@@ -4517,7 +4517,7 @@ dependencies = [
[[package]]
name = "photocraft-tablet"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"block2 0.6.2",
"objc2 0.6.4",
@@ -4529,7 +4529,7 @@ dependencies = [
[[package]]
name = "photocraft-testkit"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"memory-stats",
"photocraft-color",
@@ -4540,7 +4540,7 @@ dependencies = [
[[package]]
name = "photocraft-text"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"flate2",
"parley",
@@ -4554,7 +4554,7 @@ dependencies = [
[[package]]
name = "photocraft-ui-egui"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"base64",
"eframe",
@@ -4591,7 +4591,7 @@ dependencies = [
[[package]]
name = "photocraft-vector"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"photocraft-color",
"photocraft-doc",
@@ -4602,7 +4602,7 @@ dependencies = [
[[package]]
name = "photocraft-web"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"eframe",
"egui",
@@ -7435,7 +7435,7 @@ checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9"
[[package]]
name = "xtask"
version = "0.6.0"
version = "0.7.0"
dependencies = [
"serde",
"serde_json",
+1 -1
View File
@@ -4,7 +4,7 @@ members = ["crates/*", "apps/*", "xtask"]
default-members = ["crates/*", "apps/photocraft", "apps/photocraft-cli", "xtask"]
[workspace.package]
version = "0.6.0"
version = "0.7.0"
edition = "2024"
license = "MIT OR Apache-2.0"
rust-version = "1.95"
+2
View File
@@ -350,6 +350,8 @@ Installers and executables are code-signed.
| Fedora/RHEL/openSUSE | `photocraft-<ver>-linux-x86_64.rpm` | `photocraft-<ver>-linux-aarch64.rpm` | |
| Tarball | `photocraft-<ver>-linux-x86_64.tar.gz` | `photocraft-<ver>-linux-aarch64.tar.gz` | Unpack anywhere |
RISC-V (riscv64): `photocraft-<ver>-linux-riscv64.tar.gz` only, built against Ubuntu 24.04 (needs glibc 2.39+).
### FreeBSD
| Build | File |
+7 -1
View File
@@ -227,7 +227,13 @@ pub fn missing_message(session: DisplaySession, missing: &[AnyOf], distro: Distr
/// Library directories to search: `LD_LIBRARY_PATH`, then the usual system and Flatpak paths.
fn search_dirs(ld_library_path: Option<&str>) -> Vec<PathBuf> {
let mut dirs: Vec<PathBuf> = ld_library_path.unwrap_or("").split(':').filter(|d| !d.is_empty()).map(PathBuf::from).collect();
let triplet = if cfg!(target_arch = "aarch64") { "aarch64-linux-gnu" } else { "x86_64-linux-gnu" };
let triplet = if cfg!(target_arch = "aarch64") {
"aarch64-linux-gnu"
} else if cfg!(target_arch = "riscv64") {
"riscv64-linux-gnu"
} else {
"x86_64-linux-gnu"
};
for d in ["/app/lib", "/usr/local/lib", "/usr/lib64", "/lib64", "/usr/lib", "/lib"] {
dirs.push(PathBuf::from(d));
}
File diff suppressed because it is too large. Load diff
+9
View File
@@ -265,6 +265,15 @@ pub(crate) fn marquee_ants(xf: &ViewXform, tool: Tool, a: [f64; 2], b: [f64; 2])
if tool != Tool::EllipseMarquee {
return vec![at(x0, y0), at(x1, y0), at(x1, y1), at(x0, y1)];
}
// An axis-aligned view (rotation a multiple of 90 degrees) maps the ellipse onto the one
// inscribed in the snapped screen box of two opposite corners. Draw that, unsnapped: snapping
// each vertex on its own turns the nearly flat arcs at the edge midpoints into 1 px stairs,
// whose antialiased steps wash the ants out to grey on white and black.
let quarter = xf.rotation.rem_euclid(90.0);
if quarter < 1e-4 || 90.0 - quarter < 1e-4 {
let r = Rect::from_two_pos(at(x0, y0), at(x1, y1));
return crate::tool_feedback::ellipse_points(r);
}
// As many vertices as the same ellipse would get drawn on screen (`ellipse_points`).
let scr = Rect::from_points(&[xf.to_screen(x0 as f32, y0 as f32), xf.to_screen(x1 as f32, y1 as f32)]);
let n = (((scr.width() + scr.height()) * 0.25) as usize).clamp(16, 256);
+1
View File
@@ -53,6 +53,7 @@ in the dialog.
| Windows 10+ x86 (32-bit) | `photocraft-<v>-windows-x86.msi`, `photocraft-<v>-windows-x86-portable.zip` | `windows-latest` |
| Linux x86_64 | `photocraft-<v>-linux-x86_64.{AppImage,AppImage.zsync,deb,rpm,tar.gz,flatpak}` | `ubuntu-22.04` (Flatpak: `ubuntu-24.04`) |
| Linux aarch64 | `photocraft-<v>-linux-aarch64.{AppImage,AppImage.zsync,deb,rpm,tar.gz,flatpak}` | `ubuntu-22.04-arm` (Flatpak: `ubuntu-24.04-arm`) |
| Linux riscv64 (glibc 2.39+) | `photocraft-<v>-linux-riscv64.tar.gz` | cross-compiled on `ubuntu-24.04` (ports.ubuntu.com riscv64 libs); CLI smoke-tested under QEMU |
| FreeBSD 14 x86_64 | `photocraft-<v>-freebsd-x86_64.tar.gz` | FreeBSD 14.3 VM on `ubuntu-latest` |
| Web | `photocraft-web-<v>.zip` (static site; see [`packaging/web/README.md`](../packaging/web/README.md)) | `ubuntu-latest` |
+20 -7
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# Build and package PhotoCraft for Linux (<arch> is x86_64 or aarch64):
# Build and package PhotoCraft for Linux (<arch> is x86_64, aarch64 or riscv64):
#
# $DIST/photocraft-<version>-linux-<arch>.AppImage any distro with glibc >= the build host's
# $DIST/photocraft-<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, tar.gz only): 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"
@@ -25,13 +29,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 ;;
@@ -42,9 +47,13 @@ BASENAME="photocraft-$VERSION-linux-$ARCH"
echo "==> PhotoCraft $VERSION for Linux $ARCH ($FORMATS)"
if [ "$SKIP_BUILD" = 0 ]; then
(cd "$ROOT" && cargo build --release --locked -p photocraft -p photocraft-cli --features heif)
if [ -n "${CROSS_TARGET:-}" ]; then
(cd "$ROOT" && cargo build --release --locked -p photocraft -p photocraft-cli --features heif --target "$CROSS_TARGET")
else
(cd "$ROOT" && cargo build --release --locked -p photocraft -p photocraft-cli --features heif)
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"
@@ -52,7 +61,7 @@ rm -rf "$WORK"
# ---- stage an FHS tree (shared by every format) -------------------------------------------------
install -Dm755 "$BIN/photocraft" "$STAGE/usr/bin/photocraft"
install -Dm755 "$BIN/photocraft-cli" "$STAGE/usr/bin/photocraft-cli"
strip "$STAGE/usr/bin/photocraft" "$STAGE/usr/bin/photocraft-cli" 2>/dev/null || true
"${CROSS_COMPILE:-}strip" "$STAGE/usr/bin/photocraft" "$STAGE/usr/bin/photocraft-cli" 2>/dev/null || true
install -Dm644 "$HERE/$APP_ID.desktop" "$STAGE/usr/share/applications/$APP_ID.desktop"
install -Dm644 "$HERE/$APP_ID.mime.xml" "$STAGE/usr/share/mime/packages/$APP_ID.xml"
mkdir -p "$STAGE/usr/share/metainfo"
@@ -139,6 +148,10 @@ if has appimage; then
fi
fi
"$STAGE/usr/bin/photocraft-cli" --version
if [ -z "${CROSS_TARGET:-}" ]; then
"$STAGE/usr/bin/photocraft-cli" --version
elif [ -n "${EMULATOR:-}" ]; then
"$EMULATOR" "$STAGE/usr/bin/photocraft-cli" --version
fi
echo "==> done"
ls -lh "$DIST"