Files
Jamie Pine 61dea60558 CI green on sources: runner toolchain, clippy, typecheck, tests compile (#3102)
* ci: install rustfmt and clippy components on every runner

Self-hosted runners have rustc preinstalled, so setup-rust skipped the
dtolnay/rust-toolchain step that added the components and the Rust
Formatting job died with 'cargo-fmt is not installed'. Add the components
to rust-toolchain.toml and run rustup component add unconditionally.

* setup: install FFmpeg development libraries on Linux and macOS

crates/ffmpeg is a default workspace member that links libav* through
ffmpeg-sys-next, so a fresh machine fails the first cargo build with
'libavutil.pc not found'. Install the libav dev packages and pkg-config
from scripts/setup.sh for every supported package manager, warn from
xtask setup when pkg-config cannot find them, and document the requirement
in the README build section.

* test: call the trash directly in delete_strategy_test

bcc7337 gave LocalDeleteStrategy::move_to_trash a JobContext parameter so
it can record where the item went; the integration test still passed one
argument and stopped every cargo test target from compiling. The two trash
cases now call ops::files::trash::trash with the same arguments the
strategy forwards, which is what they were asserting on.

* interface: clear the 30 Tauri typecheck errors

Remove the 23 unused imports and locals, apply the rename rules' serde
defaults (regex and whole_name false, start and step 1) where the modal
renders optional fields, drop the size prop ToggleGroup never accepted,
and type SourceCard on ts-client's SourceInfo so a filesystem source with
no adapter renders its data type instead. Register the /redundancy/duplicates
route the dashboard already navigates to, which is what the DuplicatesView
import was for.

* clippy: make cargo clippy --workspace -D warnings pass on Linux

sd-store names its sqlx row tuples with type aliases. sd-ffmpeg converts
with try_from and f32::from where the cast was lossless, takes raw
borrows for FFI out-pointers, resamples from an integer position, and
allows the pointer-alignment and s32-to-f32 precision casts with the
reason. sd-mobile-core sets DaemonRequest.device (None, local execution)
on the two envelopes it builds. file-opening-macos and file-opening-windows
pull their platform bindings only on that target and gate their sources,
matching sd-desktop-macos. The Tauri build script drops externalBin from
the config when no daemon sidecar exists, so a check or clippy run that
never built the daemon still passes, and the desktop binary's macOS-only
commands return on other hosts without unreachable code. Workspace
rust-version moves to 1.95, the floor gpui already imposes, so the MSRV
lint stops flagging APIs the pinned 1.97.1 toolchain uses.

* docs: make the stale doctests compile

sd-media-metadata examples still imported from the old image module and
asserted a plus code that belonged to the other example's coordinates (the
value is verified against the reference Open Location Code encoder);
MediaLocation has no Display, so the parse example compares coordinates.
The sd-task-system example unwraps dispatch and matches the (TaskId,
TaskOutput) pair Done now carries. The spacedrive-sdk sketch names types
that do not exist yet and the job-derive expansion only resolves inside
sd-core, so both are marked ignore with the reason beside them.

* build: pin bun to 1.3.4 everywhere

package.json said bun@1.3.0 while CI installed 1.3.4, and any newer bun
rewrites bun.lockb on install, so the lockfile churned on every machine.
Pin packageManager to the CI version, document it, and install with
--frozen-lockfile in the TypeScript job so a drifting lockfile fails
instead of being silently rewritten.

* status: register the CI green on sources work and the libav requirement

* docs: make the sd-core doctests compile too

Five sd-core examples referenced the crate by its old name, used an arrow
glyph in a rust fence, or called methods without the trait in scope; the
copy strategy sketch needs a running JobContext so it is marked ignore.

* ci: stop shrinking the runner's root disk before installing a toolchain

easimon/maximize-build-space moves the root filesystem's free space into an
LVM volume mounted at the workspace and leaves root with the reserve, which
on the Blacksmith runner came out at 100 MB after the swap file. rustup
installs the pinned 1.97.1 toolchain under /home/runner/.rustup on root, so
both Rust jobs died with 'No space left on device'. The runner has 82 GB
free on root, which is plenty for a clippy target directory, so the step
goes.

* ci: run clippy on the Ubuntu 24.04 Blacksmith runner; let sd-server check without bun

The Blacksmith migration wrote the runner label into the matrix's target
field and left runs-on at GitHub's ubuntu-22.04, whose FFmpeg 4.4 predates
the libav 6 API sd-ffmpeg uses (ch_layout, av_dict_iterate), so the job
could never compile sd-ffmpeg. It now runs on blacksmith-4vcpu-ubuntu-2404
with FFmpeg 6.1, the same as a developer machine on 24.04, and the target
field holds a target triple again.

sd-server's build script skipped the web build when bun was absent and
RustEmbed then failed on the missing apps/web/dist. A debug build now gets
an empty dist with a warning so check and clippy pass; a release build
without bun and without a prebuilt dist still refuses, so a server never
ships without its UI by accident.

* build: let the desktop crate compile without a built frontend

tauri::generate_context! panics when frontendDist is missing, which is how
every check or clippy run looks before bun run build. The build script now
creates an empty apps/tauri/dist for debug builds with a warning; a release
build without one still refuses.

* status: record the CI result for the sources green-up
2026-10-04 20:15:07 +00:00

289 lines
8.9 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
if [ "${CI:-}" = "true" ]; then
set -x
fi
err() {
for _line in "$@"; do
echo "$_line" >&2
done
exit 1
}
has() {
for prog in "$@"; do
if ! command -v "$prog" 1>/dev/null 2>&1; then
return 1
fi
done
}
sudo() {
if [ "$(id -u)" -eq 0 ]; then
"$@"
else
env sudo "$@"
fi
}
script_failure() {
if [ -n "${1:-}" ]; then
_line="on line $1"
else
_line="(unknown)"
fi
err "An error occurred $_line." "Setup failed."
}
trap 'script_failure ${LINENO:-}' ERR
case "${OSTYPE:-}" in
'msys' | 'mingw' | 'cygwin')
err 'Bash for windows is not supported, please interact with this repo from Powershell or CMD'
;;
esac
if [ "${CI:-}" != "true" ]; then
echo 'Spacedrive Development Environment Setup'
echo 'To set up your machine for Spacedrive development, this script will install some required dependencies with your system package manager'
echo
echo 'Press Enter to continue'
read -r
if ! has bun; then
err 'bun was not found.' \
"Ensure the 'bun' command is in your \$PATH." \
'You must use bun for this project; yarn, npm, and pnpm are not allowed.' \
'https://bun.sh/docs/installation'
fi
if ! has rustc cargo; then
err 'Rust was not found.' \
"Ensure the 'rustc' and 'cargo' binaries are in your \$PATH." \
'https://rustup.rs'
fi
echo
fi
# Install rust deps for android
if [ "${1:-}" = "mobile" ]; then
MOBILE=1
# Android requires python
if ! { has python3 || { has python && python -c 'import sys; exit(0 if sys.version_info[0] == 3 else 1)'; }; }; then
err 'python3 was not found.' \
'This is required for Android mobile development.' \
"Ensure 'python3' is available in your \$PATH and try again."
fi
if ! has rustup; then
err 'Rustup was not found. It is required for cross-compiling rust to mobile targets.' \
"Ensure the 'rustup' binary is in your \$PATH." \
'https://rustup.rs'
fi
# Android targets
echo "Installing Android targets for Rust..."
if [ "${CI:-}" = "true" ]; then
# TODO: This need to be adjusted for future mobile release CI
rustup target add x86_64-linux-android
else
rustup target add \
aarch64-linux-android \
armv7-linux-androideabi \
x86_64-linux-android
fi
echo
else
MOBILE=0
fi
# Install system deps
case "$(uname)" in
"Darwin")
# crates/ffmpeg is a default workspace member and links the system libav
# libraries, so FFmpeg's headers must be present before the first build.
if [ "$(uname -m)" = 'x86_64' ] && ! [ "${CI:-}" = "true" ]; then
brew install nasm cmake ffmpeg pkg-config
elif ! [ "${CI:-}" = "true" ]; then
brew install cmake ffmpeg pkg-config
fi
# Install rust deps for iOS
if [ $MOBILE -eq 1 ]; then
echo "Checking for Xcode..."
if ! /usr/bin/xcodebuild -version >/dev/null; then
err "Xcode was not detected." \
"Please ensure Xcode is installed and try again."
fi
echo "Installing iOS targets for Rust..."
case "$(uname -m)" in
"arm64" | "aarch64") # M series
rustup target add aarch64-apple-ios aarch64-apple-ios-sim
;;
"x86_64") # Intel
rustup target add x86_64-apple-ios aarch64-apple-ios
;;
*)
err 'Unsupported architecture for CI build.'
;;
esac
echo
fi
;;
"Linux")
# https://github.com/tauri-apps/tauri-docs/blob/dev/docs/guides/getting-started/prerequisites.md#setting-up-linux
if has apt-get; then
echo "Detected apt!"
echo "Installing dependencies with apt..."
# Tauri dependencies
set -- build-essential curl wget file openssl libssl-dev libgtk-3-dev librsvg2-dev \
libwebkit2gtk-4.1-dev libayatana-appindicator3-dev libxdo-dev libdbus-1-dev
# Webkit2gtk requires gstreamer plugins for video playback to work
set -- "$@" gstreamer1.0-plugins-good gstreamer1.0-plugins-ugly libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev
# C/C++ build dependencies, required to build some *-sys crates
set -- "$@" llvm-dev libclang-dev clang nasm perl cmake pkg-config
# FFmpeg headers: crates/ffmpeg (a default workspace member) links libav* and
# ffmpeg-sys-next runs bindgen against them, which needs libclang
set -- "$@" libavutil-dev libavformat-dev libavcodec-dev libavfilter-dev \
libavdevice-dev libswscale-dev libswresample-dev
# React dependencies
set -- "$@" libvips42
sudo apt-get -y update
sudo apt-get -y install "$@"
elif has pacman; then
echo "Detected pacman!"
echo "Installing dependencies with pacman..."
# Tauri dependencies
set -- base-devel curl wget file openssl gtk3 librsvg webkit2gtk-4.1 libayatana-appindicator xdotool dbus
# Webkit2gtk requires gstreamer plugins for video playback to work
set -- "$@" gst-plugins-base gst-plugins-good gst-plugins-ugly
# C/C++ build dependencies, required to build some *-sys crates
set -- "$@" clang nasm perl cmake pkgconf
# FFmpeg headers for crates/ffmpeg
set -- "$@" ffmpeg
# React dependencies
set -- "$@" libvips
sudo pacman -Sy --needed "$@"
elif has dnf; then
echo "Detected dnf!"
echo "Installing dependencies with dnf..."
# For Enterprise Linux, you also need "Development Tools" instead of "C Development Tools and Libraries"
if ! { sudo dnf group install "C Development Tools and Libraries" || sudo dnf group install "Development Tools"; }; then
err 'We were unable to install the "C Development Tools and Libraries"/"Development Tools" package.' \
'Please open an issue if you feel that this is incorrect.' \
'https://github.com/spacedriveapp/spacedrive/issues'
fi
# Tauri dependencies
set -- openssl webkit2gtk4.1-devel openssl-devel curl wget file libappindicator-gtk3-devel librsvg2-devel libxdo-devel dbus-devel
# Webkit2gtk requires gstreamer plugins for video playback to work
set -- "$@" gstreamer1-devel gstreamer1-plugins-base-devel gstreamer1-plugins-good \
gstreamer1-plugins-good-extras gstreamer1-plugins-ugly-free
# C/C++ build dependencies, required to build some *-sys crates
set -- "$@" clang clang-devel nasm perl-core cmake pkgconf-pkg-config
# FFmpeg headers for crates/ffmpeg (ffmpeg-free ships the libav*-devel packages)
set -- "$@" ffmpeg-free-devel
# React dependencies
set -- "$@" vips
sudo dnf install "$@"
elif has apk; then
echo "Detected apk!"
echo "Installing dependencies with apk..."
echo "Alpine suport is experimental" >&2
# Tauri dependencies
set -- build-base curl wget file openssl-dev gtk+3.0-dev librsvg-dev \
webkit2gtk-4.1-dev libayatana-indicator-dev xdotool-dev dbus-dev
# Webkit2gtk requires gstreamer plugins for video playback to work
set -- "$@" gst-plugins-base-dev gst-plugins-good gst-plugins-ugly
# C/C++ build dependencies, required to build some *-sys crates
set -- "$@" llvm16-dev clang16 nasm perl cmake pkgconf
# FFmpeg headers for crates/ffmpeg
set -- "$@" ffmpeg-dev
# React dependencies
set -- "$@" vips
sudo apk add "$@"
elif has eopkg; then
echo "Detected eopkg!"
echo "Installing dependencies with eopkg..."
echo "Solus support is experimental" >&2
# Tauri dependencies
set -- curl wget file openssl openssl-devel libgtk-3-devel librsvg-devel \
libwebkit-gtk41-devel libayatana-appindicator-devel xdotool-devel dbus-devel
# Webkit2gtk requires gstreamer plugins for video playback to work
set -- "$@" gstreamer-1.0-plugins-good gstreamer-1.0-plugins-ugly gstreamer-1.0-devel gstreamer-1.0-plugins-base-devel
# C/C++ build dependencies, required to build some *-sys crates
set -- "$@" llvm-devel llvm-clang-devel llvm-clang nasm perl cmake pkg-config
# FFmpeg headers for crates/ffmpeg
set -- "$@" ffmpeg-devel
# React dependencies
set -- "$@" libvips
sudo eopkg it -c system.devel -y
sudo eopkg it "$@" -y
else
if has lsb_release; then
_distro="'$(lsb_release -s -d)' "
fi
err "Your Linux distro ${_distro:-}is not supported by this script." \
'We would welcome a PR or some help adding your OS to this script:' \
'https://github.com/spacedriveapp/spacedrive/issues'
fi
;;
*)
err "Your OS ($(uname)) is not supported by this script." \
'We would welcome a PR or some help adding your OS to this script.' \
'https://github.com/spacedriveapp/spacedrive/issues'
;;
esac
if [ "${CI:-}" != "true" ]; then
echo "Installing Rust tools..."
_tools="cargo-watch"
if [ $MOBILE -eq 1 ]; then
_tools="$_tools cargo-ndk" # For building Android
fi
echo "$_tools" | xargs cargo install
fi
echo 'Your machine has been setup for Spacedrive development!'