* docs: integration tests design proposal
Adds docs/integration_tests.md proposing a desktop-only integration suite
that drives the Dart `ShorebirdUpdater` API against the real Rust core via
FFI, with a fake HTTP server and per-test tempdir state. Describes a new
`library_test_hooks` cdylib that reaches into `updater` via a `test-hooks`
Cargo feature, so production C API stays clean. Status: design exploration,
not a committed plan.
* feat: stage 1 integration test harness for shorebird_code_push
Lands the test_hooks crate, the Dart-side loader, and one trivial
end-to-end test, per docs/integration_tests.md stage 1.
Pieces:
- New `library_test_hooks` workspace crate (cdylib). Depends on `updater`
with a new `test-hooks` Cargo feature that widens the visibility of
internal items (currently `testing_reset_config`) for sibling-crate
access only — production builds do not enable it. The crate also
re-exports `updater::c_api::dart::*` and `updater::c_api::engine::*`,
which keeps the rlib's `#[no_mangle]` symbols out of DCE so the
resulting cdylib carries both the production C API and the new
`shorebird_test_*` hooks.
- Workspace `default-members` excludes `library_test_hooks` so plain
`cargo build` / `cargo test` invocations don't unify the `test-hooks`
feature into production builds.
- `shorebird_code_push/test/integration/all_test.dart` (single file,
with a header comment explaining why) loads the cdylib via
`DynamicLibrary.open`, reassigns the existing `@visibleForTesting`
`Updater.bindings` setter, and exercises both surfaces. The build
helper shells out to `cargo build -p library_test_hooks`; if it
fails, `markTestSkipped` keeps the suite green on machines without
a working Rust toolchain.
- ffigen config (`ffigen_test_hooks.yaml`) generates the test-only
Dart bindings under `test/integration/generated/`, not `lib/`.
- CI: `library_test_hooks` is added to the rust_crate matrix, and the
shorebird_code_push job triggers on `library/**` and
`library_test_hooks/**` so cdylib changes can't break the Dart-side
integration suite without CI noticing.
Verified locally: 232 Rust unit tests + 42 Dart tests (41 existing + 1
integration) green; clippy/fmt/cspell clean; production cdylib does
not contain `shorebird_test_reset` (`nm` confirms feature isolation).
Stages 2 (FakePatchServer + golden path) and 3 (adversarial scenarios)
land separately.
* fix(integration test): early-return on skip and bump per-test timeout
Two issues caught by Shorebird CI on PR #353:
1. `markTestSkipped` does not abort test execution — it only flags the
test as skipped on its way out. The body kept running and crashed on
the `late testHooks` field when the cdylib build had failed in
setUpAll. Move the skip check into the test body itself with an
early return; drop the (no-op) skip in `setUp`.
2. Default per-test timeout (30s) also covers `setUpAll`. A cold
`cargo build -p library_test_hooks` compiles `updater` and ~100
transitive deps, which can run minutes on CI. Bump to 10 minutes
via `@Timeout` on the library.
Verified locally: passes when cargo is on PATH (1 passed), reports a
clean skip and exit 0 when cargo is removed from PATH (1 skipped).
* refactor(integration test): drop ! by promoting testHooks to late final
`testHooks` was nullable so accessing it after the skipReason check
required `!`, and `markTestSkipped(skipReason!)` had the same smell.
Make `testHooks` `late final` (non-nullable, throws if read before
setUpAll assigns) and pull `skipReason` into a non-null local before
use. Same control flow, no bang operators.
* ci: speed up Rust CI builds with caching and prebuilt tools
The Windows builder takes ~6min vs ~3min on Ubuntu, largely because
cargo-llvm-cov is compiled from source on every run. This adds
Swatinem/rust-cache for build artifact caching and switches to
taiki-e/install-action for prebuilt cargo-llvm-cov binaries.
Also fixes the undefined `inputs.shell` references by hardcoding `bash`.
* fix: add Swatinem and taiki to cspell dictionary
* ci: remove rust-cache, no measurable benefit for this project
Investigated cache hit/miss across 3 CI runs. Even with warm cache
hits (macOS/Windows), build times were unchanged or slightly slower
due to cache download/extract overhead (~39MB) outweighing the small
dependency compile time savings.
* ci: remove redundant cargo build step
Clippy already compiles all targets, so the explicit cargo build step
was redundant. The test step (cargo llvm-cov) also does its own
instrumented build, so nothing depended on the build step's artifacts.
* ci: try larger Windows runner for faster Rust builds
Switch from windows-latest (4 vCPU) to windows-latest-large (8 vCPU)
to see if the extra cores meaningfully speed up Rust compilation.
Windows builds currently take ~2x longer than macOS/Ubuntu.
* ci: use Namespace Windows runner (8 vCPU) instead of GitHub-hosted
Switch to nscloud-windows-2022-amd64-8x16 to test whether doubling
the cores from 4 to 8 meaningfully speeds up Rust compilation on
Windows, which currently takes ~2x longer than macOS/Ubuntu.
* fix: add nscloud to cspell dictionary
* fix: make tests pass on Windows
* Run ci on all supported building OSes
* Add os name to CI step
* Build rust crates on all oses
* tweak
* Only run rust on multiple oses for now
* chore: add cspell checking and make pass
* chore(shorebird_code_push): minor improvements to example (#242)
* chore(shorebird_code_push): v2.0.2 (#243)
* chore: fix cspell
---------
Co-authored-by: Felix Angelov <felix@shorebird.dev>