diff --git a/build.cake b/build.cake index 995fee1b8569..141cf39e3d99 100644 --- a/build.cake +++ b/build.cake @@ -35,1017 +35,11 @@ PowerShell: // ARGUMENTS ////////////////////////////////////////////////////////////////////// -string agentName = EnvironmentVariable("AGENT_NAME", ""); -bool isCIBuild = !String.IsNullOrWhiteSpace(agentName); -string configuration = GetBuildVariable("configuration", GetBuildVariable("BUILD_CONFIGURATION", "DEBUG")); -DirectoryPath artifactStagingDirectory = MakeAbsolute(Directory(EnvironmentVariable("BUILD_ARTIFACTSTAGINGDIRECTORY", "artifacts"))); -DirectoryPath logDirectory = MakeAbsolute(Directory(EnvironmentVariable("LogDirectory", $"{artifactStagingDirectory}/logs"))); -DirectoryPath testResultsDirectory = MakeAbsolute(Directory(EnvironmentVariable("TestResultsDirectory", $"{artifactStagingDirectory}/test-results"))); -DirectoryPath diffDirectory = MakeAbsolute(Directory(EnvironmentVariable("ApiDiffDirectory", $"{artifactStagingDirectory}/api-diff"))); -DirectoryPath tempDirectory = MakeAbsolute(Directory(EnvironmentVariable("AGENT_TEMPDIRECTORY", EnvironmentVariable("TEMP", EnvironmentVariable("TMPDIR", "../maui-temp")) + "/" + Guid.NewGuid()))); - -var target = Argument("target", "Default"); +var target = Argument("target", "Default"); if(String.IsNullOrWhiteSpace(target)) target = "Default"; -var IOS_SIM_NAME = GetBuildVariable("IOS_SIM_NAME", "iPhone 8"); -var IOS_SIM_RUNTIME = GetBuildVariable("IOS_SIM_RUNTIME", "com.apple.CoreSimulator.SimRuntime.iOS-14-4"); -var IOS_CONTROLGALLERY = "src/Compatibility/ControlGallery/src/iOS/"; -var IOS_CONTROLGALLERY_PROJ = $"{IOS_CONTROLGALLERY}Compatibility.ControlGallery.iOS.csproj"; -var IOS_TEST_PROJ = "./src/Compatibility/ControlGallery/test/iOS.UITests/Compatibility.ControlGallery.iOS.UITests.csproj"; -var IOS_TEST_LIBRARY = Argument("IOS_TEST_LIBRARY", $"./src/Compatibility/ControlGallery/test/iOS.UITests/bin/{configuration}/Microsoft.Maui.Controls.iOS.UITests.dll"); -var IOS_IPA_PATH = Argument("IOS_IPA_PATH", $"./src/Compatibility/ControlGallery/src/iOS/bin/iPhoneSimulator/{configuration}/CompatibilityControlGalleryiOS.app"); -var IOS_BUNDLE_ID = "com.microsoft.mauicompatibilitygallery"; -var IOS_BUILD_IPA = Argument("IOS_BUILD_IPA", (target == "cg-ios-deploy") ? true : (false || isCIBuild) ); -Guid IOS_SIM_UDID = Argument("IOS_SIM_UDID", Guid.Empty); - -var UWP_PACKAGE_ID = "0d4424f6-1e29-4476-ac00-ba22c3789cb6"; -var UWP_TEST_LIBRARY = GetBuildVariable("UWP_TEST_LIBRARY", $"./src/Compatibility/ControlGallery/test/Xamarin.Forms.Core.Windows.UITests/bin/{configuration}/Xamarin.Forms.Core.Windows.UITests.dll"); -var UWP_PFX_PATH = Argument("UWP_PFX_PATH", "Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx"); -var UWP_APP_PACKAGES_PATH = Argument("UWP_APP_PACKAGES_PATH", "*/AppPackages/"); -var UWP_APP_DRIVER_INSTALL_PATH = Argument("UWP_APP_DRIVER_INSTALL_PATH", "https://github.com/microsoft/WinAppDriver/releases/download/v1.2-RC/WindowsApplicationDriver.msi"); - -var ANDROID_BUNDLE_ID = "com.microsoft.mauicompatibilitygallery"; -var ANDROID_CONTROLGALLERY = "src/Compatibility/ControlGallery/src/Android/"; -var ANDROID_CONTROLGALLERY_PROJ = $"{ANDROID_CONTROLGALLERY}Compatibility.ControlGallery.Android.csproj"; -var ANDROID_RENDERERS = Argument("ANDROID_RENDERERS", "FAST"); -var ANDROID_TEST_PROJ = "./src/Compatibility/ControlGallery/test/Android.UITests/Compatibility.ControlGallery.Android.UITests.csproj"; - -var BUILD_TASKS_PROJ ="._Microsoft.Maui.BuildTasks.sln"; - -var XamarinFormsVersion = Argument("XamarinFormsVersion", ""); -var packageVersion = GetBuildVariable("packageVersion", "0.1.0-p2"); -var releaseChannelArg = GetBuildVariable("CHANNEL", "Stable"); -var teamProject = GetBuildVariable("TeamProject", GetBuildVariable("SYSTEM_TEAMPROJECT", "")); -bool isHostedAgent = agentName.StartsWith("Azure Pipelines") || agentName.StartsWith("Hosted Agent"); -var localDotnet = GetBuildVariable("workloads", (target == "VS-WINUI") ? "global" : "local") == "local"; - -var vsVersion = GetBuildVariable("VS", ""); - -var MAUI_SLN = "./._Microsoft.Maui.sln"; - -var CONTROLGALLERY_SLN = "./._ControlGallery.sln"; - -string defaultUnitTestWhere = ""; - -if(target.ToLower().Contains("uwp")) - defaultUnitTestWhere = "cat != UwpIgnore"; - -var NUNIT_TEST_WHERE = Argument("NUNIT_TEST_WHERE", defaultUnitTestWhere); -NUNIT_TEST_WHERE = ParseDevOpsInputs(NUNIT_TEST_WHERE); - -var ANDROID_HOME = EnvironmentVariable("ANDROID_HOME") ?? - (IsRunningOnWindows () ? "C:\\Program Files (x86)\\Android\\android-sdk\\" : ""); - -string MSBuildExe = Argument("msbuild", EnvironmentVariable("MSBUILD_EXE", "")); -string MSBuildArgumentsENV = EnvironmentVariable("MSBuildArguments", ""); -string MSBuildArgumentsARGS = Argument("MSBuildArguments", ""); -string MSBuildArguments; - -MSBuildArguments = $"{MSBuildArgumentsENV} {MSBuildArgumentsARGS}"; - -Information("MSBuildArguments: {0}", MSBuildArguments); - -string androidEmulators = EnvironmentVariable("ANDROID_EMULATORS", ""); - -string androidSdks = EnvironmentVariable("ANDROID_API_SDKS", - // build/platform tools - "build-tools;29.0.3," + - "build-tools;30.0.2," + - "platform-tools," + - // apis - "platforms;android-26," + - "platforms;android-27," + - "platforms;android-28," + - "platforms;android-29," + - "platforms;android-30," + - "platforms;android-31," + - // emulators - androidEmulators); - -Information("ANDROID_API_SDKS: {0}", androidSdks); -string[] androidSdkManagerInstalls = androidSdks.Split(','); - -(string name, string location, string featureList)[] windowsSdksInstalls = new (string name, string location, string featureList)[] -{ - ("10.0.19041.0", "https://go.microsoft.com/fwlink/p/?linkid=2120843", "OptionId.WindowsPerformanceToolkit OptionId.WindowsDesktopDebuggers OptionId.AvrfExternal OptionId.WindowsSoftwareLogoToolkit OptionId.MSIInstallTools OptionId.SigningTools OptionId.UWPManaged OptionId.UWPCPP OptionId.UWPLocalized OptionId.DesktopCPPx86 OptionId.DesktopCPPx64 OptionId.DesktopCPParm OptionId.DesktopCPParm64"), - ("10.0.18362.0", "https://go.microsoft.com/fwlink/?linkid=2083338", "+"), - ("10.0.17763.0", "https://go.microsoft.com/fwlink/p/?linkid=2033908", "+"), - ("10.0.16299.0", "https://go.microsoft.com/fwlink/p/?linkid=864422", "+"), - ("10.0.14393.0", "https://go.microsoft.com/fwlink/p/?LinkId=838916", "+") -}; - -string[] netFrameworkSdksLocalInstall = new string[] -{ - "https://go.microsoft.com/fwlink/?linkid=2099470", //NET461 SDK - "https://go.microsoft.com/fwlink/?linkid=874338", //NET472 SDK - "https://go.microsoft.com/fwlink/?linkid=2099465", //NET47 - "https://download.microsoft.com/download/A/1/D/A1D07600-6915-4CB8-A931-9A980EF47BB7/NDP47-DevPack-KB3186612-ENU.exe", //net47 targeting pack - "https://go.microsoft.com/fwlink/?linkid=2088517", //NET48 SDK -}; - -// these don't run on CI -(string msiUrl, string cabUrl)[] netframeworkMSI = new (string msiUrl, string cabUrl)[] -{ - ( - "https://download.visualstudio.microsoft.com/download/pr/34dae2b3-314f-465e-aba0-0a862c29638e/b2bc986f304acdd76fcd8f910012b656/sdk_tools462.msi", - "https://download.visualstudio.microsoft.com/download/pr/6283f4a0-36b3-4336-a6f2-c5afd9f8fdbb/ffbe35e429f7d5c1d3777d03b2f38a24/sdk_tools462.cab" - ), - ( - "https://download.visualstudio.microsoft.com/download/pr/0d63c72c-9341-4de6-b493-dc7ad0d01246/f16b6402b8f8fb3b95dde5c1c2e5a2b4/sdk_tools461.msi", - "https://download.visualstudio.microsoft.com/download/pr/3dc58ffd-d515-43a4-87bd-2aba395eab17/5bff8f781c9843d64bd2367898395c5e/sdk_tools461.cab" - ), - ( - "https://download.visualstudio.microsoft.com/download/pr/9d14aa59-3f7f-4fe6-85e9-3bc31031e1f2/88b90ec9d096ec382a001e1fbd4a6be8/sdk_tools472.msi", - "https://download.visualstudio.microsoft.com/download/pr/77f1d250-f253-4c48-849c-0f08c9c11e77/ab2aa8f856e686cd4ad1c921742f2eeb/sdk_tools472.cab" - ) -}; - -Information ("XamarinFormsVersion: {0}", XamarinFormsVersion); -Information ("ANDROID_RENDERERS: {0}", ANDROID_RENDERERS); -Information ("configuration: {0}", configuration); -Information ("ANDROID_HOME: {0}", ANDROID_HOME); -Information ("Team Project: {0}", teamProject); -Information ("Agent.Name: {0}", agentName); -Information ("isCIBuild: {0}", isCIBuild); -Information ("artifactStagingDirectory: {0}", artifactStagingDirectory); -Information("tempDirectory: {0}", tempDirectory); -Information("NUNIT_TEST_WHERE: {0}", NUNIT_TEST_WHERE); -Information("TARGET: {0}", target); -Information("MSBUILD: {0}", MSBuildExe); -Information("vsVersion: {0}", vsVersion); -Information("localDotnet: {0}", localDotnet); -Information("dotnet: {0}", GetBuildVariable("dotnet", "")); -Information("workloads: {0}", GetBuildVariable("workloads", "")); - - -var releaseChannel = ReleaseChannel.Stable; -if(releaseChannelArg == "Preview") -{ - releaseChannel = ReleaseChannel.Preview; -} - -Information ("Release Channel: {0}", releaseChannel); - -string androidSDK_macos = ""; -string monoSDK_macos = ""; -string iOSSDK_macos = ""; -string macSDK_macos = ""; -string monoPatchVersion = ""; -string monoMajorVersion = ""; -string monoVersion = ""; - -if(releaseChannel == ReleaseChannel.Stable) -{ - if(IsXcodeVersionAtLeast("12.0")) - { - } - else - { - monoMajorVersion = ""; - monoPatchVersion = ""; - iOSSDK_macos = $"https://bosstoragemirror.blob.core.windows.net/wrench/jenkins/d16-7-xcode11.7/3016ffe2b0ee27bf4a2d61e6161430d6bbd62f78/7/package/notarized/xamarin.ios-13.20.3.5.pkg"; - macSDK_macos = $"https://bosstoragemirror.blob.core.windows.net/wrench/jenkins/d16-7-xcode11.7/3016ffe2b0ee27bf4a2d61e6161430d6bbd62f78/7/package/notarized/xamarin.mac-6.20.3.5.pkg"; - } -} - -if(String.IsNullOrWhiteSpace(monoSDK_macos)) -{ - if(String.IsNullOrWhiteSpace(monoPatchVersion)) - monoVersion = $"{monoMajorVersion}"; - else - monoVersion = $"{monoMajorVersion}.{monoPatchVersion}"; - - if(!String.IsNullOrWhiteSpace(monoVersion)) - { - monoSDK_macos = $"https://download.mono-project.com/archive/{monoMajorVersion}/macos-10-universal/MonoFramework-MDK-{monoVersion}.macos10.xamarin.universal.pkg"; - } -} - -string androidSDK_windows = ""; -string iOSSDK_windows = ""; -string monoSDK_windows = ""; -string macSDK_windows = ""; -string android_jdk_11_windows = "https://aka.ms/download-jdk/microsoft-jdk-11.0.12.7.1-windows-x64.msi"; -string android_jdk_11_macos = "https://aka.ms/download-jdk/microsoft-jdk-11.0.12.7.1-macOS-x64.pkg"; -string android_jdk_11_folder = "C:\\Program Files\\Microsoft\\jdk-11.0.12.7-hotspot"; - -androidSDK_macos = EnvironmentVariable("ANDROID_SDK_MAC", androidSDK_macos); -iOSSDK_macos = EnvironmentVariable("IOS_SDK_MAC", iOSSDK_macos); -monoSDK_macos = EnvironmentVariable("MONO_SDK_MAC", monoSDK_macos); -macSDK_macos = EnvironmentVariable("MAC_SDK_MAC", macSDK_macos); - -androidSDK_windows = EnvironmentVariable("ANDROID_SDK_WINDOWS", ""); -iOSSDK_windows = EnvironmentVariable("IOS_SDK_WINDOWS", ""); -monoSDK_windows = EnvironmentVariable("MONO_SDK_WINDOWS", ""); -macSDK_windows = EnvironmentVariable("MAC_SDK_WINDOWS", ""); - -string androidSDK = IsRunningOnWindows() ? androidSDK_windows : androidSDK_macos; -string monoSDK = IsRunningOnWindows() ? monoSDK_windows : monoSDK_macos; -string iosSDK = IsRunningOnWindows() ? iOSSDK_windows : iOSSDK_macos; -string macSDK = IsRunningOnWindows() ? macSDK_windows : macSDK_macos; - - -Information ("androidSDK: {0}", androidSDK); -Information ("monoSDK: {0}", monoSDK); -Information ("macSDK: {0}", macSDK); -Information ("iosSDK: {0}", iosSDK); - -////////////////////////////////////////////////////////////////////// -// TASKS -////////////////////////////////////////////////////////////////////// - -Task("BuildUnitTests") - .IsDependentOn("BuildTasks") - .Description("Builds all necessary projects to run Unit Tests") - .Does(() => -{ - try - { - var msbuildSettings = GetMSBuildSettings(); - var binaryLogger = new MSBuildBinaryLogSettings { - Enabled = isCIBuild - }; - - msbuildSettings.BinaryLogger = binaryLogger; - binaryLogger.FileName = $"{artifactStagingDirectory}/Maui.Controls-{configuration}.binlog"; - MSBuild("./._Microsoft.Maui.sln", msbuildSettings.WithRestore()); - } - catch(Exception) - { - if(IsRunningOnWindows()) - throw; - } -}); - -Task("provision-macsdk") - .Description("Install Xamarin.Mac SDK") - .Does(async () => - { - if(!IsRunningOnWindows()) - { - if(!String.IsNullOrWhiteSpace(macSDK)) - await Boots(macSDK); - else - await Boots (Product.XamarinMac, releaseChannel); - } - else if(!String.IsNullOrWhiteSpace(macSDK)) - await Boots(macSDK); - }); - -Task("provision-iossdk") - .Description("Install Xamarin.iOS SDK") - .Does(async () => - { - if (!IsRunningOnWindows()) { - if(!String.IsNullOrWhiteSpace(iosSDK)) - await Boots(iosSDK); - else - await Boots (Product.XamariniOS, releaseChannel); - } - else if(!String.IsNullOrWhiteSpace(iosSDK)) - await Boots(iosSDK); - }); - -Task("provision-androidsdk") - .Description("Install Xamarin.Android SDK") - .Does(async () => - { - Information ("ANDROID_HOME: {0}", ANDROID_HOME); - - if(androidSdkManagerInstalls.Length > 0) - { - Information("Updating Android SDKs"); - var androidSdkSettings = new AndroidSdkManagerToolSettings { - SkipVersionCheck = true - }; - - if(!String.IsNullOrWhiteSpace(ANDROID_HOME)) - androidSdkSettings.SdkRoot = ANDROID_HOME; - - try{ - AcceptLicenses (androidSdkSettings); - } - catch(Exception exc) - { - Information("AcceptLicenses: {0}", exc); - } - - try{ - AndroidSdkManagerUpdateAll (androidSdkSettings); - } - catch(Exception exc) - { - Information("AndroidSdkManagerUpdateAll: {0}", exc); - } - - try{ - AcceptLicenses (androidSdkSettings); - } - catch(Exception exc) - { - Information("AcceptLicenses: {0}", exc); - } - - try{ - AndroidSdkManagerInstall (androidSdkManagerInstalls, androidSdkSettings); - } - catch(Exception exc) - { - Information("AndroidSdkManagerInstall: {0}", exc); - } - } - - if (!IsRunningOnWindows ()) - { - - await Boots(android_jdk_11_macos); - - if(!String.IsNullOrWhiteSpace(androidSDK)) - { - await Boots (androidSDK); - } - else - { - await Boots (Product.XamarinAndroid, releaseChannel); - } - } - else - { - if(!DirectoryExists(android_jdk_11_folder)) - { - await Boots(android_jdk_11_windows); - } - if(!String.IsNullOrWhiteSpace(androidSDK)) - { - await Boots (androidSDK); - } - } - }); - -Task("provision-monosdk") - .Description("Install Mono SDK") - .Does(async () => - { - if(!IsRunningOnWindows()) - { - if(!String.IsNullOrWhiteSpace(monoSDK)) - await Boots(monoSDK); - else - await Boots (Product.Mono, releaseChannel); - } - else if(!String.IsNullOrWhiteSpace(monoSDK)) - await Boots(monoSDK); - }); - -Task("provision-windowssdk") - .Description("Install Windows SDK") - .Does(() => - { - if(IsRunningOnWindows() && !isHostedAgent) - { - int i = 0; - foreach(var windowsSdk in windowsSdksInstalls) - { - string sdkPath = System.IO.Path.Combine(@"C:\Program Files (x86)\Windows Kits\10\Platforms\UAP", windowsSdk.name); - if(DirectoryExists(sdkPath) && GetFiles(System.IO.Path.Combine(sdkPath, "*.*")).Count() > 0) - { - Information("Already Installed: {0}", sdkPath); - continue; - } - - - Information("Installing: {0}", sdkPath); - string installUrl = windowsSdk.location; - string installerPath = $"{System.IO.Path.GetTempPath()}" + $"WindowsSDK{i}.exe"; - DownloadFile(installUrl, installerPath); - - var result = StartProcess(installerPath, new ProcessSettings { - Arguments = new ProcessArgumentBuilder() - .Append(@"/features ") - .Append(windowsSdk.featureList) - .Append(@" /q") - } - ); - - i++; - } - } - }); - -Task("provision-netsdk-local") - .Description("Install .NET SDK") - .Does(() => - { - if(IsRunningOnWindows() && (!isCIBuild || target == "provision-netsdk-local")) - { - foreach(var installUrl in netframeworkMSI) - { - string msiUrl = installUrl.msiUrl; - string cabUrl = installUrl.cabUrl; - - - string cabName = cabUrl.Split('/').Last(); - string msiName = msiUrl.Split('/').Last(); - string cabPath = $"{System.IO.Path.GetTempPath()}{cabName}"; - - Information("Downloading: {0} to {1}", cabUrl, cabPath); - DownloadFile(cabUrl, cabPath); - InstallMsiOrExe(msiUrl, null, msiName); - } - - int i = 0; - foreach(var installUrl in netFrameworkSdksLocalInstall) - { - Information("Installing: {0}", installUrl); - string installerPath = $"{System.IO.Path.GetTempPath()}" + $"netSDKS{i}.exe"; - DownloadFile(installUrl, installerPath); - - var result = StartProcess(installerPath, new ProcessSettings { - Arguments = new ProcessArgumentBuilder() - .Append(@"/quiet") - } - ); - - i++; - } - } - }); - -Task ("cg-uwp") - .IsDependentOn("BuildTasks") - .Does (() => -{ - MSBuild ("Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal.csproj", - GetMSBuildSettings().WithRestore()); -}); - -Task ("cg-uwp-build-tests") - .IsDependentOn("BuildTasks") - .Does (() => -{ - MSBuild ("Xamarin.Forms.ControlGallery.WindowsUniversal\\Xamarin.Forms.ControlGallery.WindowsUniversal.csproj", - GetMSBuildSettings(null) - .WithProperty("AppxBundlePlatforms", "x86") - .WithProperty("AppxBundle", "Always") - .WithProperty("UapAppxPackageBuildMode", "StoreUpload") - .WithProperty("AppxPackageSigningEnabled", "true") - .WithProperty("PackageCertificateThumbprint", "a59087cc92a9a8117ffdb5255eaa155748f9f852") - .WithProperty("PackageCertificateKeyFile", "Xamarin.Forms.ControlGallery.WindowsUniversal_TemporaryKey.pfx") - .WithProperty("PackageCertificatePassword", "") - // The platform unit tests can't run when UseDotNetNativeToolchain is set to true so we force it off here - .WithProperty("UseDotNetNativeToolchain", "false") - .WithRestore() - ); - - MSBuild("Xamarin.Forms.Core.Windows.UITests\\Xamarin.Forms.Core.Windows.UITests.csproj", - GetMSBuildSettings(buildConfiguration:"Debug").WithRestore()); -}); - -Task ("cg-uwp-deploy") - .WithCriteria(IsRunningOnWindows()) - .Does (() => -{ - var uninstallPS = new Action (() => { - try { - StartProcess ("powershell", - "$app = Get-AppxPackage -Name " + UWP_PACKAGE_ID + "; if ($app) { Remove-AppxPackage -Package $app.PackageFullName }"); - } catch { } - }); - // Try to uninstall the app if it exists from before - uninstallPS(); - - StartProcess("certutil", "-f -p \"\" -importpfx \"" + UWP_PFX_PATH + "\""); - - // Install the appx - var dependencies = GetFiles(UWP_APP_PACKAGES_PATH + "*/Dependencies/x86/*.appx"); - - foreach (var dep in dependencies) { - try - { - Information("Installing Dependency appx: {0}", dep); - StartProcess("powershell", "Add-AppxPackage -Path \"" + MakeAbsolute(dep).FullPath + "\""); - } - catch(Exception exc) - { - Information("Error: {0}", exc); - } - } - - var appxBundlePath = GetFiles(UWP_APP_PACKAGES_PATH + "*/*.appxbundle").First (); - Information("Installing appx: {0}", appxBundlePath); - StartProcess ("powershell", "Add-AppxPackage -Path \"" + MakeAbsolute(appxBundlePath).FullPath + "\""); -}); - -Task("cg-uwp-run-tests") - .IsDependentOn("cg-uwp-build-tests") - .IsDependentOn("cg-uwp-deploy") - .IsDependentOn("provision-uitests-uwp") - .IsDependentOn("_cg-uwp-run-tests"); - -Task("_cg-uwp-run-tests") - .Does((ctx) => - { - System.Diagnostics.Process process = null; - if(!isHostedAgent) - { - try - { - var info = new System.Diagnostics.ProcessStartInfo(@"C:\Program Files (x86)\Windows Application Driver\WinAppDriver.exe") - { - }; - - process = System.Diagnostics.Process.Start(info); - } - catch(Exception exc) - { - Information("Failed: {0}", exc); - } - } - - var settings = new NUnit3Settings { - Params = new Dictionary() - { - {"IncludeScreenShots", "true"} - } - }; - - - try - { - RunTests(UWP_TEST_LIBRARY, settings, ctx); - } - finally - { - try - { - process?.Kill(); - } - catch{} - } - - }); - -Task("cg-uwp-run-tests-ci") - .IsDependentOn("provision-windowssdk") - .IsDependentOn("cg-uwp-deploy") - .IsDependentOn("_cg-uwp-run-tests") - .Does(() => - { - }); - -Task("provision-uitests-uwp") - .WithCriteria(IsRunningOnWindows() && !isHostedAgent) - .Description("Installs and Starts WindowsApplicationDriver. Use WinAppDriverPath to specify WinAppDriver Location.") - .Does(() => - { - string installPath = Argument("WinAppDriverPath", @"C:\Program Files (x86)\"); - string driverPath = System.IO.Path.Combine(installPath, "Windows Application Driver"); - if(!DirectoryExists(driverPath)) - { - try{ - InstallMsiOrExe(UWP_APP_DRIVER_INSTALL_PATH, installPath); - } - catch(Exception e) - { - Information("Failed to Install Win App Driver: {0}", e); - } - } - }); - - -async Task InstallMsiWithBoots(string msiFile, string installTo = null, string fileName = "InstallFile.msi") -{ - bool success = false; - - try - { - await Boots(msiFile); - success = true; - } - catch (System.Exception e) - { - Information("Boots failed: {0}", e); - } - - - if(success) - return; - - try - { - InstallMsiOrExe(msiFile, installTo, fileName, !isCIBuild); - success = true; - } - catch (System.Exception e) - { - Information("Our attempt failed: {0}", e); - } -} - -void InstallMsiOrExe(string msiFile, string installTo = null, string fileName = "InstallFile.msi", bool interactive = false) -{ - if(msiFile.EndsWith(".exe") && fileName == "InstallFile.msi") - fileName = "InstallFile.exe"; - - string installerPath = $"{System.IO.Path.GetTempPath()}{fileName}"; - - try - { - Information ("Installing: {0}", msiFile); - DownloadFile(msiFile, installerPath); - Information("File Downloaded To: {0}", installerPath); - int result = -1; - - if(msiFile.EndsWith(".exe")) - { - result = StartProcess(installerPath, new ProcessSettings { - Arguments = new ProcessArgumentBuilder() - .Append(@" /q") - } - ); - } - else{ - var argumentBuilder = - new ProcessArgumentBuilder() - .Append("/a") - .Append(installerPath); - - if(!interactive) - argumentBuilder = argumentBuilder.Append("/qn"); - - if(!String.IsNullOrWhiteSpace(installTo)) - { - Information("Installing into: {0}", installTo); - argumentBuilder = argumentBuilder.Append("TARGETDIR=\"" + installTo + "\""); - } - - result = StartProcess("msiexec", new ProcessSettings { - Arguments = argumentBuilder - }); - } - - if(result != 0) - throw new Exception("Failed to install: " + msiFile); - - Information("File Installed: {0}", result); - } - catch(Exception exc) - { - Information("Failed to install {0} make sure you are running script as admin {1}", msiFile, exc); - throw; - } - finally{ - DeleteFile(installerPath); - - } -} - -Task("provision") - .Description("Install SDKs required to build project") - .IsDependentOn("provision-macsdk") - .IsDependentOn("provision-iossdk") - .IsDependentOn("provision-androidsdk") - .IsDependentOn("provision-netsdk-local") - .IsDependentOn("provision-windowssdk") - .IsDependentOn("provision-monosdk"); // always provision monosdk last otherwise CI might fail - -Task("provision-powershell").Does(()=> { - var settings = new DotNetCoreToolSettings - { - DiagnosticOutput = true, - ArgumentCustomization = args=>args.Append("install --global PowerShell") - }; - - DotNetCoreTool("tool", settings); -}); - -Task("Restore") - .Description($"Restore target on {MAUI_SLN}") - .Does(() => - { - try{ - MSBuild(MAUI_SLN, GetMSBuildSettings().WithTarget("restore")); - } - catch{ - // ignore restore errors that come from uwp - if(IsRunningOnWindows()) - throw; - } - }); - -Task("WriteGoogleMapsAPIKey") - .Description("Write GoogleMapsAPIKey to Android Control Gallery") - .Does(() => - { - string GoogleMapsAPIKey = Argument("GoogleMapsAPIKey", ""); - - if(!String.IsNullOrWhiteSpace(GoogleMapsAPIKey)) - { - Information("Writing GoogleMapsAPIKey"); - System.IO.File.WriteAllText($"{ANDROID_CONTROLGALLERY}/Properties/MapsKey.cs", "[assembly: Android.App.MetaData(\"com.google.android.maps.v2.API_KEY\", Value = \"" + GoogleMapsAPIKey + "\")]"); - } - }); - -Task("BuildTasks") - .Description($"Build {BUILD_TASKS_PROJ}") - .Does(() => -{ - MSBuild(BUILD_TASKS_PROJ, GetMSBuildSettings().WithRestore()); -}); - -Task("Build") - .Description("Builds all necessary projects to run Control Gallery") - .IsDependentOn("Restore") - .Does(() => -{ - try{ - MSBuild(MAUI_SLN, GetMSBuildSettings().WithRestore()); - } - catch(Exception) - { - if(IsRunningOnWindows()) - throw; - } -}); - -Task("Android100") - .Description("Builds Monodroid10.0 targets") - .Does(() => - { - MSBuild(MAUI_SLN, - GetMSBuildSettings() - .WithRestore() - .WithProperty("AndroidTargetFrameworks", "MonoAndroid10.0")); - }); - -Task("VS") - .Description("Builds projects necessary so solution compiles on VS Preview") - .IsDependentOn("Clean") - .IsDependentOn("VSMAC") - .IsDependentOn("VSWINDOWS"); - -Task("VS-CG") - .Description("Builds projects necessary so solution compiles on VS") - .IsDependentOn("Clean") - .IsDependentOn("VSMAC") - .IsDependentOn("VSWINDOWS"); - -Task("VS-CG-STABLE") - .Description("Builds projects necessary so solution compiles on VS") - .IsDependentOn("Clean") - .IsDependentOn("VSMAC") - .IsDependentOn("VSWINDOWS"); - -Task("VS-STABLE") - .Description("Builds projects necessary so solution compiles on VS Stable") - .IsDependentOn("Clean") - .IsDependentOn("VSMAC") - .IsDependentOn("VSWINDOWS"); - -Task("VSWINDOWS") - .Description("Builds projects necessary so solution compiles on VS Windows") - .IsDependentOn("BuildTasks") - .WithCriteria(IsRunningOnWindows()) - .Does(() => - { - bool includePrerelease = !target.ToLower().Contains("stable"); - - if (target.ToLower().StartsWith("vs-cg")) - { - MSBuild("._Compatibility.ControlGallery.sln", - GetMSBuildSettings() - .WithRestore()); - StartVisualStudio("._Compatibility.ControlGallery.sln", includePrerelease: includePrerelease); - } - else - { - MSBuild(@"src\Compatibility\Core\src\Compatibility.csproj", - GetMSBuildSettings() - .WithProperty("BuildForLegacy", "true") - .WithRestore()); - StartVisualStudio("._Microsoft.Maui.sln", includePrerelease: includePrerelease); - } - }); - -Task("VSMAC") - .Description("Builds projects necessary so solution compiles on VSMAC") - .WithCriteria(!IsRunningOnWindows()) - .IsDependentOn("BuildTasks") - .Does(() => - { - - string sln = "._Microsoft.Maui.sln"; - if (target == "VS-CG") - sln = "._Compatibility.ControlGallery.sln"; - - MSBuild("src/Core/src/Core.csproj", - GetMSBuildSettings() - .WithRestore()); - - MSBuild("src/Essentials/src/Essentials.csproj", - GetMSBuildSettings() - .WithRestore()); - - MSBuild("src/SingleProject/Resizetizer/src/Resizetizer.csproj", GetMSBuildSettings().WithRestore()); - - StartVisualStudio(sln); - }); - -Task("cg-android") - .Description("Builds Android Control Gallery") - .IsDependentOn("WriteGoogleMapsAPIKey") - .IsDependentOn("BuildTasks") - .Does(() => - { - var buildSettings = GetMSBuildSettings(); - - buildSettings = buildSettings.WithRestore(); - - if(isCIBuild) - { - buildSettings = buildSettings.WithTarget("Rebuild").WithTarget("SignAndroidPackage"); - var binaryLogger = new MSBuildBinaryLogSettings { - Enabled = true - }; - - buildSettings.BinaryLogger = binaryLogger; - binaryLogger.FileName = $"{artifactStagingDirectory}/android-{ANDROID_RENDERERS}.binlog"; - } - - MSBuild(ANDROID_CONTROLGALLERY_PROJ, buildSettings); - }); - -Task("cg-android-build-tests") - .IsDependentOn("BuildTasks") - .Does(() => - { - var buildSettings = GetMSBuildSettings(); - - buildSettings = buildSettings.WithRestore(); - - if(isCIBuild) - { - var binaryLogger = new MSBuildBinaryLogSettings { - Enabled = true, - FileName = $"{artifactStagingDirectory}/android-uitests.binlog" - }; - - buildSettings.BinaryLogger = binaryLogger; - } - - MSBuild(ANDROID_TEST_PROJ, buildSettings); - }); - -Task("cg-android-vs") - .Description("Builds Android Control Gallery and open VS") - .IsDependentOn("cg-android") - .Does(() => - { - StartVisualStudio(); - }); - -Task("cg-ios") - .Description("Builds iOS Control Gallery and open VS") - .IsDependentOn("BuildTasks") - .Does(() => - { - var buildSettings = - GetMSBuildSettings(null) - .WithProperty("BuildIpa", $"{IOS_BUILD_IPA}"); - - buildSettings = buildSettings.WithRestore(); - - if(isCIBuild) - { - var binaryLogger = new MSBuildBinaryLogSettings { - Enabled = true - }; - - buildSettings.BinaryLogger = binaryLogger; - binaryLogger.FileName = $"{artifactStagingDirectory}/ios-cg.binlog"; - } - - MSBuild(IOS_CONTROLGALLERY_PROJ, buildSettings); - }); - -Task("cg-ios-vs") - .Description("Builds iOS Control Gallery and open VS") - .IsDependentOn("cg-ios") - .Does(() => - { - StartVisualStudio(); - }); - -Task("cg-ios-build-tests") - .IsDependentOn("BuildTasks") - .Does(() => - { - // the UI Tests all reference the galleries so those get built as a side effect of building the - // ui tests - var buildSettings = - GetMSBuildSettings(null, configuration) - .WithProperty("MtouchArch", "x86_64") - .WithProperty("iOSPlatform", "iPhoneSimulator") - .WithProperty("BuildIpa", $"true") - .WithProperty("CI", $"true") - .WithRestore(); - - if(isCIBuild) - { - var binaryLogger = new MSBuildBinaryLogSettings { - Enabled = true, - FileName = $"{artifactStagingDirectory}/ios-uitests.binlog" - }; - - buildSettings.BinaryLogger = binaryLogger; - } - - MSBuild(IOS_TEST_PROJ, buildSettings); - }); - -Task("cg-ios-run-tests") - .IsDependentOn("cg-ios-build-tests") - .IsDependentOn("cg-ios-deploy") - .IsDependentOn("_cg-ios-run-tests"); - -Task("_cg-ios-run-tests") - .Does((ctx) => - { - var sim = GetIosSimulator(); - - var settings = new NUnit3Settings { - Params = new Dictionary() - { - {"UDID", GetIosSimulator().UDID}, - {"IncludeScreenShots", "true"} - } - }; - - if(isCIBuild) - { - Information("defaults write com.apple.CrashReporter DialogType none"); - IEnumerable redirectedStandardOutput; - StartProcess("defaults", - new ProcessSettings { - Arguments = new ProcessArgumentBuilder().Append(@"write com.apple.CrashReporter DialogType none"), - RedirectStandardOutput = true - }, - out redirectedStandardOutput - ); - - - foreach (var item in redirectedStandardOutput) - { - Information(item); - } - } - - RunTests(IOS_TEST_LIBRARY, settings, ctx); - }); - -Task("cg-ios-run-tests-ci") - .IsDependentOn("cg-ios-deploy") - .IsDependentOn("_cg-ios-run-tests") - .Does(() => - { - }); - -Task ("cg-ios-deploy") - .Does (() => -{ - // Look for a matching simulator on the system - var sim = GetIosSimulator(); - - //ShutdownAndResetiOSSimulator(sim); - - // Boot the simulator - Information("Booting: {0} ({1} - {2})", sim.Name, sim.Runtime, sim.UDID); - if (!sim.State.ToLower().Contains ("booted")) - BootAppleSimulator (sim.UDID); - - // Wait for it to be booted - var booted = false; - for (int i = 0; i < 100; i++) { - if (ListAppleSimulators().Any (s => s.UDID == sim.UDID && s.State.ToLower().Contains("booted"))) { - booted = true; - break; - } - System.Threading.Thread.Sleep(1000); - } - - // Install the IPA that was previously built - var ipaPath = new FilePath(IOS_IPA_PATH); - Information ("Installing: {0}", ipaPath); - InstalliOSApplication(sim.UDID, MakeAbsolute(ipaPath).FullPath); - - - // Launch the IPA - Information("Launching: {0}", IOS_BUNDLE_ID); - LaunchiOSApplication(sim.UDID, IOS_BUNDLE_ID); -}); - ////////////////////////////////////////////////////////////////////// // TASK TARGETS ////////////////////////////////////////////////////////////////////// @@ -1056,246 +50,4 @@ Task("Default").IsDependentOn("dotnet").IsDependentOn("dotnet-pack"); // EXECUTION ////////////////////////////////////////////////////////////////////// -RunTarget(target); - -void RunTests(string unitTestLibrary, NUnit3Settings settings, ICakeContext ctx) -{ - try - { - if(!String.IsNullOrWhiteSpace(NUNIT_TEST_WHERE)) - { - settings.Where = NUNIT_TEST_WHERE; - } - - NUnit3(new [] { unitTestLibrary }, settings); - } - catch - { - SetTestResultsEnvironmentVariables(); - throw; - } - - SetTestResultsEnvironmentVariables(); - - void SetTestResultsEnvironmentVariables() - { - var doc = new System.Xml.XmlDocument(); - doc.Load("TestResult.xml"); - var root = doc.DocumentElement; - - foreach(System.Xml.XmlAttribute attr in root.Attributes) - { - SetEnvironmentVariable($"NUNIT_{attr.Name}", attr.Value, ctx); - } - } -} - -void StartVisualStudio(string sln = "./._Microsoft.Maui.sln", bool includePrerelease = true) -{ - if(isCIBuild) - return; - - if (!String.IsNullOrWhiteSpace(vsVersion)) - includePrerelease = (vsVersion == "preview"); - - if(IsRunningOnWindows()) - { - var vsLatest = VSWhereLatest(new VSWhereLatestSettings { IncludePrerelease = includePrerelease, }); - if (vsLatest == null) - throw new Exception("Unable to find Visual Studio!"); - - StartProcess(vsLatest.CombineWithFilePath("./Common7/IDE/devenv.exe"), sln); - } - else - StartProcess("open", new ProcessSettings{ Arguments = sln }); -} - -MSBuildSettings GetMSBuildSettings( - PlatformTarget? platformTarget = PlatformTarget.MSIL, - string buildConfiguration = null, - bool includePrerelease = false) -{ - var buildSettings = new MSBuildSettings { - PlatformTarget = platformTarget, - MSBuildPlatform = Cake.Common.Tools.MSBuild.MSBuildPlatform.x86, - Configuration = buildConfiguration ?? configuration, - }; - - - if(IsRunningOnWindows()) - { - var vsInstallation = - VSWhereLatest(new VSWhereLatestSettings { Requires = "Microsoft.Component.MSBuild", IncludePrerelease = includePrerelease }) - ?? VSWhereLatest(new VSWhereLatestSettings { Requires = "Microsoft.Component.MSBuild" }); - - if (vsInstallation != null) - { - buildSettings.ToolPath = vsInstallation.CombineWithFilePath(@"MSBuild\Current\Bin\MSBuild.exe"); - if (!FileExists(buildSettings.ToolPath)) - buildSettings.ToolPath = vsInstallation.CombineWithFilePath(@"MSBuild\15.0\Bin\MSBuild.exe"); - } - } - - buildSettings = buildSettings.WithProperty("ANDROID_RENDERERS", $"{ANDROID_RENDERERS}"); - if(!String.IsNullOrWhiteSpace(XamarinFormsVersion)) - { - buildSettings = buildSettings.WithProperty("XamarinFormsVersion", XamarinFormsVersion); - } - - buildSettings.ArgumentCustomization = args => args.Append($"/nowarn:VSX1000 {MSBuildArguments}"); - return buildSettings; -} - -bool IsXcodeVersionAtLeast(string version) -{ - if(IsRunningOnWindows()) - return true; - - return XcodeVersion() >= Version.Parse(version); -} - -Version XcodeVersion() -{ - if(IsRunningOnWindows()) - return null; - - IEnumerable redirectedStandardOutput; - StartProcess("xcodebuild", - new ProcessSettings { - Arguments = new ProcessArgumentBuilder().Append(@"-version"), - RedirectStandardOutput = true - }, - out redirectedStandardOutput - ); - - foreach (var item in redirectedStandardOutput) - { - if(item.Contains("Xcode")) - { - var xcodeVersion = Version.Parse(item.Replace("Xcode", "")); - Information($"Xcode: {xcodeVersion}"); - - return xcodeVersion; - } - } - - return null; -} - -IReadOnlyList iosSimulators = null; - -void ShutdownAndResetiOSSimulator(AppleSimulator sim) -{ - //close all simulators , reset needs simulator to be closed - Information("Shutdown simulators: {0} ({1} - {2}) State: {3}", sim.Name, sim.Runtime, sim.UDID, sim.State); - ShutdownAllAppleSimulators(); - - var shutdown = false; - for (int i = 0; i < 100; i++) { - if (ListAppleSimulators().Any (s => s.UDID == sim.UDID && s.State.ToLower().Contains("shutdown"))) { - shutdown = true; - break; - } - System.Threading.Thread.Sleep(1000); - } - - //Reset the simulator - Information ("Factory reset simulator: {0}", sim.UDID); - EraseAppleSimulator(sim.UDID); -} - -AppleSimulator GetIosSimulator() -{ - if(iosSimulators == null) - { - iosSimulators = ListAppleSimulators (); - foreach (var s in iosSimulators) - { - Information("Info: {0} ({1} - {2} - {3})", s.Name, s.Runtime, s.UDID, s.Availability); - } - - StartProcess("xcrun", new ProcessSettings { - Arguments = new ProcessArgumentBuilder() - .Append(@"simctl list") - } - ); - } - - if(IOS_SIM_UDID != Guid.Empty) - return iosSimulators.First (s => Guid.Parse(s.UDID) == IOS_SIM_UDID); - - // Look for a matching simulator on the system - return iosSimulators.First (s => s.Name == IOS_SIM_NAME && s.Runtime == IOS_SIM_RUNTIME); -} - -public void SetEnvironmentVariable(string key, string value, ICakeContext context) -{ - var buildSystem = context.BuildSystem(); - Information("Setting: {0} to {1}", key, value); - if(isCIBuild) - { - buildSystem.AzurePipelines.Commands.SetVariable(key, value); - } - else - { - System.Environment.SetEnvironmentVariable(key, value); - } -} - -public string ParseDevOpsInputs(string nunitWhere) -{ - var ExcludeCategory = GetBuildVariable("ExcludeCategory", "")?.Replace("\"", ""); - var ExcludeCategory2 = GetBuildVariable("ExcludeCategory2", "")?.Replace("\"", ""); - var IncludeCategory = GetBuildVariable("IncludeCategory", "")?.Replace("\"", ""); - - Information("ExcludeCategory: {0}", ExcludeCategory); - Information("IncludeCategory: {0}", IncludeCategory); - Information("ExcludeCategory2: {0}", ExcludeCategory2); - string excludeString = String.Empty; - string includeString = String.Empty; - string returnValue = String.Empty; - - List azureDevopsFilters = new List(); - - // Replace Azure devops syntax for unit tests to Nunit3 filters - if(!String.IsNullOrWhiteSpace(ExcludeCategory)) - { - azureDevopsFilters.AddRange(ExcludeCategory.Split(new string[] { "--exclude-category" }, StringSplitOptions.None)); - } - - if(!String.IsNullOrWhiteSpace(ExcludeCategory2)) - { - azureDevopsFilters.AddRange(ExcludeCategory2.Split(new string[] { "--exclude-category" }, StringSplitOptions.None)); - } - - for(int i = 0; i < azureDevopsFilters.Count; i++) - { - if(!String.IsNullOrWhiteSpace(excludeString)) - excludeString += " && "; - - excludeString += $" cat != {azureDevopsFilters[i]} "; - } - - String.Join(" cat != ", azureDevopsFilters); - - if(!String.IsNullOrWhiteSpace(IncludeCategory)) - { - foreach (var item in IncludeCategory.Split(new string[] { "--include-category" }, StringSplitOptions.None)) - { - if(!String.IsNullOrWhiteSpace(includeString)) - includeString += " || "; - - includeString += $" cat == {item} "; - } - } - - foreach(var filter in new []{nunitWhere,includeString,excludeString}.Where(x=> !String.IsNullOrWhiteSpace(x))) - { - if(!String.IsNullOrWhiteSpace(returnValue)) - returnValue += " && "; - - returnValue += $"({filter})"; - } - - return returnValue; -} +RunTarget(target); \ No newline at end of file diff --git a/eng/cake/dotnet.cake b/eng/cake/dotnet.cake index cc4feae959c7..433bdf9b34b0 100644 --- a/eng/cake/dotnet.cake +++ b/eng/cake/dotnet.cake @@ -2,6 +2,11 @@ var ext = IsRunningOnWindows() ? ".exe" : ""; var dotnetPath = $"./bin/dotnet/dotnet{ext}"; +string configuration = GetBuildVariable("configuration", GetBuildVariable("BUILD_CONFIGURATION", "DEBUG")); +var localDotnet = GetBuildVariable("workloads", "local") == "local"; +var vsVersion = GetBuildVariable("VS", ""); +string MSBuildExe = Argument("msbuild", EnvironmentVariable("MSBUILD_EXE", "")); +Exception pendingException = null; // Tasks for CI @@ -15,7 +20,7 @@ Task("dotnet") DotNetCoreBuild("./src/DotNet/DotNet.csproj", new DotNetCoreBuildSettings { MSBuildSettings = new DotNetCoreMSBuildSettings() - .EnableBinaryLogger($"{logDirectory}/dotnet-{configuration}.binlog") + .EnableBinaryLogger($"{GetLogDirectory()}/dotnet-{configuration}.binlog") .SetConfiguration(configuration), }); }); @@ -29,7 +34,7 @@ Task("dotnet-local-workloads") DotNetCoreBuild("./src/DotNet/DotNet.csproj", new DotNetCoreBuildSettings { MSBuildSettings = new DotNetCoreMSBuildSettings() - .EnableBinaryLogger($"{logDirectory}/dotnet-{configuration}.binlog") + .EnableBinaryLogger($"{GetLogDirectory()}/dotnet-{configuration}.binlog") .SetConfiguration(configuration) .WithProperty("InstallWorkloadPacks", "false"), }); @@ -37,7 +42,7 @@ Task("dotnet-local-workloads") DotNetCoreBuild("./src/DotNet/DotNet.csproj", new DotNetCoreBuildSettings { MSBuildSettings = new DotNetCoreMSBuildSettings() - .EnableBinaryLogger($"{logDirectory}/dotnet-install-{configuration}.binlog") + .EnableBinaryLogger($"{GetLogDirectory()}/dotnet-install-{configuration}.binlog") .SetConfiguration(configuration) .WithTarget("Install"), ToolPath = dotnetPath, @@ -45,10 +50,21 @@ Task("dotnet-local-workloads") }); Task("dotnet-buildtasks") + .WithCriteria(Argument("sln", null) == null) .IsDependentOn("dotnet") .Does(() => { RunMSBuildWithDotNet("./Microsoft.Maui.BuildTasks.slnf"); + }) + .OnError(exception => + { + if (IsTarget("VS")) + { + pendingException = exception; + return; + } + + throw exception; }); Task("dotnet-build") @@ -80,7 +96,7 @@ Task("dotnet-templates") var dn = localDotnet ? dotnetPath : "dotnet"; - var templatesTest = tempDirectory.Combine("templatesTest"); + var templatesTest = GetTempDirectory().Combine("templatesTest"); EnsureDirectoryExists(templatesTest); CleanDirectories(templatesTest.FullPath); @@ -210,6 +226,7 @@ Task("dotnet-test") }); Task("dotnet-pack-maui") + .WithCriteria(RunPackTarget()) .Does(() => { DotNetCoreTool("pwsh", new DotNetCoreToolSettings @@ -220,6 +237,7 @@ Task("dotnet-pack-maui") }); Task("dotnet-pack-additional") + .WithCriteria(RunPackTarget()) .Does(() => { // Download some additional symbols that need to be archived along with the maui symbols: @@ -241,6 +259,7 @@ Task("dotnet-pack-additional") }); Task("dotnet-pack-library-packs") + .WithCriteria(RunPackTarget()) .Does(() => { var tempDir = $"./artifacts/library-packs-temp"; @@ -270,6 +289,7 @@ Task("dotnet-pack-library-packs") }); Task("dotnet-pack") + .WithCriteria(RunPackTarget()) .IsDependentOn("dotnet-pack-maui") .IsDependentOn("dotnet-pack-additional") .IsDependentOn("dotnet-pack-library-packs"); @@ -291,11 +311,11 @@ Task("dotnet-diff") else { // clean all working folders - var diffCacheDir = tempDirectory.Combine("diffCache"); + var diffCacheDir = GetTempDirectory().Combine("diffCache"); EnsureDirectoryExists(diffCacheDir); CleanDirectories(diffCacheDir.FullPath); - EnsureDirectoryExists(diffDirectory); - CleanDirectories(diffDirectory.FullPath); + EnsureDirectoryExists(GetDiffDirectory()); + CleanDirectories(GetDiffDirectory().FullPath); // run the diff foreach (var nupkg in nupkgs) @@ -311,7 +331,7 @@ Task("dotnet-diff") .Append("--prerelease") .Append("--group-ids") .Append("--ignore-unchanged") - .AppendSwitchQuoted("--output", diffDirectory.FullPath) + .AppendSwitchQuoted("--output", GetDiffDirectory().FullPath) .AppendSwitchQuoted("--cache", diffCacheDir.FullPath) }); } @@ -326,7 +346,7 @@ Task("dotnet-diff") Information("Unable to clean up diff cache directory."); } - var diffs = GetFiles($"{diffDirectory}/**/*.md"); + var diffs = GetFiles($"{GetDiffDirectory()}/**/*.md"); if (!diffs.Any()) { Warning($"##vso[task.logissue type=warning]No NuGet diffs were found."); @@ -366,48 +386,58 @@ Task("dotnet-diff") }); // Tasks for Local Development - -Task("VS-DOGFOOD") - .Description("Provisions .NET 6 and launches an instance of Visual Studio using it.") +Task("VS") + .Description("Provisions .NET 6, and launches an instance of Visual Studio using it.") + .IsDependentOn("Clean") .IsDependentOn("dotnet") + .IsDependentOn("dotnet-buildtasks") + .IsDependentOn("dotnet-pack") // Run conditionally .Does(() => { - StartVisualStudioForDotNet6(null); - }); + if (pendingException != null) + { + Error($"{pendingException}"); + Error("!!!!BUILD TASKS FAILED: !!!!!"); + } + + StartVisualStudioForDotNet6(); + }); +// Keeping this for users that are already using this. Task("VS-NET6") .Description("Provisions .NET 6 and launches an instance of Visual Studio using it.") .IsDependentOn("Clean") - .IsDependentOn("dotnet") - .IsDependentOn("dotnet-buildtasks") + .IsDependentOn("VS") .Does(() => { - StartVisualStudioForDotNet6(); + Warning("!!!!Please switch to using the `VS` target.!!!!"); }); -Task("VS-WINUI") - .Description("Provisions .NET 6 and launches an instance of Visual Studio with WinUI projects.") - .IsDependentOn("VS-NET6"); - // .IsDependentOn("dotnet") WINUI currently can't launch application with local dotnet - // .IsDependentOn("dotnet-buildtasks") +bool RunPackTarget() +{ + // Is the user running the pack target explicitly? + if (TargetStartsWith("dotnet-pack")) + return true; -Task("VS-ANDROID") - .Description("Provisions .NET 6 and launches an instance of Visual Studio with Android projects.") - .IsDependentOn("Clean") - .IsDependentOn("dotnet") - .IsDependentOn("dotnet-buildtasks") - .Does(() => + // If the default target is running then let the pack target run + if (IsTarget("Default")) + return true; + + // Does the user want to run a pack as part of a different target? + if (HasArgument("pack")) + return true; + + // If the request is to open a different sln then let's see if pack has ever run + // if it hasn't then lets pack maui so the sln will open + if (Argument("sln", null) != null) { - DotNetCoreRestore("./Microsoft.Maui.sln", new DotNetCoreRestoreSettings - { - ToolPath = dotnetPath - }); + var mauiPacks = MakeAbsolute(Directory("./bin/dotnet/packs/Microsoft.Maui.Sdk")).ToString(); + if (!DirectoryExists(mauiPacks)) + return true; + } - // VS has trouble building all the references correctly so this makes sure everything is built - // and we're ready to go right when VS launches - RunMSBuildWithDotNet("./src/Controls/samples/Controls.Sample/Maui.Controls.Sample.csproj"); - StartVisualStudioForDotNet6("./Microsoft.Maui.Droid.sln"); - }); + return false; +} string FindMSBuild() { @@ -431,6 +461,30 @@ string FindMSBuild() return "msbuild"; } + +Dictionary GetDotNetEnvironmentVariables() +{ + Dictionary envVariables = new Dictionary(); + var dotnet = MakeAbsolute(Directory("./bin/dotnet/")).ToString(); + + envVariables.Add("DOTNET_INSTALL_DIR", dotnet); + envVariables.Add("DOTNET_ROOT", dotnet); + envVariables.Add("DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR", dotnet); + envVariables.Add("DOTNET_MULTILEVEL_LOOKUP", "0"); + envVariables.Add("MSBuildEnableWorkloadResolver", "true"); + + var existingPath = EnvironmentVariable("PATH"); + Information(dotnet + ":" + existingPath); + envVariables.Add("PATH", dotnet + ":" + existingPath); + + // Get "full" .binlog in Project System Tools + if (HasArgument("debug")) + envVariables.Add("MSBuildDebugEngine", "1"); + + return envVariables; + +} + void SetDotNetEnvironmentVariables() { var dotnet = MakeAbsolute(Directory("./bin/dotnet/")).ToString(); @@ -441,11 +495,22 @@ void SetDotNetEnvironmentVariables() SetEnvironmentVariable("DOTNET_MULTILEVEL_LOOKUP", "0"); SetEnvironmentVariable("MSBuildEnableWorkloadResolver", "true"); SetEnvironmentVariable("PATH", dotnet, prepend: true); + + // Get "full" .binlog in Project System Tools + if (HasArgument("debug")) + SetEnvironmentVariable("MSBuildDebugEngine", "1"); } -void StartVisualStudioForDotNet6(string sln = null) +void StartVisualStudioForDotNet6() { - if (sln == null) + string sln = Argument("sln", null); + + bool includePrerelease = true; + + if (!String.IsNullOrEmpty(vsVersion)) + includePrerelease = (vsVersion == "preview"); + + if (String.IsNullOrWhiteSpace(sln)) { if (IsRunningOnWindows()) { @@ -453,35 +518,34 @@ void StartVisualStudioForDotNet6(string sln = null) } else { - sln = "./Microsoft.Maui-mac.slnf"; + sln = "_omnisharp.sln"; } } - if (isCIBuild) + + if (IsCIBuild()) { - Information("This target should not run on CI."); + Error("This target should not run on CI."); return; } + if(localDotnet) { SetDotNetEnvironmentVariables(); SetEnvironmentVariable("_ExcludeMauiProjectCapability", "true"); } + if (IsRunningOnWindows()) { - bool includePrerelease = true; - - if (!String.IsNullOrEmpty(vsVersion)) - includePrerelease = (vsVersion == "preview"); - var vsLatest = VSWhereLatest(new VSWhereLatestSettings { IncludePrerelease = includePrerelease, }); if (vsLatest == null) throw new Exception("Unable to find Visual Studio!"); - + StartProcess(vsLatest.CombineWithFilePath("./Common7/IDE/devenv.exe"), sln); } else { - StartProcess("open", new ProcessSettings{ Arguments = sln }); + + StartProcess("open", new ProcessSettings{ Arguments = sln, EnvironmentVariables = GetDotNetEnvironmentVariables() }); } } @@ -501,8 +565,8 @@ void RunMSBuildWithDotNet( var name = System.IO.Path.GetFileNameWithoutExtension(sln); var type = useDotNetBuild ? "dotnet" : "msbuild"; var binlog = string.IsNullOrEmpty(targetFramework) ? - $"\"{logDirectory}/{name}-{configuration}-{target}-{type}.binlog\"" : - $"\"{logDirectory}/{name}-{configuration}-{target}-{targetFramework}-{type}.binlog\""; + $"\"{GetLogDirectory()}/{name}-{configuration}-{target}-{type}.binlog\"" : + $"\"{GetLogDirectory()}/{name}-{configuration}-{target}-{targetFramework}-{type}.binlog\""; if(localDotnet) SetDotNetEnvironmentVariables(); @@ -533,6 +597,7 @@ void RunMSBuildWithDotNet( { MSBuildSettings = msbuildSettings, }; + dotnetBuildSettings.ArgumentCustomization = args => { if (!restore) @@ -588,7 +653,7 @@ void RunMSBuildWithDotNet( void RunTestWithLocalDotNet(string csproj) { var name = System.IO.Path.GetFileNameWithoutExtension(csproj); - var binlog = $"{logDirectory}/{name}-{configuration}.binlog"; + var binlog = $"{GetLogDirectory()}/{name}-{configuration}.binlog"; var results = $"{name}-{configuration}.trx"; if(localDotnet) @@ -601,7 +666,7 @@ void RunTestWithLocalDotNet(string csproj) ToolPath = dotnetPath, NoBuild = true, Logger = $"trx;LogFileName={results}", - ResultsDirectory = testResultsDirectory, + ResultsDirectory = GetTestResultsDirectory(), ArgumentCustomization = args => args.Append($"-bl:{binlog}") }); } diff --git a/eng/cake/helpers.cake b/eng/cake/helpers.cake index 7c4ae849c0b8..628bec7ccfa5 100644 --- a/eng/cake/helpers.cake +++ b/eng/cake/helpers.cake @@ -1,4 +1,7 @@ +bool isCleanSet = HasArgument("clean") || IsTarget("clean"); + Task("Clean") + .WithCriteria(isCleanSet) .Description("Deletes all the obj/bin directories") .Does(() => { @@ -21,7 +24,34 @@ Task("Clean") } }); +DirectoryPath _artifactStagingDirectory; +DirectoryPath GetArtifactStagingDirectory() => + _artifactStagingDirectory ??= MakeAbsolute(Directory(EnvironmentVariable("BUILD_ARTIFACTSTAGINGDIRECTORY", "artifacts"))); + +DirectoryPath _logDirectory; +DirectoryPath GetLogDirectory() => + _logDirectory ??= MakeAbsolute(Directory(EnvironmentVariable("LogDirectory", $"{GetArtifactStagingDirectory()}/logs"))); + +DirectoryPath _testResultsDirectory; +DirectoryPath GetTestResultsDirectory() => + _testResultsDirectory ??= MakeAbsolute(Directory(EnvironmentVariable("TestResultsDirectory", $"{GetArtifactStagingDirectory()}/test-results"))); + +DirectoryPath _diffDirectory; +DirectoryPath GetDiffDirectory() => + _diffDirectory ??= MakeAbsolute(Directory(EnvironmentVariable("ApiDiffDirectory", $"{GetArtifactStagingDirectory()}/api-diff"))); + +DirectoryPath _tempDirectory; +DirectoryPath GetTempDirectory() => + _tempDirectory ??= MakeAbsolute(Directory(EnvironmentVariable("AGENT_TEMPDIRECTORY", EnvironmentVariable("TEMP", EnvironmentVariable("TMPDIR", "../maui-temp")) + "/" + Guid.NewGuid()))); +string GetAgentName() => + EnvironmentVariable("AGENT_NAME", ""); + +bool IsCIBuild() => + !String.IsNullOrWhiteSpace(GetAgentName()); + +bool IsHostedAgent() => + GetAgentName().StartsWith("Azure Pipelines") || GetAgentName().StartsWith("Hosted Agent"); T GetBuildVariable(string key, T defaultValue) { @@ -85,3 +115,9 @@ void SetEnvironmentVariable(string name, string value, bool prepend = false) Information("Setting environment variable: {0} = '{1}'", name, value); } + +bool IsTarget(string target) => + Argument("target", "Default").Equals(target, StringComparison.InvariantCultureIgnoreCase); + +bool TargetStartsWith(string target) => + Argument("target", "Default").StartsWith(target, StringComparison.InvariantCultureIgnoreCase); diff --git a/eng/package.ps1 b/eng/package.ps1 index b672ee334cde..ac0be1097351 100644 --- a/eng/package.ps1 +++ b/eng/package.ps1 @@ -101,12 +101,16 @@ if ($IsWindows) else { $oldPATH=$env:PATH + $oldDOTNET_ROOT=$env:DOTNET_ROOT try { # Put our local dotnet on $PATH $env:PATH=($dotnet + [IO.Path]::PathSeparator + $env:PATH) $dotnet_tool = Join-Path $dotnet dotnet + # This tells .NET to use the bootstrapped runtime + $env:DOTNET_ROOT=$dotnet + # Build with ./bin/dotnet/dotnet & $dotnet_tool pack $slnMac ` -c:$configuration ` @@ -117,5 +121,6 @@ else finally { $env:PATH=$oldPATH + $env:DOTNET_ROOT=$oldDOTNET_ROOT } } diff --git a/src/DotNet/DotNet.csproj b/src/DotNet/DotNet.csproj index c615666631bf..8cc5edff2147 100644 --- a/src/DotNet/DotNet.csproj +++ b/src/DotNet/DotNet.csproj @@ -103,6 +103,14 @@ + + +