| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418 | 
							- using System;
 
- using System.Diagnostics;
 
- using System.IO;
 
- using System.IO.Compression;
 
- using System.Linq;
 
- using System.Runtime.InteropServices;
 
- using System.Threading.Tasks;
 
- using System.Xml.Linq;
 
- using Nuke.Common;
 
- using Nuke.Common.Tooling;
 
- using Nuke.Common.Tools.DotNet;
 
- using Nuke.Common.Tools.Npm;
 
- using static Nuke.Common.EnvironmentInfo;
 
- using static Nuke.Common.IO.FileSystemTasks;
 
- using static Nuke.Common.IO.PathConstruction;
 
- using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
 
- using static Nuke.Common.Tools.DotNet.DotNetTasks;
 
- using static Nuke.Common.Tools.Xunit.XunitTasks;
 
- using static Nuke.Common.Tools.VSWhere.VSWhereTasks;
 
- using static Serilog.Log;
 
- using MicroCom.CodeGenerator;
 
- using Nuke.Common.IO;
 
- /*
 
-  Before editing this file, install support plugin for your IDE,
 
-  running and debugging a particular target (optionally without deps) would be way easier
 
-  ReSharper/Rider - https://plugins.jetbrains.com/plugin/10803-nuke-support
 
-  VSCode - https://marketplace.visualstudio.com/items?itemName=nuke.support
 
-  */
 
- partial class Build : NukeBuild
 
- {
 
-     BuildParameters Parameters { get; set; }
 
-     [PackageExecutable("Microsoft.DotNet.ApiCompat.Tool", "Microsoft.DotNet.ApiCompat.Tool.dll", Framework = "net6.0")]
 
-     Tool ApiCompatTool;
 
-     
 
-     [PackageExecutable("Microsoft.DotNet.GenAPI.Tool", "Microsoft.DotNet.GenAPI.Tool.dll", Framework = "net8.0")]
 
-     Tool ApiGenTool;
 
-     
 
-     protected override void OnBuildInitialized()
 
-     {
 
-         Parameters = new BuildParameters(this, ScheduledTargets.Contains(BuildToNuGetCache));
 
-         Information("Building version {0} of Avalonia ({1}) using version {2} of Nuke.",
 
-             Parameters.Version,
 
-             Parameters.Configuration,
 
-             typeof(NukeBuild).Assembly.GetName().Version.ToString());
 
-         if (Parameters.IsLocalBuild)
 
-         {
 
-             Information("Repository Name: " + Parameters.RepositoryName);
 
-             Information("Repository Branch: " + Parameters.RepositoryBranch);
 
-         }
 
-         Information("Configuration: " + Parameters.Configuration);
 
-         Information("IsLocalBuild: " + Parameters.IsLocalBuild);
 
-         Information("IsRunningOnUnix: " + Parameters.IsRunningOnUnix);
 
-         Information("IsRunningOnWindows: " + Parameters.IsRunningOnWindows);
 
-         Information("IsRunningOnAzure:" + Parameters.IsRunningOnAzure);
 
-         Information("IsPullRequest: " + Parameters.IsPullRequest);
 
-         Information("IsMainRepo: " + Parameters.IsMainRepo);
 
-         Information("IsMasterBranch: " + Parameters.IsMasterBranch);
 
-         Information("IsReleaseBranch: " + Parameters.IsReleaseBranch);
 
-         Information("IsReleasable: " + Parameters.IsReleasable);
 
-         Information("IsMyGetRelease: " + Parameters.IsMyGetRelease);
 
-         Information("IsNuGetRelease: " + Parameters.IsNuGetRelease);
 
-         void ExecWait(string preamble, string command, string args)
 
-         {
 
-             Console.WriteLine(preamble);
 
-             Process.Start(new ProcessStartInfo(command, args) {UseShellExecute = false}).WaitForExit();
 
-         }
 
-         ExecWait("dotnet version:", "dotnet", "--info");
 
-         ExecWait("dotnet workloads:", "dotnet", "workload list");
 
-         Information("Processor count: " + Environment.ProcessorCount);
 
-         Information("Available RAM: " + GC.GetGCMemoryInfo().TotalAvailableMemoryBytes / 0x100000 + "MB");
 
-     }
 
-     DotNetConfigHelper ApplySettingCore(DotNetConfigHelper c)
 
-     {
 
-         if (Parameters.IsRunningOnAzure)
 
-             c.AddProperty("JavaSdkDirectory", GetVariable<string>("JAVA_HOME_11_X64"));
 
-         c.AddProperty("PackageVersion", Parameters.Version)
 
-             .SetConfiguration(Parameters.Configuration)
 
-             .SetVerbosity(DotNetVerbosity.Minimal);
 
-         if (Parameters.IsPackingToLocalCache)
 
-             c
 
-                 .AddProperty("ForcePackAvaloniaNative", "True")
 
-                 .AddProperty("SkipObscurePlatforms", "True")
 
-                 .AddProperty("SkipBuildingSamples", "True")
 
-                 .AddProperty("SkipBuildingTests", "True");
 
-         return c;
 
-     }
 
-     DotNetBuildSettings ApplySetting(DotNetBuildSettings c, Configure<DotNetBuildSettings> configurator = null) =>
 
-         ApplySettingCore(c).Build.Apply(configurator);
 
-     DotNetPackSettings ApplySetting(DotNetPackSettings c, Configure<DotNetPackSettings> configurator = null) =>
 
-         ApplySettingCore(c).Pack.Apply(configurator);
 
-     DotNetTestSettings ApplySetting(DotNetTestSettings c, Configure<DotNetTestSettings> configurator = null) =>
 
-         ApplySettingCore(c).Test.Apply(configurator);
 
-     Target Clean => _ => _.Executes(() =>
 
-     {
 
-         Parameters.BuildDirs.ForEach(DeleteDirectory);
 
-         Parameters.BuildDirs.ForEach(EnsureCleanDirectory);
 
-         EnsureCleanDirectory(Parameters.ArtifactsDir);
 
-         EnsureCleanDirectory(Parameters.NugetIntermediateRoot);
 
-         EnsureCleanDirectory(Parameters.NugetRoot);
 
-         EnsureCleanDirectory(Parameters.ZipRoot);
 
-         EnsureCleanDirectory(Parameters.TestResultsRoot);
 
-     });
 
-     Target CompileHtmlPreviewer => _ => _
 
-         .DependsOn(Clean)
 
-         .OnlyWhenStatic(() => !Parameters.SkipPreviewer)
 
-         .Executes(() =>
 
-         {
 
-             var webappDir = RootDirectory / "src" / "Avalonia.DesignerSupport" / "Remote" / "HtmlTransport" / "webapp";
 
-             NpmTasks.NpmInstall(c => c
 
-                 .SetProcessWorkingDirectory(webappDir)
 
-                 .SetProcessArgumentConfigurator(a => a.Add("--silent")));
 
-             NpmTasks.NpmRun(c => c
 
-                 .SetProcessWorkingDirectory(webappDir)
 
-                 .SetCommand("dist"));
 
-         });
 
-     Target CompileNative => _ => _
 
-         .DependsOn(Clean)
 
-         .DependsOn(GenerateCppHeaders)
 
-         .OnlyWhenStatic(() => EnvironmentInfo.IsOsx)
 
-         .Executes(() =>
 
-         {
 
-             var project = $"{RootDirectory}/native/Avalonia.Native/src/OSX/Avalonia.Native.OSX.xcodeproj/";
 
-             var args = $"-project {project} -configuration {Parameters.Configuration} CONFIGURATION_BUILD_DIR={RootDirectory}/Build/Products/Release";
 
-             ProcessTasks.StartProcess("xcodebuild", args).AssertZeroExitCode();
 
-         });
 
-     Target Compile => _ => _
 
-         .DependsOn(Clean, CompileNative)
 
-         .DependsOn(CompileHtmlPreviewer)
 
-         .Executes(() =>
 
-         {
 
-             DotNetBuild(c => ApplySetting(c)
 
-                 .SetProjectFile(Parameters.MSBuildSolution)
 
-             );
 
-         });
 
-     Target OutputVersion => _ => _
 
-         .Requires(() => VersionOutputDir)
 
-         .Executes(() =>
 
-         {
 
-             var versionFile = Path.Combine(Parameters.VersionOutputDir, "version.txt");
 
-             var currentBuildVersion = Parameters.Version;
 
-             Console.WriteLine("Version is: " + currentBuildVersion);
 
-             File.WriteAllText(versionFile, currentBuildVersion);
 
-             var prIdFile = Path.Combine(Parameters.VersionOutputDir, "prId.txt");
 
-             var prId = Environment.GetEnvironmentVariable("SYSTEM_PULLREQUEST_PULLREQUESTNUMBER");
 
-             Console.WriteLine("PR Number  is: " + prId);
 
-             File.WriteAllText(prIdFile, prId);
 
-         });
 
-     void RunCoreTest(string projectName)
 
-     {
 
-         Information($"Running tests from {projectName}");
 
-         var project = RootDirectory.GlobFiles(@$"**\{projectName}.csproj").FirstOrDefault()
 
-             ?? throw new InvalidOperationException($"Project {projectName} doesn't exist");
 
-         // Nuke and MSBuild tools have build-in helpers to get target frameworks from the project.
 
-         // Unfortunately, it gets broken with every second SDK update, so we had to do it manually.
 
-         var fileXml = XDocument.Parse(File.ReadAllText(project));
 
-         var targetFrameworks = fileXml.Descendants("TargetFrameworks")
 
-             .FirstOrDefault()?.Value.Split(';').Select(f => f.Trim());
 
-         if (targetFrameworks is null)
 
-         {
 
-             var targetFramework = fileXml.Descendants("TargetFramework").FirstOrDefault()?.Value;
 
-             if (targetFramework is not null)
 
-             {
 
-                 targetFrameworks = new[] { targetFramework };
 
-             }
 
-         }
 
-         if (targetFrameworks is null)
 
-         {
 
-             throw new InvalidOperationException("No target frameworks were found in the test project");
 
-         }
 
-         foreach (var fw in targetFrameworks)
 
-         {
 
-             var tfm = fw;
 
-             if (tfm == "$(AvsCurrentTargetFramework)")
 
-             {
 
-                 tfm = "net8.0";
 
-             }
 
-             if (tfm == "$(AvsLegacyTargetFrameworks)")
 
-             {
 
-                 tfm = "net6.0";
 
-             }
 
-             
 
-             if (tfm.StartsWith("net4")
 
-                 && (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
 
-                 && Environment.GetEnvironmentVariable("FORCE_LINUX_TESTS") != "1")
 
-             {
 
-                 Information($"Skipping {projectName} ({tfm}) tests on *nix - https://github.com/mono/mono/issues/13969");
 
-                 continue;
 
-             }
 
-             Information($"Running for {projectName} ({tfm}) ...");
 
-             DotNetTest(c => ApplySetting(c)
 
-                 .SetProjectFile(project)
 
-                 .SetFramework(tfm)
 
-                 .EnableNoBuild()
 
-                 .EnableNoRestore()
 
-                 .When(Parameters.PublishTestResults, _ => _
 
-                     .SetLoggers("trx")
 
-                     .SetResultsDirectory(Parameters.TestResultsRoot)));
 
-         }
 
-     }
 
-     Target RunHtmlPreviewerTests => _ => _
 
-         .DependsOn(CompileHtmlPreviewer)
 
-         .OnlyWhenStatic(() => !(Parameters.SkipPreviewer || Parameters.SkipTests))
 
-         .Executes(() =>
 
-         {
 
-             var webappTestDir = RootDirectory / "tests" / "Avalonia.DesignerSupport.Tests" / "Remote" / "HtmlTransport" / "webapp";
 
-             NpmTasks.NpmInstall(c => c
 
-                 .SetProcessWorkingDirectory(webappTestDir)
 
-                 .SetProcessArgumentConfigurator(a => a.Add("--silent")));
 
-             NpmTasks.NpmRun(c => c
 
-                 .SetProcessWorkingDirectory(webappTestDir)
 
-                 .SetCommand("test"));
 
-         });
 
-     Target RunCoreLibsTests => _ => _
 
-         .OnlyWhenStatic(() => !Parameters.SkipTests)
 
-         .DependsOn(Compile)
 
-         .Executes(() =>
 
-         {
 
-             RunCoreTest("Avalonia.Base.UnitTests");
 
-             RunCoreTest("Avalonia.Controls.UnitTests");
 
-             RunCoreTest("Avalonia.Controls.DataGrid.UnitTests");
 
-             RunCoreTest("Avalonia.Markup.UnitTests");
 
-             RunCoreTest("Avalonia.Markup.Xaml.UnitTests");
 
-             RunCoreTest("Avalonia.Skia.UnitTests");
 
-             RunCoreTest("Avalonia.ReactiveUI.UnitTests");
 
-             RunCoreTest("Avalonia.Headless.NUnit.UnitTests");
 
-             RunCoreTest("Avalonia.Headless.XUnit.UnitTests");
 
-         });
 
-     Target RunRenderTests => _ => _
 
-         .OnlyWhenStatic(() => !Parameters.SkipTests)
 
-         .DependsOn(Compile)
 
-         .Executes(() =>
 
-         {
 
-             RunCoreTest("Avalonia.Skia.RenderTests");
 
-             if (Parameters.IsRunningOnWindows)
 
-                 RunCoreTest("Avalonia.Direct2D1.RenderTests");
 
-         });
 
-     Target RunToolsTests => _ => _
 
-         .OnlyWhenStatic(() => !Parameters.SkipTests)
 
-         .DependsOn(Compile)
 
-         .Executes(() =>
 
-         {
 
-             RunCoreTest("Avalonia.Generators.Tests");
 
-             if (Parameters.IsRunningOnWindows)
 
-                 RunCoreTest("Avalonia.DesignerSupport.Tests");
 
-         });
 
-     Target RunLeakTests => _ => _
 
-         .OnlyWhenStatic(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
 
-         .DependsOn(Compile)
 
-         .Executes(() =>
 
-         {
 
-             void DoMemoryTest()
 
-             {
 
-                 RunCoreTest("Avalonia.LeakTests");
 
-             }
 
-             ControlFlow.ExecuteWithRetry(DoMemoryTest, delay: TimeSpan.FromMilliseconds(3));
 
-         });
 
-     Target ZipFiles => _ => _
 
-         .After(CreateNugetPackages, Compile, RunCoreLibsTests, Package)
 
-         .Executes(() =>
 
-         {
 
-             var data = Parameters;
 
-             Zip(data.ZipNuGetArtifacts, data.NugetRoot);
 
-         });
 
-     Target CreateIntermediateNugetPackages => _ => _
 
-         .DependsOn(Compile)
 
-         .After(RunTests)
 
-         .Executes(() =>
 
-         {
 
-             DotNetPack(c => ApplySetting(c).SetProject(Parameters.MSBuildSolution));
 
-         });
 
-     Target CreateNugetPackages => _ => _
 
-         .DependsOn(CreateIntermediateNugetPackages)
 
-         .Executes(() =>
 
-         {
 
-             BuildTasksPatcher.PatchBuildTasksInPackage(Parameters.NugetIntermediateRoot / "Avalonia.Build.Tasks." +
 
-                                                        Parameters.Version + ".nupkg");
 
-             var config = Numerge.MergeConfiguration.LoadFile(RootDirectory / "nukebuild" / "numerge.config");
 
-             EnsureCleanDirectory(Parameters.NugetRoot);
 
-             if(!Numerge.NugetPackageMerger.Merge(Parameters.NugetIntermediateRoot, Parameters.NugetRoot, config,
 
-                 new NumergeNukeLogger()))
 
-                 throw new Exception("Package merge failed");
 
-             RefAssemblyGenerator.GenerateRefAsmsInPackage(
 
-                 Parameters.NugetRoot / $"Avalonia.{Parameters.Version}.nupkg",
 
-                 Parameters.NugetRoot / $"Avalonia.{Parameters.Version}.snupkg");
 
-         });
 
-     
 
-     Target ValidateApiDiff => _ => _
 
-         .DependsOn(CreateNugetPackages)
 
-         .Executes(async () =>
 
-         {
 
-             await Task.WhenAll(
 
-                 Directory.GetFiles(Parameters.NugetRoot, "*.nupkg").Select(nugetPackage => ApiDiffHelper.ValidatePackage(
 
-                     ApiCompatTool, nugetPackage, Parameters.ApiValidationBaseline,
 
-                     Parameters.ApiValidationSuppressionFiles, Parameters.UpdateApiValidationSuppression)));
 
-         });
 
-     
 
-     Target OutputApiDiff => _ => _
 
-         .DependsOn(CreateNugetPackages)
 
-         .Executes(async () =>
 
-         {
 
-             await Task.WhenAll(
 
-                 Directory.GetFiles(Parameters.NugetRoot, "*.nupkg").Select(nugetPackage => ApiDiffHelper.GetDiff(
 
-                     ApiGenTool, RootDirectory / "api" / "diff",
 
-                     nugetPackage, Parameters.ApiValidationBaseline)));
 
-         });
 
-     
 
-     Target RunTests => _ => _
 
-         .DependsOn(RunCoreLibsTests)
 
-         .DependsOn(RunRenderTests)
 
-         .DependsOn(RunToolsTests)
 
-         .DependsOn(RunHtmlPreviewerTests)
 
-         .DependsOn(RunLeakTests);
 
-     Target Package => _ => _
 
-         .DependsOn(RunTests)
 
-         .DependsOn(CreateNugetPackages)
 
-         .DependsOn(ValidateApiDiff);
 
-     Target CiAzureLinux => _ => _
 
-         .DependsOn(RunTests);
 
-     Target CiAzureOSX => _ => _
 
-         .DependsOn(Package)
 
-         .DependsOn(ZipFiles);
 
-     Target CiAzureWindows => _ => _
 
-         .DependsOn(Package)
 
-         .DependsOn(ZipFiles);
 
-     Target BuildToNuGetCache => _ => _
 
-         .DependsOn(CreateNugetPackages)
 
-         .Executes(() =>
 
-         {
 
-             if (!Parameters.IsPackingToLocalCache)
 
-                 throw new InvalidOperationException();
 
-             
 
-             foreach (var path in Parameters.NugetRoot.GlobFiles("*.nupkg"))
 
-             {
 
-                 using var f = File.Open(path.ToString(), FileMode.Open, FileAccess.Read);
 
-                 using var zip = new ZipArchive(f, ZipArchiveMode.Read);
 
-                 var nuspecEntry = zip.Entries.First(e => e.FullName.EndsWith(".nuspec") && e.FullName == e.Name);
 
-                 var packageId = XDocument.Load(nuspecEntry.Open()).Document.Root
 
-                     .Elements().First(x => x.Name.LocalName == "metadata")
 
-                     .Elements().First(x => x.Name.LocalName == "id").Value;
 
-                 var packagePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile),
 
-                     ".nuget",
 
-                     "packages",
 
-                     packageId.ToLowerInvariant(),
 
-                     BuildParameters.LocalBuildVersion);
 
-                 if (Directory.Exists(packagePath))
 
-                     Directory.Delete(packagePath, true);
 
-                 Directory.CreateDirectory(packagePath);
 
-                 zip.ExtractToDirectory(packagePath);
 
-                 File.WriteAllText(Path.Combine(packagePath, ".nupkg.metadata"), @"{
 
-   ""version"": 2,
 
-   ""contentHash"": ""e900dFK7jHJ2WcprLcgJYQoOMc6ejRTwAAMi0VGOFbSczcF98ZDaqwoQIiyqpAwnja59FSbV+GUUXfc3vaQ2Jg=="",
 
-   ""source"": ""https://api.nuget.org/v3/index.json""
 
- }");
 
-             }
 
-         });
 
-     Target GenerateCppHeaders => _ => _.Executes(() =>
 
-     {
 
-         var file = MicroComCodeGenerator.Parse(
 
-             File.ReadAllText(RootDirectory / "src" / "Avalonia.Native" / "avn.idl"));
 
-         File.WriteAllText(RootDirectory / "native" / "Avalonia.Native" / "inc" / "avalonia-native.h",
 
-             file.GenerateCppHeader());
 
-     });
 
-     public static int Main() =>
 
-         RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
 
-             ? Execute<Build>(x => x.Package)
 
-             : Execute<Build>(x => x.RunTests);
 
- }
 
- public static class ToolSettingsExtensions
 
- {
 
-     public static T Apply<T>(this T settings, Configure<T> configurator)
 
-     {
 
-         return configurator != null ? configurator(settings) : settings;
 
-     }
 
- }
 
 
  |