ci(delta-sync): raise password-only fixture timeout 15m -> 25m #69
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Delta Sync Integration | |
| # Validates the rsync-over-SSH stack end-to-end against a local docker | |
| # fixture. Cheap to run, scoped to paths that actually affect the feature | |
| # so unrelated PRs don't pay for it. | |
| on: | |
| push: | |
| branches: [main] | |
| paths: | |
| - 'src-tauri/src/lib.rs' | |
| - 'src-tauri/src/settings.rs' | |
| - 'src-tauri/src/ssh_exec.rs' | |
| - 'src-tauri/src/rsync_output.rs' | |
| - 'src-tauri/src/rsync_over_ssh.rs' | |
| - 'src-tauri/src/delta_transport.rs' | |
| - 'src-tauri/src/delta_sync_rsync.rs' | |
| - 'src-tauri/src/providers/sftp.rs' | |
| - 'src-tauri/Cargo.lock' | |
| - 'src-tauri/tests/fixtures/sftp-rsync/**' | |
| - 'src-tauri/tests/integration_delta_sync.rs' | |
| - '.github/workflows/delta-sync-integration.yml' | |
| pull_request: | |
| branches: [main] | |
| paths: | |
| - 'src-tauri/src/lib.rs' | |
| - 'src-tauri/src/settings.rs' | |
| - 'src-tauri/src/ssh_exec.rs' | |
| - 'src-tauri/src/rsync_output.rs' | |
| - 'src-tauri/src/rsync_over_ssh.rs' | |
| - 'src-tauri/src/delta_transport.rs' | |
| - 'src-tauri/src/delta_sync_rsync.rs' | |
| - 'src-tauri/src/providers/sftp.rs' | |
| - 'src-tauri/Cargo.lock' | |
| - 'src-tauri/tests/fixtures/sftp-rsync/**' | |
| - 'src-tauri/tests/integration_delta_sync.rs' | |
| - '.github/workflows/delta-sync-integration.yml' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| integration: | |
| name: SFTP rsync fixture + live test (key-auth) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| toolchain: stable | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2 | |
| with: | |
| workspaces: './src-tauri -> target' | |
| - name: Install system dependencies | |
| run: | | |
| sudo apt-get update | |
| # rsync + ssh client for the host side of the integration test. | |
| # Webkit/GTK stack is needed because compiling the aeroftp | |
| # library pulls Tauri deps even when we only run one test binary. | |
| sudo apt-get install -y \ | |
| rsync \ | |
| openssh-client \ | |
| libwebkit2gtk-4.1-dev \ | |
| libappindicator3-dev \ | |
| librsvg2-dev | |
| - name: Generate fixture SSH key | |
| working-directory: src-tauri/tests/fixtures/sftp-rsync | |
| run: bash setup.sh | |
| - name: Build & start docker fixture | |
| working-directory: src-tauri/tests/fixtures/sftp-rsync | |
| run: docker compose up -d --build | |
| - name: Wait for fixture SSH | |
| run: | | |
| for i in $(seq 1 20); do | |
| if ssh -i src-tauri/tests/fixtures/sftp-rsync/ssh_key \ | |
| -o StrictHostKeyChecking=no \ | |
| -o UserKnownHostsFile=/dev/null \ | |
| -o BatchMode=yes \ | |
| -o ConnectTimeout=2 \ | |
| -p 2222 testuser@127.0.0.1 'true' 2>/dev/null; then | |
| echo "Fixture SSH ready after $((i * 2))s" | |
| exit 0 | |
| fi | |
| echo "Waiting for fixture SSH... ($i/20)" | |
| sleep 2 | |
| done | |
| echo "Fixture did not come up within 40s; dumping logs" >&2 | |
| docker logs aeroftp-delta-sync-fixture >&2 || true | |
| exit 1 | |
| - name: "Unit tests: delta-sync modules" | |
| working-directory: src-tauri | |
| run: | | |
| cargo test --lib --no-fail-fast -- \ | |
| rsync_output:: \ | |
| rsync_over_ssh:: \ | |
| ssh_exec:: \ | |
| delta_transport:: \ | |
| delta_sync_rsync:: | |
| - name: "Integration test: delta sync over SSH" | |
| working-directory: src-tauri | |
| run: cargo test --test integration_delta_sync -- --ignored --nocapture | |
| - name: Dump fixture logs on failure | |
| if: failure() | |
| working-directory: src-tauri/tests/fixtures/sftp-rsync | |
| run: | | |
| docker logs aeroftp-delta-sync-fixture || true | |
| docker compose ps | |
| - name: Teardown fixture | |
| if: always() | |
| working-directory: src-tauri/tests/fixtures/sftp-rsync | |
| run: docker compose down -v | |
| fallback-fixture: | |
| # PR-T02: covers the silent-fallback branch when the SFTP session | |
| # is password-only (delta path returns `None`, classic upload takes | |
| # over) and the offline hard-rejection contract. Runs in parallel | |
| # with the key-auth integration job so a regression in either lane | |
| # blocks the PR independently. | |
| name: SFTP password-only fixture + fallback contract | |
| runs-on: ubuntu-latest | |
| # Cold-cache PRs (Cargo.lock churn from deps bumps) compile the full | |
| # workspace + Tauri + aeroftp lib before the test binary links. The | |
| # sibling key-auth job needs ~11min on a warm shared cache; this lane | |
| # uses an isolated shared-key so the first cache miss can take 18-22 | |
| # minutes. 25min gives enough headroom without parking PRs forever. | |
| timeout-minutes: 25 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Install Rust | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| toolchain: stable | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2 | |
| with: | |
| workspaces: './src-tauri -> target' | |
| shared-key: delta-sync-fallback | |
| - name: Install system dependencies | |
| # sshpass needed to poll the password-auth fixture readiness | |
| # (the integration test itself uses russh via SftpProvider - | |
| # sshpass is just a scripting convenience). | |
| run: | | |
| sudo apt-get update | |
| sudo apt-get install -y \ | |
| rsync \ | |
| openssh-client \ | |
| sshpass \ | |
| libwebkit2gtk-4.1-dev \ | |
| libappindicator3-dev \ | |
| librsvg2-dev | |
| - name: Build & start password-auth docker fixture | |
| uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60 # v3 | |
| with: | |
| timeout_minutes: 5 | |
| max_attempts: 2 | |
| retry_wait_seconds: 10 | |
| command: | | |
| cd src-tauri/tests/fixtures/sftp-rsync | |
| docker compose -f docker-compose.password.yml up -d --build | |
| - name: Wait for password fixture SSH | |
| run: | | |
| for i in $(seq 1 20); do | |
| if sshpass -p testpass ssh \ | |
| -o StrictHostKeyChecking=no \ | |
| -o UserKnownHostsFile=/dev/null \ | |
| -o BatchMode=no \ | |
| -o PreferredAuthentications=password \ | |
| -o PubkeyAuthentication=no \ | |
| -o ConnectTimeout=2 \ | |
| -p 2223 testuser@127.0.0.1 'true' 2>/dev/null; then | |
| echo "Password fixture SSH ready after $((i * 2))s" | |
| exit 0 | |
| fi | |
| echo "Waiting for password fixture SSH... ($i/20)" | |
| sleep 2 | |
| done | |
| echo "Password fixture did not come up within 40s; dumping logs" >&2 | |
| docker logs aeroftp-delta-sync-fixture-password >&2 || true | |
| exit 1 | |
| - name: Offline hard-rejection contract | |
| working-directory: src-tauri | |
| # Non-ignored offline pins: no fixture needed but we run them | |
| # here too so a change that breaks the string contract without | |
| # touching the key-auth lane's paths is still caught. | |
| run: | | |
| cargo test --test integration_delta_sync -- \ | |
| hard_rejection_string_contract_is_pinned_offline \ | |
| hard_error_branch_runs_before_classic_fallback_in_bivio \ | |
| --nocapture | |
| - name: "Fallback integration test: password-only fixture" | |
| working-directory: src-tauri | |
| run: | | |
| cargo test --test integration_delta_sync -- \ | |
| --ignored \ | |
| product_path_falls_through_silently_when_session_not_eligible \ | |
| --nocapture | |
| - name: Dump fixture logs on failure | |
| if: failure() | |
| working-directory: src-tauri/tests/fixtures/sftp-rsync | |
| run: | | |
| docker logs aeroftp-delta-sync-fixture-password || true | |
| docker compose -f docker-compose.password.yml ps | |
| - name: Teardown fixture | |
| if: always() | |
| working-directory: src-tauri/tests/fixtures/sftp-rsync | |
| run: docker compose -f docker-compose.password.yml down -v | |
| windows-native: | |
| # PR-T11: validate the cross-OS surgical gate on Windows. | |
| # Since v3.6.1 `aerorsync` is in the default feature set, | |
| # so the "default features" matrix entry is the same as | |
| # "--features aerorsync". The two meaningful matrix entries | |
| # are now: | |
| # - default (native prototype on): the shipping configuration | |
| # - `--no-default-features`: the classic-only fallback path; on | |
| # Windows this must compile to a `delta_transport() -> None` | |
| # surface so the consumer drops silently to plain SFTP. | |
| # No live fixture on Windows: the CI image cannot reach a Linux rsync | |
| # server and the native prototype's live probe is covered by the | |
| # aerorsync-protocol.yml lane against the Linux fixture. | |
| name: Windows cross-OS build + native unit tests | |
| runs-on: windows-latest | |
| # `windows-latest` is slower than ubuntu-latest by ~2x for MSVC | |
| # link steps on the large lib target; the single-config run used | |
| # to fit in 20 min but the v3.6.1 default-feature change doubled | |
| # the amount of code the test binary pulls in. 40 min is the new | |
| # comfortable ceiling; will be tightened again after pipeline | |
| # caching stabilises across a few more runs. | |
| timeout-minutes: 40 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 | |
| - name: Install Rust (stable, msvc) | |
| uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable | |
| with: | |
| toolchain: stable | |
| targets: x86_64-pc-windows-msvc | |
| - name: Rust cache | |
| uses: swatinem/rust-cache@c19371144df3bb44fab255c43d04cbc2ab54d1c4 # v2 | |
| with: | |
| workspaces: './src-tauri -> target' | |
| shared-key: delta-sync-windows | |
| # Compile-surface gate for the classic-only fallback path: | |
| # `--no-default-features` turns `aerorsync` off, and on | |
| # Windows the binary-rsync transport is also gated out. The only | |
| # thing that should survive on this path is | |
| # `SftpProvider::delta_transport() -> None`, which the consumer | |
| # treats as "drop to plain SFTP silently". Regression here means | |
| # the surgical `#[cfg(unix)]` gate has leaked a Unix-only symbol | |
| # back into the cross-OS surface. | |
| - name: cargo check (--no-default-features, classic-only fallback) | |
| working-directory: src-tauri | |
| run: cargo check --locked --no-default-features | |
| # Compile-surface gate for the shipping configuration (default | |
| # features, which include `aerorsync`). This confirms | |
| # the native rsync driver, the type layer | |
| # (`RsyncCapability`/`RsyncConfig`/`RsyncError`/`RsyncStats`), | |
| # the cross-platform adapter, and `SftpProvider::delta_transport()` | |
| # all build cleanly under MSVC with the feature on. | |
| - name: "cargo check (default features: shipping configuration)" | |
| working-directory: src-tauri | |
| run: cargo check --locked --all-targets | |
| # Note on the test binary: a full `cargo test --lib` on Windows | |
| # requires the whole lib-test link closure, which pulls in | |
| # `whisper-rs-sys` (STT for Linux/Windows, excluded on macOS). | |
| # `whisper-rs-sys` link-time symbols against the MSVC import | |
| # library stubs (`__imp_rand`, `__imp__aligned_malloc`, | |
| # `__imp_expm1f`, `__imp_fmaxf`, `__imp_erff`, etc.) do not | |
| # resolve cleanly in the `cargo test` profile today (a known | |
| # issue with the vendored ggml sources' CRT import descriptors | |
| # under recent MSVC toolchains). The cross-platform unit tests | |
| # we actually care about for PR-T11 (delta_sync_rsync | |
| # eligibility probes, rsync_output parsing, native prototype | |
| # encoders, ndx round-trips) are executed by the | |
| # aerorsync-protocol.yml lane and by the Linux integration | |
| # job above. Adding a Windows-side test runner is tracked as a | |
| # follow-up to harden whisper-rs-sys MSVC linkage separately | |
| # from the release gate. |