mirror of
https://github.com/spacedriveapp/spacedrive.git
synced 2026-11-02 13:25:19 -05:00
* 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
118 lines
3.4 KiB
Rust
118 lines
3.4 KiB
Rust
use std::env;
|
|
use std::path::{Path, PathBuf};
|
|
use std::process::Command;
|
|
|
|
fn main() {
|
|
println!("cargo:rerun-if-changed=build.rs");
|
|
println!("cargo:rerun-if-env-changed=SD_SKIP_WEB_BUILD");
|
|
|
|
if env::var_os("SD_SKIP_WEB_BUILD").is_some() {
|
|
println!("cargo:warning=SD_SKIP_WEB_BUILD set — using existing apps/web/dist");
|
|
return;
|
|
}
|
|
|
|
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
|
|
let repo_root = manifest_dir
|
|
.parent()
|
|
.and_then(Path::parent)
|
|
.expect("apps/server is two levels below the repo root")
|
|
.to_path_buf();
|
|
let web_dir = repo_root.join("apps/web");
|
|
|
|
// If bun isn't available (e.g., Docker Rust build stage), the caller is
|
|
// expected to have prebuilt apps/web/dist. RustEmbed needs the folder to
|
|
// exist even for a check or clippy run, so a debug build without either
|
|
// gets an empty one; a release build refuses to ship a server without a UI.
|
|
if Command::new("bun").arg("--version").output().is_err() {
|
|
let dist = web_dir.join("dist");
|
|
if !dist.exists() {
|
|
if env::var("PROFILE").as_deref() == Ok("release") {
|
|
panic!(
|
|
"bun not found on PATH and {} does not exist; build the web UI first or set SD_SKIP_WEB_BUILD=1 with a prebuilt dist",
|
|
dist.display()
|
|
);
|
|
}
|
|
std::fs::create_dir_all(&dist).expect("create an empty apps/web/dist");
|
|
println!(
|
|
"cargo:warning=bun not found on PATH — created an empty apps/web/dist so the server compiles without the web UI"
|
|
);
|
|
return;
|
|
}
|
|
println!("cargo:warning=bun not found on PATH — using existing apps/web/dist");
|
|
return;
|
|
}
|
|
|
|
// Refuse to proceed if workspace dependencies aren't installed.
|
|
if !repo_root.join("node_modules").exists() {
|
|
panic!(
|
|
"node_modules missing at {} — run `bun install` (or `just setup`) before building sd-server, \
|
|
or set SD_SKIP_WEB_BUILD=1 to skip the embedded UI build.",
|
|
repo_root.display()
|
|
);
|
|
}
|
|
|
|
// Invalidate the build script when any UI source or relevant config changes.
|
|
// Cargo will cache this build script's output otherwise, so Rust-only changes
|
|
// won't pay the cost of rebuilding the web bundle.
|
|
watch_dir(&web_dir.join("src"));
|
|
watch_dir(&repo_root.join("packages/interface/src"));
|
|
watch_dir(&repo_root.join("packages/ts-client/src"));
|
|
for path in [
|
|
web_dir.join("index.html"),
|
|
web_dir.join("vite.config.ts"),
|
|
web_dir.join("package.json"),
|
|
web_dir.join("tsconfig.json"),
|
|
repo_root.join("packages/interface/package.json"),
|
|
repo_root.join("packages/ts-client/package.json"),
|
|
] {
|
|
if path.exists() {
|
|
rerun(&path);
|
|
}
|
|
}
|
|
|
|
let status = Command::new("bun")
|
|
.args(["run", "build"])
|
|
.current_dir(&web_dir)
|
|
.status()
|
|
.expect("failed to spawn `bun run build`");
|
|
|
|
if !status.success() {
|
|
panic!(
|
|
"`bun run build` in {} failed with status {}",
|
|
web_dir.display(),
|
|
status
|
|
);
|
|
}
|
|
}
|
|
|
|
fn watch_dir(dir: &Path) {
|
|
if !dir.exists() {
|
|
return;
|
|
}
|
|
let entries = match std::fs::read_dir(dir) {
|
|
Ok(e) => e,
|
|
Err(_) => return,
|
|
};
|
|
for entry in entries.flatten() {
|
|
let path = entry.path();
|
|
let file_type = match entry.file_type() {
|
|
Ok(ft) => ft,
|
|
Err(_) => continue,
|
|
};
|
|
if file_type.is_dir() {
|
|
if let Some(name) = path.file_name().and_then(|s| s.to_str()) {
|
|
if matches!(name, "node_modules" | "dist" | ".turbo" | "build" | ".next") {
|
|
continue;
|
|
}
|
|
}
|
|
watch_dir(&path);
|
|
} else if file_type.is_file() {
|
|
rerun(&path);
|
|
}
|
|
}
|
|
}
|
|
|
|
fn rerun(path: &Path) {
|
|
println!("cargo:rerun-if-changed={}", path.display());
|
|
}
|