Spacedrive uses GitHub Actions workflows, git tags, and a custom xtask command to manage releases. This page covers the full release pipeline from version bump to published artifacts.
Versioning
Spacedrive follows semver with pre-release suffixes for alpha/beta releases.
2.0.0-alpha.1 # Pre-release
2.0.0-beta.1 # Pre-release
2.0.0 # Stable release
The version string lives in 7 files across the repo:
core/Cargo.toml
apps/server/Cargo.toml
apps/cli/Cargo.toml
apps/tauri/src-tauri/Cargo.toml
apps/tauri/sd-tauri-core/Cargo.toml
apps/tauri/src-tauri/tauri.conf.json
apps/tauri/package.json
These must stay in sync. The bump command handles this automatically.
Bump Command
cargo xtask bump updates all version files, commits the changes, and creates a git tag.
cargo xtask bump 2.0.0-alpha.2
This does three things:
- Updates the version string in all 7 files
- Commits with message
v2.0.0-alpha.2
- Creates git tag
v2.0.0-alpha.2
It does not push. You push manually when ready:
Pushing the tag triggers the release workflows.
Workflows
Five GitHub Actions workflows handle CI and releases.
CI (ci.yml)
Runs on every pull request and push to main. Handles formatting checks, linting, and build verification. This is the standard PR gate.
Core Tests (core_tests.yml)
Runs sd-core integration tests on push to main across macOS, Linux, and Windows. Tests run on real hardware including self-hosted macOS ARM64 and Windows runners.
Release (release.yml)
Triggered by pushing a v* tag or manual dispatch. Builds all release artifacts and creates a draft GitHub release.
Server binary builds:
| Platform | Architecture |
|---|
| Linux | x86_64 |
| Linux | aarch64 |
Server binaries are compiled with sd-core/heif, sd-core/ffmpeg, and sd-core/ai features enabled. Each produces a tarball with the binary and a SHA256 checksum.
Desktop builds (Tauri):
| Platform | Architecture | Bundle |
|---|
| macOS | aarch64 | DMG, App |
| macOS | x86_64 | DMG, App |
| Windows | x86_64 | NSIS |
| Linux | x86_64 | DEB |
| Linux | aarch64 | DEB |
Desktop builds go through tauri-action which handles code signing (macOS), Tauri signing keys (for the updater), and bundle creation. macOS builds run on self-hosted runners with Apple signing certificates.
The final release job waits for all builds to complete, downloads all artifacts, and creates a draft release on GitHub. The release is always created as a draft so you can review before publishing.
The release is created as a draft. You must manually publish it on GitHub after verifying the artifacts.
Server Docker (server.yml)
Triggered by the same v* tag or manual dispatch. Builds a multi-arch Docker image (amd64 + arm64) and pushes it to GitHub Container Registry at ghcr.io/spacedriveapp/spacedrive/server.
The Docker build uses buildah with QEMU emulation for cross-platform images. The Dockerfile is at apps/server/Dockerfile.
Tagging behavior:
| Tag pushed | Docker tags applied | latest updated? |
|---|
v2.0.0-alpha.1 | v2.0.0-alpha.1 | No |
v2.0.0-beta.1 | v2.0.0-beta.1 | No |
v2.0.0 | v2.0.0, latest | Yes |
| Manual dispatch | {short-sha}, staging | No |
The latest tag only moves for stable releases (tags matching vX.Y.Z with no suffix). Pre-release tags like alpha or beta are published under their specific version only. This protects users pulling latest from getting unstable builds.
Mobile Release (mobile.yml)
Manual dispatch only. Builds the React Native app for iOS and/or Android. A platform picker lets you build ios, android, or all.
The mobile app bundles sd-mobile-core, a native Expo module that wraps the Spacedrive Rust core. This means mobile builds require the full Cargo workspace and Rust cross-compilation toolchain, not just JavaScript bundling.
iOS (TestFlight):
- Compiles
sd-mobile-core for aarch64-apple-ios via cargo xtask build-mobile
- Runs
expo prebuild to generate the Xcode project
- Archives with
xcodebuild using manual code signing
- Exports IPA with
app-store-connect distribution method
- Uploads directly to TestFlight via
xcrun altool
Runs on a self-hosted macOS ARM64 runner (same as desktop macOS builds). TestFlight handles distribution to testers automatically after upload.
Android (Play Store Internal):
- Compiles
sd-mobile-core for aarch64-linux-android via cargo xtask build-mobile
- Runs
expo prebuild to generate the Android project
- Builds a signed AAB with
./gradlew bundleRelease
- Uploads to Play Store internal testing track
Runs on a Linux runner with Java 17 and the Android SDK/NDK.
The mobile workflow is manual dispatch only. It is not triggered by tags. Run it from the Actions tab when you want to push a mobile build to testers.
Required secrets (in addition to existing Apple secrets):
| Secret | Purpose |
|---|
MOBILE_PROVISIONING_PROFILE | iOS App Store distribution profile for com.spacedrive.app (base64) |
ANDROID_KEYSTORE | Android release keystore file (base64) |
ANDROID_KEYSTORE_PASSWORD | Keystore password |
ANDROID_KEY_ALIAS | Signing key alias |
ANDROID_KEY_PASSWORD | Signing key password |
GOOGLE_PLAY_SERVICE_ACCOUNT | Google Play API service account JSON (for automated upload) |
Release Flow
A full release looks like this:
# 1. Bump version, commit, and tag
cargo xtask bump 2.0.0-alpha.2
# 2. Push the tag (triggers release + server docker workflows)
git push --tags
# 3. Wait for workflows to complete on GitHub Actions
# 4. Review the draft release on GitHub, then publish
Both release.yml and server.yml trigger in parallel from the same tag push. The GitHub release is created as a draft. The Docker image is pushed to ghcr.io immediately.
Mobile releases are decoupled from this flow. Trigger the mobile workflow manually from the Actions tab when you want to push a build to TestFlight or Play Store internal testing.
Tauri Updater
Desktop builds include includeUpdaterJson: true in the Tauri action config. This generates a JSON manifest that the Tauri updater checks against to notify users of new versions. The updater JSON files are included as release artifacts alongside the binaries.
Secrets
The release workflow depends on several repository secrets:
| Secret | Purpose |
|---|
APPLE_CERTIFICATE | macOS code signing certificate (base64) |
APPLE_CERTIFICATE_PASSWORD | Certificate password |
APPLE_SIGNING_IDENTITY | Signing identity string |
APPLE_API_KEY | App Store Connect API key ID |
APPLE_API_KEY_BASE64 | API key file (base64) |
APPLE_API_ISSUER | API key issuer ID |
APPLE_PROVIDER_SHORT_NAME | Team provider short name |
TAURI_PRIVATE_KEY | Tauri update signing key |
TAURI_KEY_PASSWORD | Tauri signing key password |
SENTRY_AUTH_TOKEN | Sentry error tracking |
The Docker workflow uses only GITHUB_TOKEN which is provided automatically.