diff --git a/Documentation/release-notes/fix-4677.md b/Documentation/release-notes/fix-4677.md new file mode 100644 index 00000000000..9a164bdc426 --- /dev/null +++ b/Documentation/release-notes/fix-4677.md @@ -0,0 +1,6 @@ +#### Application and library build and deployment + +- [GitHub 4677](https://github.com/xamarin/xamarin-android/issues/4677): + On Windows, the `InstallAndroidDependencies` MSBuild target would not yet + install the expected Android SDK Platform or Android SDK Build-Tools + components in a newly configured command line build environment. diff --git a/src/Xamarin.Android.Build.Tasks/Tasks/CalculateProjectDependencies.cs b/src/Xamarin.Android.Build.Tasks/Tasks/CalculateProjectDependencies.cs index a19c4e820ab..515a6fd12b6 100644 --- a/src/Xamarin.Android.Build.Tasks/Tasks/CalculateProjectDependencies.cs +++ b/src/Xamarin.Android.Build.Tasks/Tasks/CalculateProjectDependencies.cs @@ -53,8 +53,8 @@ public override bool RunTask () manifestApiLevel = manifest.TargetSdkVersion ?? manifest.MinSdkVersion ?? DefaultMinSDKVersion; } var sdkVersion = Math.Max (targetApiLevel.Value, manifestApiLevel); - dependencies.Add (CreateAndroidDependency ($"platforms/android-{sdkVersion}", $"")); - dependencies.Add (CreateAndroidDependency ($"build-tools/{BuildToolsVersion}", BuildToolsVersion)); + dependencies.Add (CreateAndroidDependency (Path.Combine ("platforms", $"android-{sdkVersion}"), $"")); + dependencies.Add (CreateAndroidDependency (Path.Combine ("build-tools", BuildToolsVersion), BuildToolsVersion)); if (!string.IsNullOrEmpty (PlatformToolsVersion)) { dependencies.Add (CreateAndroidDependency ("platform-tools", PlatformToolsVersion)); } diff --git a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs index 73c328815d9..dfed65a2eea 100644 --- a/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs +++ b/src/Xamarin.Android.Build.Tasks/Tests/Xamarin.Android.Build.Tests/AndroidDependenciesTests.cs @@ -1,5 +1,7 @@ using System; +using System.Collections.Generic; using System.IO; +using System.Linq; using NUnit.Framework; using Xamarin.ProjectTools; @@ -13,19 +15,42 @@ public class AndroidDependenciesTests : BaseTest [Test] public void InstallAndroidDependenciesTest () { + var path = Path.Combine (Root, "temp", TestName); + TestOutputDirectories [TestContext.CurrentContext.Test.ID] = path; if (!CommercialBuildAvailable) Assert.Ignore ("Not required on Open Source Builds"); var old = Environment.GetEnvironmentVariable ("ANDROID_SDK_PATH"); try { - string sdkPath = Path.Combine (Root, "temp", TestName, "android-sdk"); + string sdkPath = Path.Combine (path, "android-sdk"); + CreateFauxAndroidSdkDirectory (sdkPath, buildToolsVersion: "23.0.0"); + // Provide mock version info so the `tools` component won't be downloaded. + File.WriteAllText (Path.Combine (sdkPath, "tools", "source.properties"), "Pkg.Revision=99.99.99"); Environment.SetEnvironmentVariable ("ANDROID_SDK_PATH", sdkPath); var proj = new XamarinAndroidApplicationProject (); - using (var b = CreateApkBuilder ()) { + // Use `BuildHelper.CreateApkBuilder()` instead of `BaseTest.CreateApkBuilder()` so + // `android-sdk` can be placed beside the project directory rather than within it. + using (var b = BuildHelper.CreateApkBuilder (Path.Combine (path, "Project"))) { string defaultTarget = b.Target; b.Target = "InstallAndroidDependencies"; + b.ThrowOnBuildFailure = false; + Assert.IsFalse (b.Build (proj, parameters: new string [] { "AcceptAndroidSDKLicenses=false" }), "InstallAndroidDependencies should have failed."); + IEnumerable taskOutput = b.LastBuildOutput + .SkipWhile (x => !(x.StartsWith (" Detecting Android SDK in") && x.Contains (sdkPath))) + .TakeWhile (x => !x.StartsWith ("Done executing task \"InstallAndroidDependencies\"")) + .Where (x => x.StartsWith (" Dependency to be installed:")); + Assert.AreEqual (2, taskOutput.Count (), "Exactly two dependencies should be identified to be installed."); + StringAssertEx.Contains ("Dependency to be installed: Android SDK Platform", taskOutput); + StringAssertEx.Contains ("Dependency to be installed: Android SDK Build-Tools", taskOutput); + b.ThrowOnBuildFailure = true; Assert.IsTrue (b.Build (proj, parameters: new string [] { "AcceptAndroidSDKLicenses=true" }), "InstallAndroidDependencies should have succeeded."); + Assert.IsTrue (Directory.Exists (Path.Combine (sdkPath, "platforms")), "At least one platform should have been installed"); + Assert.IsTrue (Directory.Exists (Path.Combine (sdkPath, "build-tools")), "At least one Build Tools version should have been installed"); b.Target = defaultTarget; Assert.IsTrue (b.Build (proj), "build should have succeeded."); + taskOutput = b.LastBuildOutput + .SkipWhile (x => !x.StartsWith (" ResolveSdks Outputs:")) + .TakeWhile (x => !x.StartsWith ("Done executing task \"ResolveSdks\"")); + StringAssert.Contains (sdkPath, taskOutput.First (x => x.StartsWith (" AndroidSdkPath:"))); } } finally { Environment.SetEnvironmentVariable ("ANDROID_SDK_PATH", old);