Commit Graph

134 Commits

Author SHA1 Message Date
Eric Seidel 2057fd4f46 fix: resolve all Dependabot security vulnerabilities (#316)
Run `cargo update` to bump transitive dependencies, fixing 10 of 11
alerts (h2, ring, idna, mio, tokio, bytes, time, quinn-proto,
rustls-webpki, unsafe-libyaml).

Replace deprecated `tempdir` dev-dependency with `tempfile` to
eliminate the `remove_dir_all` vulnerability (the last alert).
2026-04-01 15:36:12 +00:00
Eric Seidel c6647a2dfe refactor: replace reqwest with ureq to reduce binary size (#317)
* refactor: replace reqwest with ureq to reduce binary size

reqwest's blocking API is built on top of its async implementation,
pulling in tokio, hyper, futures, and ~84 other transitive dependencies
even though we only make simple synchronous HTTP calls.

ureq is a synchronous-only HTTP client that eliminates the async
runtime entirely. This reduces transitive dependencies from 227 to 143
and the linked dylib from 4.5 MB to 3.7 MB (-18%). The .a archive
drops from 28 MB to 26 MB, but real savings will be larger once
linked into libflutter with dead code stripping.

The network API surface is unchanged — three functions (patch check,
file download, event reporting) using POST/GET with JSON.

* chore: add ureq to spell check dictionary

* refactor: use into_body() instead of body_mut() where response is consumed

* fix: simplify network error matching to avoid fragile string checks

Consolidate HostNotFound, ConnectionFailed, and all Io errors into
a single network-error arm instead of pattern-matching on error
message strings that could change across OS versions or locales.

* chore: add TODO for misleading network error message
2026-04-01 08:23:48 -07:00
Eric Seidel 4ff2839cdb feat: add tests and docs for boot state machine (#309)
* test: test api calls

* chore: add docs

* chore: fix cspell

* fix: use no-op network hooks in multi_engine tests

Set no-op network hooks after init_for_testing so the fire-and-forget
thread spawned by report_launch_success completes instantly without
network I/O, preventing leaked threads from interfering with subsequent
serial tests that use mock servers.
2026-03-30 23:01:50 +00:00
Eric Seidel 6d0e4a1193 chore(deps): bump Rust and Dart dependencies (#315)
* chore(deps): bump Rust and Dart dependencies

Bump Rust dependencies in library/ and patch/:
- comde: 0.2.3 → 0.3.1 (library), 0.2.3 → 0.3.0 (patch)
- zip: 0.6.4 → 3.0.0 (breaking: FileOptions → SimpleFileOptions)
- android_logger: 0.13.0 → 0.15.0
- mockall: 0.12.1 → 0.13.1
- serial_test: 2.0.0 → 3.2.0
- cbindgen: 0.24.0 → 0.28.0

Bump Dart dev dependency in shorebird_code_push/:
- ffigen: upper bound <17.0.0 → <19.0.0

Updated zip API usage (FileOptions → SimpleFileOptions) and
adjusted test assertion for changed error message.

Binary size impact (macOS release, arm64):
- libupdater.a: +83 KB (+0.28%)
- libupdater.dylib: +34 KB (+0.75%)

Closes #206, #271, #273.

* chore: add EOCD to cspell dictionary

The zip 3.0 crate changed its error message to reference "EOCD"
(End of Central Directory), which cspell doesn't recognize.
2026-03-30 15:50:44 -07:00
Eric Seidel ed8cea1463 fix: improve inflate error handling and validate compressed patches (#314)
* fix: improve inflate error handling and validate compressed patches

Addresses #2989: "pipe reader has been dropped" / "failed to fill whole
buffer" errors during patch inflation were masking the real root cause.

Three changes:

1. Join the decompression thread and propagate its error as the primary
   failure, rather than fire-and-forget logging. The patching thread's
   broken-pipe error is a side-effect, not the cause. Also drop the pipe
   reader before joining to avoid deadlock when patching fails.

2. Validate the downloaded compressed patch (non-empty, valid zstd magic
   bytes) before attempting decompression, so corrupt/truncated downloads
   produce a clear error instead of cryptic pipe errors.

3. Log the download size in download_to_path to help diagnose truncated
   downloads in the field.

* docs: expand comment on drop(fresh_r) to clarify deadlock risk

* feat: log app_id, patch number, and version before download

* test: add inflate tests for corrupt data and invalid magic

* test: cover decompression-error-as-primary-cause path in inflate

Uses a valid zstd frame followed by a corrupt second frame so that
bipatch::Reader::new succeeds but decompression fails midway, verifying
that the decompression error is reported as the primary cause.
2026-03-27 12:54:00 -07:00
Brandon DeRosier eeec42efb7 feat: add enhanced error messages for file operations (#310)
* feat: add enhanced error messages for file operations

Add a file_errors module that provides context-aware error messages
for file operations. When file operations fail, users now see:
- The specific operation that failed (create, read, write, rename, etc.)
- The full path involved
- Helpful hints about possible causes based on error type
- Android-specific hints for permission errors (SELinux, Work Profile,
  MDM/Knox policies, app cloning features)

This helps diagnose issues like "Permission denied (os error 13)" by
indicating which operation failed and suggesting possible causes.
2026-02-04 12:36:39 -08:00
Eric Seidel 08fb9df932 fix: Rare bug if rollback happens during second update call
The scenario is:

1. User is running patch 2 (booted successfully, so last_booted_patch = 2)
2. While the app is still running, they call the check-for-update API
3. Patch 3 is downloaded and installed (next_boot_patch = 3)
4. Before the app restarts, they check again and patch 4 is available
5. The buggy code is supposed to delete patch 3 (never booted), but instead deletes patch 2 (the last known-good patch)
6. Patch 4 is set as next_boot_patch

If patch 4 boots fine, nobody notices. But if patch 4 fails to boot and the system tries to roll back to patch 2, those artifacts are gone.
2026-01-29 10:18:14 -08:00
Eric Seidel 8691c8f60e feat: add verification_mode config option (#308)
* feat: move patch verification from boot time to install time

* feat: make it switchable

* chore: update comments

* fix: test invalid yaml

* chore: update readme

* feat: add more comments to readme

* doc: more readme updates

* chore: rename to patch_verification
2026-01-11 15:04:59 -08:00
Bryan Oltman 9db198a634 fix: checking for update should not overwrite good next patch (#307)
* chore: remove unnecessary mutability of self in next_boot_patch

* fix: checking for update should not overwrite good next patch
2025-12-19 13:18:08 -05:00
Bryan Oltman 58a5bcc0b0 chore: remove unnecessary mutability of self in next_boot_patch (#305) 2025-12-19 10:02:33 -05:00
Bryan Oltman 76f005940d feat: add uuid to updater state, patch check request (#300)
* feat: add uuid to updater state

* add client_id to patch check request

* cleanup

* comments

* cleanup

* more comments

* delete commented-out code

* Update library/src/cache/updater_state.rs

Co-authored-by: Eric Seidel <eric@shorebird.dev>

* formatting

---------

Co-authored-by: Eric Seidel <eric@shorebird.dev>
2025-10-29 15:57:06 -04:00
Bryan Oltman 8bfe1bac47 fix: separate validation checks from next_boot_patch getter (#297)
* fix: separate validation checks from next_boot_patch getter

* coverage

* coverage

* coverage
2025-10-08 17:55:29 -04:00
Bryan Oltman ab23721e35 fix: roll back patches in check_for_downloadable_update (#270)
* fix: roll back patches in check_for_downloadable_update

* Update docs
2025-02-12 20:29:06 +00:00
Bryan Oltman 78c84e5bf7 chore: more logging 2025-02-07 14:18:03 -05:00
Bryan Oltman 67f8643242 chore: add more info-level logging around patch downloads (#267) 2025-02-07 14:07:19 -05:00
Bryan Oltman a4a7255796 feat: configure logging on linux (#263) 2025-01-28 10:28:48 -05:00
Bryan Oltman 69468a0c9f fix multiple definitions of patch_base 2025-01-24 15:00:09 -05:00
Bryan Oltman 707346df33 fix multiple definitions of patch_base 2025-01-24 14:55:41 -05:00
Bryan Oltman ba52a62b5d feat: change updater to support intel macs (#262)
* feat: change updater to support intel macs

* cleanup

* Fix targeting in patch_base function
2025-01-24 13:58:30 -05:00
Bryan Oltman 71b5ed65fa feat: add windows support (#259)
* feat: add windows support

* Cleanup
2024-12-20 14:35:28 -08:00
Felix Angelov 54e1e2ce2f fix(updater): re-export shorebird_check_for_update for backward compat (#258) 2024-12-19 15:51:07 -06:00
Bryan Oltman 38aadee1c5 feat: enable updater logging on windows (#256) 2024-12-18 14:10:37 -08:00
Bryan Oltman a6c761f50f fix: build updater with static runtime to prevent flutter engine build linking errors (#254)
* fix: build updater with static runtime to prevent flutter engine build linking errors

* Update library/.cargo/config.toml

Co-authored-by: Eric Seidel <eric@shorebird.dev>

* cspell

---------

Co-authored-by: Eric Seidel <eric@shorebird.dev>
2024-12-17 21:34:20 +00:00
Bryan Oltman 1e4efce65f fix: make tests pass on Windows (#252)
* 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
2024-12-11 12:09:04 -05:00
Bryan Oltman b4775d30dd feat: support macOS (#247)
* feat: support macOS

* fix tests
2024-12-05 17:53:45 -05:00
Eric Seidel 6298d37d86 chore: add cspell checking and make pass (#244)
* 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>
2024-11-20 13:50:16 -05:00
Felix Angelov ee3f5ec669 feat(shorebird_code_push): track support (#232)
* feat(shorebird_code_push): track support

* cleanup and add todos

* docs

* run ffigen

* use c_char instead of char

* Add channel support

* tests

* tests

* update podfile.lock

* Update example to include tracks selector

---------

Co-authored-by: Bryan Oltman <bryan@shorebird.dev>
Co-authored-by: Bryan Oltman <bryanoltman@gmail.com>
2024-11-12 14:58:50 -05:00
Bryan Oltman c06b5df4e9 fix: reset patches when updater state fails to deserialize (#233)
* fix: reset patches when updater state fails to deserialize

* cleanup
2024-11-08 22:10:30 +00:00
Bryan Oltman 0988c854af Revert "feat: generate a rollout group number on UpdaterState creation (#227)" (#231)
This reverts commit 8e7ec5a9b6.
2024-11-07 09:34:32 -05:00
Felix Angelov 6f1be35bd3 feat(shorebird_code_push): rewrite Dart API (#225) 2024-11-04 12:22:37 -06:00
Bryan Oltman 8e7ec5a9b6 feat: generate a rollout group number on UpdaterState creation (#227)
* feat: generate a rollout group number on UpdaterState creation

* update test

* use inclusive range
2024-10-30 17:40:46 -04:00
Bryan Oltman 5ace5b84f5 chore: improve logging (#226) 2024-10-30 12:33:02 -04:00
Bryan Oltman 9294c545e8 feat: prepend all log messages with "[shorebird]" (#221)
* feat: prepend all log messages with "[shorebird]"

* update doc

* PR feedback
2024-10-30 11:53:20 -04:00
Bryan Oltman b2d5eced03 feat: add message to patch event (#210) 2024-08-30 17:03:43 +00:00
Bryan Oltman e4e4c57b59 chore: log when reporting successful launch (#209) 2024-08-30 16:30:38 +00:00
Bryan Oltman bec79a4f8d fix: update current_boot_patch to always return currently running patch (#202)
* fix: don't return true from isNewPatchAvailableForDownload if the new patch will not be installed

* fix: update current_boot_patch to always return currently running patch

* add C api tests

* add extra test check
2024-07-25 21:13:58 +00:00
Bryan Oltman 7c559c0915 fix: don't return true from isNewPatchAvailableForDownload if the new patch will not be installed (#201) 2024-07-25 16:50:55 -04:00
Bryan Oltman 75de37ccb3 feat: report patch downloads (#195)
* feat: add rollback support

* Cleanup

* add test

* docs and cleanup

* feat: report patch downloads
2024-07-23 13:53:53 -04:00
Bryan Oltman 9ab417882c refactor: make patch_check_request a constructor (#196) 2024-07-23 13:48:43 -04:00
Bryan Oltman a9fa67c95a feat: add rollback support (#194)
* feat: add rollback support

* Cleanup

* add test

* docs and cleanup

* log full PatchCheckResponse

* remove unnecessary file permission spec from test helper
2024-07-23 10:41:01 -04:00
Bryan Oltman 6ba524716c fix: report launch failure when a patch was in the process of booting on app start (#189)
* report launch failure when a patch was in the process of booting on app start

* refactor: extract shared fake patch test logic into function

* cleanup

* remove commented-out code

* cleanup

* Cleanup

* cleanup

* rename

* update comments

* add todo

* remove added logs

* update comments

* make patch_event a proper constructor

* Split with_mut_state out from with_state

* update comment

* feat: track known_bad_patches instead of highest_seen_patch to support rollbacks (#191)

* feat: track known_bad_patches instead of highest_seen_patch to support rollbacks

* docs

* do not send patch number, do not install already installed patches

* remove patch number from PatchCheckRequest

* tests

* more tests

* fix merge issues
2024-07-19 17:41:04 -04:00
Bryan Oltman 6c36ab68b9 refactor: extract shared fake patch test logic into function (#190)
* refactor: extract shared fake patch test logic into function

* cleanup
2024-07-17 12:50:09 -04:00
Bryan Oltman 3073a76dbc refactor: only check whether a patch failed to boot on initialization (#186)
* fix: track patches while they are booting

* update comment

* update comment

* add test

* refactor: only check whether a patch failed to boot on initialization

* fix test
2024-07-16 16:39:53 -04:00
Bryan Oltman a18b90f01c fix: track patches while they are booting (#185)
* fix: track patches while they are booting

* update comment

* update comment

* add test

* only init UpdaterState if set_config succeeds

* pr feedback

* cleanup

* pr feedback

* add todo referencing github bug re: patch install failure events

* document lifetime of currently_booting_patch

* more details about on_init lifetime

* add todo re: validation

* update test comments

* update test to regenerate patch manager when simulating a fresh start

* Introduce InitError for better testing

* fix test

* add extra assert in PatchManager on_init_tests
2024-07-16 15:23:02 -04:00
Bryan Oltman 3cae153d11 refactor: remove duplicated sent_patch_check_request code (#182)
* refactor: remove duplicated sent_patch_check_request code

* maintain debug log
2024-07-12 17:16:40 -04:00
Bryan Oltman 3da6c38ef4 feat: add timestamp to patch events (#179)
* feat: add timestamp to patch events

* fix test
2024-06-20 15:47:59 -04:00
Bryan Oltman 349f4236b3 chore: add error log when patch signature is invalid 2024-05-28 11:14:31 -04:00
Bryan Oltman 390aa49cba feat: update patch manager to check signature on boot (#171)
* feat: store patch signature on disk with patch metadata

* add note about explicit lifetime

* fix tests

* feat: update patch manager to check signature on boot

* remove unused imports

* fix tests

* add log when no public key detected

* clean up log message

* pr feedback

* rename test

* rename tests null -> none

* change signature field name to hash_signature

* Add comment

* update print statements for clearer device logs

* fix test

* improve docs

* cleanup of signing error handling
2024-05-23 14:41:02 -04:00
Bryan Oltman 4685789e59 feat: store patch signature on disk with patch metadata (#170)
* feat: store patch signature on disk with patch metadata

* add note about explicit lifetime

* fix tests
2024-05-22 10:00:36 -04:00
Bryan Oltman 5de07bb48a feat: store patch hash on disk (#169) 2024-05-21 14:38:37 -04:00