This document describes the FFI library build and release process for SyndDB.
SyndDB uses a single unified workflow (build-ffi-libs.yml) that handles three distinct scenarios:
- Trigger: PRs that touch client code
- Platforms: Linux x86_64, macOS ARM64
- Builds: Yes
- Commits: No
- Artifacts: Yes (7 days)
- Purpose: Verify FFI builds work before merge
- Trigger: Commits to
mainthat touch client code - Platforms: Linux x86_64, macOS ARM64
- Builds: Yes
- Commits: Yes (to
crates/synddb-client/libs/with[skip ci]) - Artifacts: Yes (7 days)
- Purpose: Keep libraries in sync for cross-language developers
- Trigger: Git tags matching
v*.*.*(e.g.,v0.2.0) - Platforms: All 4 (Linux, macOS x64, macOS ARM64, Windows)
- Builds: Yes
- Commits: No
- Artifacts: Yes (90 days)
- GitHub Release: Yes (with checksums)
- crates.io: Yes (publishes package)
- Purpose: Production binaries for end users
Key Design: One workflow file, conditional logic based on github.event_name and github.ref
Libraries are automatically rebuilt and committed to the repository on every push to main:
Location: crates/synddb-client/libs/
libs/
├── linux-x64/
│ └── libsynddb_client.so
└── darwin-arm64/
└── libsynddb_client.dylib
Benefits:
- Python/Node.js developers can use libraries without building Rust
- Libraries are always in sync with the code
- CI automatically updates them via
[skip ci]commits
How it works:
- Code pushed to
main - GitHub Actions builds Linux + macOS ARM64 libs
- Bot commits libraries back to repo with
[skip ci] - Developers pull and use updated libraries
Release builds support all major platforms:
- Linux x86_64:
libsynddb_client.so - macOS x86_64 (Intel):
libsynddb_client.dylib - macOS ARM64 (M1/M2/M3):
libsynddb_client.dylib - Windows x86_64:
synddb_client.dll
- Ensure all tests pass on
mainbranch - Update version numbers in relevant
Cargo.tomlfiles - Update
CHANGELOG.mdwith release notes - Ensure
CARGO_REGISTRY_TOKENsecret is configured in repository settings (for crates.io publishing)
We follow Semantic Versioning:
- MAJOR version for incompatible API changes
- MINOR version for backwards-compatible functionality additions
- PATCH version for backwards-compatible bug fixes
-
Update version numbers:
# Update version in all crates # Edit crates/synddb-client/Cargo.toml # Edit crates/synddb-sequencer/Cargo.toml # Edit crates/synddb-benchmark/Cargo.toml
-
Commit version bump:
git add -A git commit -m "chore: Bump version to v0.2.0" git push origin main -
Create and push a tag:
git tag v0.2.0 git push origin v0.2.0
-
Workflow triggers automatically:
- Go to Actions tab
- Watch the "Release" workflow build all platforms
- Check the "Releases" page for the new release
The release workflow performs these steps:
-
Multi-platform builds (parallel):
- Linux x86_64: Builds on
ubuntu-latest - macOS x86_64: Builds on
macos-13 - macOS ARM64: Builds on
macos-14 - Windows x86_64: Builds on
windows-latest
- Linux x86_64: Builds on
-
Artifact preparation:
- Renames libraries with platform suffixes
- Generates SHA256 checksums
- Includes C header file (
synddb.h)
-
GitHub Release:
- Creates release with tag name
- Uploads all platform libraries
- Uploads checksums file
- Adds comprehensive release notes
-
crates.io publishing:
- Publishes
synddb-clientto crates.io - Only on tag pushes (not manual triggers)
- Publishes
The unified build-ffi-libs.yml workflow includes:
-
build-libs (matrix)
- Builds all platforms in parallel
- Conditional: Skips release-only platforms on dev builds
- Uses
build_for: bothorbuild_for: releaseflags - Uploads artifacts with context-appropriate retention
-
commit-dev-libs
- Runs only on
maincommits (not tags) - Downloads dev artifacts (Linux, macOS ARM64)
- Commits to
crates/synddb-client/libs/with[skip ci]
- Runs only on
-
create-release
- Runs only on tags
- Downloads all artifacts (4 platforms)
- Renames with platform suffixes
- Generates checksums
- Creates GitHub Release
-
publish-crates
- Runs only on tags
- Publishes to crates.io (if token configured)
See .github/workflows/rust-ci.yml for testing and benchmarking:
- Tests:
cargo test --all - Benchmarks: Performance regression detection
- Code Quality: Clippy, rustfmt (in
rust-checks.yml)
FFI library building is handled separately by build-ffi-libs.yml
After a release, users can download pre-built libraries:
# Download for your platform
curl -LO https://github.com/Syndicate/SyndDB/releases/download/v0.2.0/synddb_client-linux-x86_64.so
curl -LO https://github.com/Syndicate/SyndDB/releases/download/v0.2.0/synddb.hcurl -LO https://github.com/Syndicate/SyndDB/releases/download/v0.2.0/SHA256SUMS
sha256sum -c SHA256SUMSPython (ctypes):
# Download library for your platform
# Use examples/ffi/test.py as referenceNode.js (koffi/ffi-napi):
npm install
# Download library and place in project root
# Use examples/ffi/test_koffi.js as referenceGo (cgo):
# Download library
# Use bindings/go/ as referenceIf you need to build the FFI library yourself:
# Build for current platform
cargo build --package synddb-client --features ffi --release
# Output location
ls -lh target/release/libsynddb_client.*- Check Actions logs for specific error
- Common issues:
- Version already exists on crates.io (expected, won't fail)
- Build failures on specific platforms
- Missing secrets (CARGO_REGISTRY_TOKEN)
If a platform binary is missing from the release:
- Check if that platform's build job failed
- Re-run the failed job or re-trigger the workflow
- Build locally on that platform if needed
- Ensure CARGO_REGISTRY_TOKEN is set in repository secrets
- Check if version already published (idempotent, won't fail)
- Verify Cargo.toml has correct metadata
Before creating a release:
- All tests pass on
main - Benchmarks show no regressions
- Version numbers updated in Cargo.toml files
- CHANGELOG.md updated
- Examples tested and working
- Documentation up to date
- FFI header file (
synddb.h) is current
After release:
- Verify all platform binaries present in GitHub Release
- Test downloads work
- Verify checksums match
- Check crates.io shows new version
- Announce release (if public)
Potential enhancements to the release process:
- Publish to npm (@synddb/client-native)
- Publish to PyPI (synddb-client)
- Automated changelog generation
- Automated version bumping
- Cross-compilation for more platforms (ARM Linux, etc.)
- Signed binaries
- Notarization for macOS binaries