Skip to content

Simpler crates for embedding Surreal Sync #275

Simpler crates for embedding Surreal Sync

Simpler crates for embedding Surreal Sync #275

Workflow file for this run

name: Test PR
on:
pull_request:
branches:
- main
# Cancel superseded runs for the same PR.
concurrency:
group: test-pr-${{ github.ref }}
cancel-in-progress: true
env:
CARGO_TERM_COLOR: always
jobs:
lint:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install system build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential cmake libssl-dev libsasl2-dev pkg-config protobuf-compiler postgresql-client
- name: Install Rust toolchain (from rust-toolchain.toml) + cache
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
components: rustfmt, clippy
cache: true
- name: Format check
run: cargo fmt --all -- --check
- name: Clippy
run: cargo clippy --workspace --all-targets --all-features -- -D warnings
# Parallel with build/lint — does not extend the build → test critical path
examples:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install system build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential cmake libssl-dev libsasl2-dev pkg-config protobuf-compiler postgresql-client ripgrep
- name: Install Rust toolchain (from rust-toolchain.toml) + cache
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
cache: true
- name: Compile embedder examples
run: make compile-embedder-examples CARGO_PROFILE=ci
- name: Embed dependency tree gates
run: |
set -euo pipefail
# Kafka / snowflake / runtime / mysql must not pull surrealdb
# in the normal+build graph (embed examples live in separate packages).
for pkg in surreal-sync-kafka surreal-sync-snowflake surreal-sync-runtime surreal-sync-mysql; do
out=$(cargo tree -p "$pkg" -e normal,build -i surrealdb 2>&1 || true)
if echo "$out" | rg -q '^surrealdb v'; then
echo "FAIL: $pkg unexpectedly depends on surrealdb:"
echo "$out"
exit 1
fi
echo "OK: $pkg has no surrealdb in normal/build graph"
done
# snowflake / mysql must not pull kafka or neo4j clients
for pkg in surreal-sync-snowflake surreal-sync-mysql; do
for deny in rdkafka neo4rs; do
out=$(cargo tree -p "$pkg" -e normal,build -i "$deny" 2>&1 || true)
if echo "$out" | rg -q "^${deny} "; then
echo "FAIL: $pkg unexpectedly depends on $deny:"
echo "$out"
exit 1
fi
done
echo "OK: $pkg has no rdkafka/neo4rs in normal/build graph"
done
# Surreal crate must not pull clap by default (runtime cli feature is opt-in)
for feats in "v2" "v3"; do
out=$(cargo tree -p surreal-sync-surreal --features "$feats" -e normal,build -i clap 2>&1 || true)
if echo "$out" | rg -q '^clap v'; then
echo "FAIL: surreal-sync-surreal --features $feats unexpectedly depends on clap:"
echo "$out"
exit 1
fi
echo "OK: surreal-sync-surreal --features $feats has no clap in normal/build graph"
done
# surreal-sync-core must not list tokio in [dependencies] (dev-only ok)
if rg -n '^\s*tokio\s*=' crates/sync-core/Cargo.toml; then
echo "FAIL: surreal-sync-core must not depend on tokio"
exit 1
fi
echo "OK: surreal-sync-core has no tokio dep"
# Single-major feature graphs: exactly one surrealdb major
# (default includes v3 — disable defaults so `v2` is not dual-SDK)
for feats in "v2" "v3"; do
tree=$(cargo tree -p surreal-sync-surreal --no-default-features --features "$feats" -e normal,build)
majors=$(echo "$tree" | rg -o 'surrealdb v[0-9]+' | sort -u | wc -l | tr -d ' ')
if [[ "$majors" != "1" ]]; then
echo "FAIL: surreal-sync-surreal --no-default-features --features $feats should depend on exactly one surrealdb major, got $majors"
echo "$tree"
exit 1
fi
echo "OK: surreal-sync-surreal --no-default-features --features $feats has one surrealdb major"
done
# Documented embed graphs (examples/from-* packages mirror a real embedder).
for pkg in surreal-sync-example-from-snowflake surreal-sync-example-from-mysql-binlog; do
for deny in rdkafka neo4rs; do
out=$(cargo tree -p "$pkg" -e normal,build -i "$deny" 2>&1 || true)
if echo "$out" | rg -q "^${deny} "; then
echo "FAIL: $pkg unexpectedly depends on $deny:"
echo "$out"
exit 1
fi
done
tree=$(cargo tree -p "$pkg" -e normal,build -i surrealdb 2>&1 || true)
if ! echo "$tree" | rg -q '^surrealdb v'; then
echo "FAIL: $pkg should link surrealdb (Surreal3Sink)"
echo "$tree"
exit 1
fi
majors=$(echo "$tree" | rg -o 'surrealdb v[0-9]+' | sort -u | wc -l | tr -d ' ')
if [[ "$majors" != "1" ]]; then
echo "FAIL: $pkg should depend on exactly one surrealdb major, got $majors"
echo "$tree"
exit 1
fi
if echo "$tree" | rg -q 'surrealdb v2'; then
echo "FAIL: $pkg should use SurrealDB v3 only"
echo "$tree"
exit 1
fi
echo "OK: $pkg has no kafka/neo4j and exactly one surrealdb v3 major"
done
# mysql-binlog CDC checkpoints live in surreal-sync-runtime (checkpoint_fs),
# not a separate checkpoint-fs package
if ! cargo tree -p surreal-sync-example-from-mysql-binlog -e normal,build \
| rg -q 'surreal-sync-surreal'; then
echo "FAIL: mysql-binlog example should depend on surreal-sync-surreal"
exit 1
fi
if ! cargo tree -p surreal-sync-example-from-mysql-binlog -e normal,build \
| rg -q 'surreal-sync-runtime'; then
echo "FAIL: mysql-binlog example should pull surreal-sync-runtime (checkpoint_fs)"
exit 1
fi
if cargo tree -p surreal-sync-example-from-mysql-binlog -e normal,build \
| rg -q 'surreal-sync-checkpoint-fs'; then
echo "FAIL: obsolete package surreal-sync-checkpoint-fs must not appear in the graph"
exit 1
fi
echo "OK: mysql-binlog example uses surreal-sync-runtime checkpoints"
# Embed example sources monomorphize Surreal3Sink only
if ! rg -n 'run::<Surreal3Sink>' examples/from-snowflake examples/from-mysql-binlog; then
echo "FAIL: examples should monomorphize Surreal3Sink"
exit 1
fi
if rg -n 'run::<Surreal2Sink>|Surreal2Sink' examples/from-snowflake examples/from-mysql-binlog; then
echo "FAIL: embed examples must not reference Surreal2Sink"
exit 1
fi
echo "OK: examples use run::<Surreal3Sink> only"
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install system build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential cmake libssl-dev libsasl2-dev pkg-config protobuf-compiler postgresql-client
- name: Install Rust toolchain (from rust-toolchain.toml) + cache
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
cache: true
- name: Install cargo-nextest
uses: taiki-e/install-action@16b05812d776ae1dfaabc8277e421fb6d2506419 # v2.82.7
with:
tool: nextest
- name: Build CLI + all test binaries
run: cargo build --workspace --all-features --profile ci --bins --tests
- name: Archive test binaries
run: cargo nextest archive --workspace --all-features --cargo-profile ci --profile ci --archive-file nextest.tar.zst
- name: Upload nextest archive
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: nextest-archive
path: nextest.tar.zst
retention-days: 1
test:
needs: build
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3]
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Download nextest archive
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: nextest-archive
- name: Install cargo-nextest
uses: taiki-e/install-action@16b05812d776ae1dfaabc8277e421fb6d2506419 # v2.82.7
with:
tool: nextest
- name: Pre-build PostgreSQL (wal2json) test image
run: |
docker build -t postgres-wal2json-test \
-f crates/postgresql/Dockerfile.postgres16.wal2json \
crates/postgresql
- name: Pre-pull MySQL/MariaDB binlog test images
run: make prepull-binlog-images
- name: Export binlog test image tags
run: make print-test-images >> $GITHUB_ENV
- name: Run unit + integration tests (nextest shard ${{ matrix.shard }}/3)
env:
SURREAL_SYNC_BIN: ${{ github.workspace }}/target/ci/surreal-sync
RUST_BACKTRACE: 1
run: |
cargo nextest run --archive-file nextest.tar.zst --profile ci \
--extract-to . --extract-overwrite \
--partition count:${{ matrix.shard }}/3
- name: Clean up leftover test containers
if: always()
run: docker rm -f $(docker ps -aq) 2>/dev/null || true
- name: Upload test results on failure
if: failure()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: test-results-shard-${{ matrix.shard }}
path: |
target/nextest/ci/junit.xml
logs/test/
retention-days: 7
if-no-files-found: ignore
doc:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- name: Install system build dependencies
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends \
build-essential cmake libssl-dev libsasl2-dev pkg-config protobuf-compiler postgresql-client
- name: Install Rust toolchain (from rust-toolchain.toml) + cache
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
with:
cache: true
- name: Run documentation tests
run: cargo test --workspace --doc