feat(deploy): preserve app data on --native when signing key matches#23
Merged
Conversation
adb_install_all ran an unconditional 'adb uninstall' before 'adb install', wiping MOB_DATA_DIR (on-device identity, screen stores) on every native deploy — even an in-place update signed with the same committed debug keystore. Try 'adb install -r' first (preserves data when signatures match) and only fall back to uninstall+install when the in-place update is genuinely rejected (INSTALL_FAILED_UPDATE_INCOMPATIBLE, INSTALL_FAILED_VERSION_DOWNGRADE, ...). Decision extracted to NativeBuild.needs_clean_reinstall?/2 and unit-tested. Verified empirically: on the same device, 'mix mob.deploy --native' wiped the seeded identity while a manual 'adb install -r' of the same keystore-signed APK preserved it (firstInstallTime unchanged) — confirming the uninstall, not a signature mismatch, was the cause. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The fallback printed "In-place update rejected — reinstalling clean (app data will be cleared)" for any `install -r` failure, including a transient adb error (e.g. device offline) where nothing is rejected and the follow-up uninstall+install just re-fails without clearing data. Split the notice: only a genuine package-state rejection (an INSTALL_FAILED line, i.e. signature/version mismatch) claims app data will be cleared; a non-zero exit without INSTALL_FAILED reports the adb exit code and "retrying with a clean install". Also drops the em-dash from user-facing output. Behaviour is unchanged; wording only. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
mix mob.deploy --nativewiped on-device app data —MOB_DATA_DIR(the app'sidentity, built-screen stores, anything in
files/) — on every nativedeploy.
adb_install_all/3ran an unconditionaladb uninstall <pkg>beforeadb install <apk>, so even an in-place update of an APK signed with the samekey (e.g. a committed debug keystore pinned precisely to avoid this) lost its data.
This makes a stable on-device identity impossible across
--nativeredeploys: acommitted keystore stabilizes beam-only
mix mob.deploy, but the native paththrew the data away regardless.
Root cause (verified empirically)
On one device, same keystore-signed APK:
mix mob.deploy --nativefirstInstallTimereset)adb install -r <apk>firstInstallTimeunchanged)So
install -rworks fine — the explicituninstallwas the cause, not anysignature mismatch.
Fix
adb_install_all/3now attemptsadb install -rfirst (an in-place update thatpreserves data when the signing key matches) and only falls back to
uninstall+installwhen the in-place update is genuinely rejected — anon-zero exit or an
INSTALL_FAILED_*line (INSTALL_FAILED_UPDATE_INCOMPATIBLEfor a real signature change,
INSTALL_FAILED_VERSION_DOWNGRADE, etc.). When itdoes fall back, it logs that app data will be cleared.
This strictly improves on the old behavior (which always uninstalled): the
fallback path is identical, it's just no longer the default.
The decision is a pure helper,
NativeBuild.needs_clean_reinstall?/2, unit-testedfor the success / signature-mismatch / downgrade / non-zero-exit cases.
Tests
test/mob_dev/native_build_test.exs— 4 new cases; full file156 passed.Pre-push (format + credo + suite) green.
Docs
CHANGELOG.md[Unreleased] → Changed, so users can track the behavior change.🤖 Generated with Claude Code