Uh oh!
There was an error while loading. Please reload this page.
[FastDeploy2] Clean orphan staging files - #12310
Conversation
There was a problem hiding this comment.
Pull request overview
This PR adds a FastDeploy2 “cold deploy” maintenance step to clean up orphaned on-device staging directories under /data/local/tmp/fastdeploy2/<package>/<user> when the corresponding package is no longer installed, with rate limiting and a safety window. It also wires a private MSBuild escape hatch to skip the cleanup, adds a unit test for the generated shell command, and documents command/tool compatibility expectations.
Changes:
- Implement orphan staging cleanup shell command generation and invoke it on the cold deployment path (rate-limited, safety-window guarded).
- Add
$(_AndroidFastDeploySkipCleanup)→FastDeploySkipCleanuptask wiring as an internal escape hatch. - Add a unit test for the cleanup command structure and extend FastDeploy2 documentation (including command compatibility notes).
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/DebuggingTasksTests.cs | Adds a unit test validating key fragments/order of the generated cleanup command. |
| src/Xamarin.Android.Build.Debugging.Tasks/Xamarin.Android.Common.Debugging.targets | Passes the new MSBuild property into the FastDeploy2 task invocation. |
| src/Xamarin.Android.Build.Debugging.Tasks/Tasks/FastDeploy2.Manifest.cs | Adds cleanup command generation + execution helper (adb shell) for orphan staging directories. |
| src/Xamarin.Android.Build.Debugging.Tasks/Tasks/FastDeploy2.cs | Adds the FastDeploySkipCleanup task property and runs cleanup only on the cold path. |
| Documentation/guides/FastDeploy2.md | Documents the new escape hatch, the cleanup behavior, and command compatibility expectations. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
jonathanpeppers
commented
Aug 7, 2026
/review |
✅ Android PR Reviewer completed successfully! |
There was a problem hiding this comment.
Reviewed the full diff and surrounding implementation. I found no correctness or safety defects in the fail-closed cleanup logic. I left one non-blocking test-coverage suggestion for the production safety guards.
CI is still in progress: 29 of 44 checks have completed successfully, 14 are running, and the aggregate check remains queued; no failures are currently reported.
Generated by Android PR Reviewer for #12310 · gpt56 · 132.7 AIC · ⌖ 10.1 AIC · ⊞ 25.3K
Comment /review to run again
Uh oh!
There was an error while loading. Please reload this page.
1fdb3e6 to
232973bCompare
simonrozsival
left a comment
There was a problem hiding this comment.
I think this is a practical solution to the cleanup problem right now and we can later consider improving it based on customer feedback.
232973b to
57f48ffComparejonathanpeppers
commented
Aug 19, 2026
/review |
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
Found one correctness warning and one test-coverage suggestion. The package lookup and grep handling are otherwise appropriately fail-closed, and cleanup is correctly restricted to successful APK-install paths rather than managed-only incremental deployments.
CI is still in progress: the visible completed checks are passing, six jobs are running, and the aggregate dotnet-android check is queued; no failure is currently reported.
Generated by Android PR Reviewer for #12310 · gpt56 · 152.2 AIC · ⌖ 20.1 AIC · ⊞ 25.6K
Comment /review to run again
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
57f48ff to
33eb388Comparejonathanpeppers
commented
Aug 19, 2026
/review |
✅ Android PR Reviewer completed successfully!
|
There was a problem hiding this comment.
Verdict: ✅ LGTM pending CI completion — no blocking correctness or safety issues found. I left 1 💡 testing suggestion for the destructive command's fail-closed branches.
The package matching is exact, ambiguous command results avoid deletion, installed-package staging is preserved, and cleanup is correctly limited to successful APK-install paths. At the latest CI snapshot, 39 checks had completed successfully, two were still running, and the aggregate check was queued; no failures were reported.
Generated by Android PR Reviewer for #12310 · gpt56 · 161.5 AIC · ⌖ 8.93 AIC · ⊞ 25.7K
Comment /review to run again
Uh oh!
There was an error while loading. Please reload this page.
33eb388 to
4247f17Comparejonathanpeppers
commented
Aug 20, 2026
@dalexsoto review |
dalexsoto
left a comment
There was a problem hiding this comment.
Three destructive-cleanup blockers remain:
- The two-level staging glob follows a symlinked root or package directory, allowing
rm -rf "$d"to delete a numeric directory outside/data/local/tmp/fastdeploy2(reproduced with the exact command). - Any nonempty
pmstdout with status 0 is trusted as a complete package list; supported Android versions can print server-error diagnostics while returning 0, causing every package lookup to look absent and permitting delete-all. - The once-per-user package snapshot races concurrent uninstall/reinstall/deploy flows, so cleanup can delete staging after the package has become installed and is being reused.
Please enforce no-follow/root confinement immediately before deletion, validate package output as package records, and coordinate/revalidate candidates against concurrent deployments.
Remove staging directories for packages that are no longer installed after APK installation, while keeping managed-only incremental deployments on the fast path. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 80e378d0-3374-44f9-9b1c-692ac97297a7
4247f17 to
08921ceComparejonathanpeppers
commented
Aug 20, 2026
Addressed the two reproduced cleanup safety issues in 08921ce:
I intentionally did not add deployment locking or concurrency coordination here. That is a separate deployment-lifecycle concern and would be scope creep for this cleanup PR. |
Uh oh!
There was an error while loading. Please reload this page.
Summary
/data/local/tmp/fastdeploy2/<package>/<user>staging directories when the package is definitely no longer installed for that Android userpmoutput, and ambiguousgrepresults$(_AndroidFastDeployMaxShellCommandLength)$(_AndroidFastDeploySkipCleanup)as an escape hatchMSBuildDeviceIntegrationtest covering orphan deletion, installed-package retention, symlink confinement, and cleanup skipping on a managed-only incremental deploymentValidation
Xamarin.Android.Build.Debugging.Tasks.csprojXamarin.Android.Common.Debugging.targetsas XMLThe full device integration test requires the repository's .NET 11 local SDK, which is not available in this worktree.