Skip to content

Commit cd88d9c

Browse files
[xabt] Implement DeployToDevice target (#10631)
Context: https://github.com/dotnet/sdk/blob/c164a9bc1246c48191fb780992530f0fe975141b/documentation/specs/dotnet-run-for-maui.md Implements the `DeployToDevice` MSBuild target per the `dotnet run` spec for .NET MAUI scenarios. This target allows deploying an already-built app to a device without rebuilding, supporting the `dotnet run` workflow. The target reuses existing deployment logic but skips the full build, enabling faster iteration when only deployment is needed e.g. `--no-build`. Also consolidates `$(SignAndroidPackageDependsOn)`, `$(InstallDependsOnTargets)`, and `$(UninstallDependsOnTargets)` properties into `BuildOrder.targets` to keep all target dependency ordering in one place. Adds test coverage to verify the target deploys successfully and the app can be launched via adb commands.
1 parent 384f7f2 commit cd88d9c

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed

src/Xamarin.Android.Build.Tasks/Microsoft.Android.Sdk/targets/Microsoft.Android.Sdk.BuildOrder.targets

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,48 @@ properties that determine build ordering.
9494
</_PrepareBuildApkDependsOnTargets>
9595
</PropertyGroup>
9696

97+
<PropertyGroup>
98+
<InstallDependsOnTargets>
99+
SignAndroidPackage;
100+
_DeployApk;
101+
_DeployAppBundle;
102+
</InstallDependsOnTargets>
103+
<UninstallDependsOnTargets>
104+
AndroidPrepareForBuild;
105+
_Uninstall
106+
</UninstallDependsOnTargets>
107+
<!-- When inside an IDE, Build has just been run. This is a minimal list of targets for SignAndroidPackage. -->
108+
<_MinimalSignAndroidPackageDependsOn>
109+
BuildOnlySettings;
110+
_CreatePropertiesCache;
111+
ResolveReferences;
112+
PrepareResources;
113+
CreateSatelliteAssemblies;
114+
_CopyPackage;
115+
_Sign;
116+
_CreateUniversalApkFromBundle;
117+
</_MinimalSignAndroidPackageDependsOn>
118+
<SignAndroidPackageDependsOn Condition=" '$(BuildingInsideVisualStudio)' != 'true' ">
119+
Build;
120+
Package;
121+
_Sign;
122+
_CreateUniversalApkFromBundle;
123+
</SignAndroidPackageDependsOn>
124+
<SignAndroidPackageDependsOn Condition=" '$(BuildingInsideVisualStudio)' == 'true' ">
125+
$(_MinimalSignAndroidPackageDependsOn);
126+
</SignAndroidPackageDependsOn>
127+
<!-- This should function similar to SignAndroidPackage inside VS plus also deploy -->
128+
<DeployToDeviceDependsOnTargets Condition=" '$(_XASupportsFastDev)' == 'true' ">
129+
$(_MinimalSignAndroidPackageDependsOn);
130+
_Upload;
131+
</DeployToDeviceDependsOnTargets>
132+
<DeployToDeviceDependsOnTargets Condition=" '$(_XASupportsFastDev)' != 'true' ">
133+
$(_MinimalSignAndroidPackageDependsOn);
134+
_DeployApk;
135+
_DeployAppBundle;
136+
</DeployToDeviceDependsOnTargets>
137+
</PropertyGroup>
138+
97139
<PropertyGroup Condition=" '$(AndroidApplication)' != 'True' ">
98140
<BuildDependsOn>
99141
$(_AndroidBuildDependsOn);

src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,28 +2800,10 @@ because xbuild doesn't support framework reference assemblies.
28002800
<UnzipToFolder Sources="$(_UniversalApkSetIntermediate)" DestinationDirectories="$(OutDir)" Files="@(_FilestoExtract)" />
28012801
</Target>
28022802

2803-
<PropertyGroup>
2804-
<SignAndroidPackageDependsOn Condition=" '$(BuildingInsideVisualStudio)' != 'True' ">
2805-
Build;
2806-
Package;
2807-
_Sign;
2808-
_CreateUniversalApkFromBundle;
2809-
</SignAndroidPackageDependsOn>
2810-
<!-- When inside an IDE, Build has just been run. This is a minimal list of targets for SignAndroidPackage. -->
2811-
<SignAndroidPackageDependsOn Condition=" '$(BuildingInsideVisualStudio)' == 'True' ">
2812-
BuildOnlySettings;
2813-
_CreatePropertiesCache;
2814-
ResolveReferences;
2815-
PrepareResources;
2816-
CreateSatelliteAssemblies;
2817-
_CopyPackage;
2818-
_Sign;
2819-
_CreateUniversalApkFromBundle;
2820-
</SignAndroidPackageDependsOn>
2821-
</PropertyGroup>
28222803
<Target Name="SignAndroidPackage" DependsOnTargets="$(SignAndroidPackageDependsOn)">
28232804
</Target>
28242805

2806+
<Target Name="DeployToDevice" DependsOnTargets="$(DeployToDeviceDependsOnTargets)" />
28252807

28262808
<!-- Callable targets -->
28272809
<PropertyGroup>
@@ -2938,18 +2920,6 @@ because xbuild doesn't support framework reference assemblies.
29382920
<WriteLinesToFile File="$(_LldbConfigFile)" Lines="MANIFEST=$(IntermediateOutputPath)android\AndroidManifest.xml"/>
29392921
</Target>
29402922

2941-
<PropertyGroup>
2942-
<InstallDependsOnTargets>
2943-
SignAndroidPackage;
2944-
_DeployApk;
2945-
_DeployAppBundle;
2946-
</InstallDependsOnTargets>
2947-
<UninstallDependsOnTargets>
2948-
AndroidPrepareForBuild;
2949-
_Uninstall
2950-
</UninstallDependsOnTargets>
2951-
</PropertyGroup>
2952-
29532923
<Target Name="_DeployApk"
29542924
Condition=" '$(AndroidPackageFormat)' != 'aab' ">
29552925
<AndroidAdb

tests/MSBuildDeviceIntegration/Tests/InstallAndRunTests.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,31 @@ public void DotNetRun (bool isRelease, string typemapImplementation)
5353
Assert.IsTrue (didLaunch, "Activity should have started.");
5454
}
5555

56+
[Test]
57+
[TestCase (true)]
58+
[TestCase (false)]
59+
public void DeployToDevice (bool isRelease)
60+
{
61+
var proj = new XamarinAndroidApplicationProject {
62+
IsRelease = isRelease
63+
};
64+
using var builder = CreateApkBuilder ();
65+
builder.Save (proj);
66+
67+
var dotnet = new DotNetCLI (Path.Combine (Root, builder.ProjectDirectory, proj.ProjectFilePath));
68+
Assert.IsTrue (dotnet.Build (), "`dotnet build` should succeed");
69+
Assert.IsTrue (dotnet.Build ("DeployToDevice"), "`dotnet build -t:DeployToDevice` should succeed");
70+
71+
// Launch the app using adb
72+
ClearAdbLogcat ();
73+
var result = AdbStartActivity ($"{proj.PackageName}/{proj.JavaPackageName}.MainActivity");
74+
Assert.IsTrue (result.Contains ("Starting: Intent"), $"Activity should have launched. adb output:\n{result}");
75+
76+
bool didLaunch = WaitForActivityToStart (proj.PackageName, "MainActivity",
77+
Path.Combine (Root, builder.ProjectDirectory, "logcat.log"), 30);
78+
Assert.IsTrue (didLaunch, "Activity should have started.");
79+
}
80+
5681
[Test]
5782
public void ActivityAliasRuns ([Values (true, false)] bool isRelease)
5883
{

0 commit comments

Comments
 (0)