Files
Jamie Pineandcapy-ai-staging[bot] a2831ac9b2 Run the pairing suites in CI: device persistence, proxy pairing, and relay pairing through a local relay (#3152)
* Run the pairing suites in CI with condition waits and a local relay

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Say what the integration group's wall-time budget is and which relay the mDNS suites still reach

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Name where the integration group's 15 minute target comes from

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Keep a newer same-ALPN connection alive when an older one to the same node closes

The connection map is keyed by node and ALPN, so an incoming pairing
connection and an outbound one opened for a single message share a key.
When the older one closed, the handler and the per-node watcher removed
the key and took the newer connection's last handle, so QUIC closed it
under the peer before the message had been read. Carol's proxy acceptance
to Alice was lost this way in 1 of 13 proxy_pairing_test runs in sequence.
Removal now checks the stored connection is the closed one, and a one-shot
send waits for the peer to acknowledge the bytes before returning.

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

* Wait for the message acknowledgement off the event loop and say when a closed connection's key is kept

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>

---------

Co-authored-by: capy-ai-staging[bot] <305915985+capy-ai-staging[bot]@users.noreply.github.com>
2026-10-09 12:17:23 +00:00
..
…

xtask

Build automation tasks for Spacedrive using the xtask pattern.

What is xtask?

The xtask pattern is the idiomatic Rust way to handle project-specific build automation. Instead of using shell scripts, Makefiles, JavaScript, or external build tools, you write your build tasks as Rust code in a workspace member called xtask.

This approach is used by major Rust projects including:

  • rust-analyzer - IDE support
  • tokio - async runtime
  • cargo itself - Rust's package manager

Benefits

  • Pure Rust - No shell scripts or JavaScript tooling
  • Type-safe - Catch errors at compile time
  • Debuggable - Use standard Rust debugging tools
  • Cross-platform - Works on Windows, macOS, Linux
  • No external tools - Just cargo and rustup
  • Self-contained - No need for pnpm, node, or JavaScript

Usage

Run tasks using cargo xtask:

# Setup development environment (replaces pnpm prep)
cargo xtask setup

# Build iOS framework (device + simulator)
cargo xtask build-ios

# Or use the convenient alias:
cargo ios

Available Commands

test-core

Single source of truth for core integration tests!

Runs all sd-core integration tests with progress tracking and result summary. This command is used by both CI and local development, ensuring consistency.

Usage:

cargo xtask test-core           # Run with minimal output
cargo xtask test-core --verbose # Show full test output

Features:

  • Progress tracking (shows which test is running)
  • Timing for each test suite
  • Summary report showing passed/failed tests
  • Same test definitions used in CI workflows
  • Continues running even if some tests fail

All tests are defined in xtask/src/test_core.rs as the single source of truth. Add or remove tests there and they automatically apply to both CI and local runs.

setup

Replaces pnpm prep with a pure Rust implementation!

Sets up your development environment:

  1. Downloads native dependencies (FFmpeg, protoc, OpenSSL, libheif, etc.)
  2. Extracts them to apps/.deps/
  3. Downloads iOS-specific deps if iOS targets are installed
  4. Creates symlinks for shared libraries (macOS/Linux)
  5. Generates .cargo/config.toml from the template

Usage:

cargo xtask setup

First time setup:

# Install Rust if you haven't already
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# Add iOS targets (macOS only, optional)
rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios

# Run setup
cargo xtask setup

# Build the CLI
cargo build

build-ios

Builds the sd-ios-core library for iOS (macOS only):

  1. Compiles for aarch64-apple-ios (physical devices)
  2. Compiles for aarch64-apple-ios-sim (M1/M2 simulator)
  3. Compiles for x86_64-apple-ios (Intel simulator)
  4. Creates universal simulator library (ARM64 + x86_64) using lipo
  5. Updates the existing XCFramework that Xcode is already using

Output: apps/ios/sd-ios-core/sd_ios_core.xcframework/

The XCFramework structure looks like:

sd_ios_core.xcframework/
├── Info.plist                           # Top-level XCFramework metadata
├── ios-arm64/
│   ├── libsd_ios_core.a                 # Device library
│   └── Info.plist                       # Device metadata
└── ios-arm64-simulator/
    ├── libsd_ios_core.a                 # Universal simulator library (ARM64 + x86_64)
    └── Info.plist                       # Simulator metadata

How It Works

The xtask pattern works through Cargo's workspace and alias features. When you run:

cargo ios

Cargo:

  1. Looks for an alias in .cargo/config.toml
  2. Expands it to cargo run --package xtask -- build-ios
  3. Builds and runs the xtask binary
  4. Passes build-ios as an argument

The xtask binary is just a regular Rust program that uses std::process::Command to invoke cargo builds and file operations.

Migration from Old Setup

Replaced: pnpm prep (JavaScript)

Old way:

pnpm i              # Install JS dependencies
pnpm prep           # Run JavaScript setup script

New way:

cargo xtask setup   # Pure Rust, no JS needed!

Replaced: scripts/build_ios_xcframework.sh (Bash)

Old way:

./scripts/build_ios_xcframework.sh

New way:

cargo ios           # Convenient alias
# or
cargo xtask build-ios

Why the Change?

  • Old: Required pnpm, node, JavaScript dependencies, bash scripts
  • New: Only requires Rust toolchain (cargo/rustup)
  • Result: Faster setup, fewer dependencies, more maintainable

Requirements

  • Rust toolchain with iOS targets installed:
    rustup target add aarch64-apple-ios aarch64-apple-ios-sim x86_64-apple-ios
    
  • Xcode with iOS SDK (for lipo command)

Adding New Tasks

To add a new task:

  1. Add a new function in src/main.rs
  2. Add a match arm in main() to call your function
  3. Document it in the help message
  4. Optionally add a cargo alias in .cargo/config.toml

Example:

fn clean_ios() -> Result<()> {
    // Clean iOS builds
    todo!()
}

// In main():
match args[1].as_str() {
    "build-ios" => build_ios()?,
    "clean-ios" => clean_ios()?, // Add this
    _ => { /* ... */ }
}

Further Reading