Build.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.IO;
  5. using System.Linq;
  6. using System.Runtime.InteropServices;
  7. using System.Threading;
  8. using Nuke.Common;
  9. using Nuke.Common.Git;
  10. using Nuke.Common.ProjectModel;
  11. using Nuke.Common.Tooling;
  12. using Nuke.Common.Tools.DotNet;
  13. using Nuke.Common.Tools.MSBuild;
  14. using Nuke.Common.Utilities;
  15. using static Nuke.Common.EnvironmentInfo;
  16. using static Nuke.Common.IO.FileSystemTasks;
  17. using static Nuke.Common.IO.PathConstruction;
  18. using static Nuke.Common.Tools.MSBuild.MSBuildTasks;
  19. using static Nuke.Common.Tools.DotNet.DotNetTasks;
  20. using static Nuke.Common.Tools.Xunit.XunitTasks;
  21. /*
  22. Before editing this file, install support plugin for your IDE,
  23. running and debugging a particular target (optionally without deps) would be way easier
  24. ReSharper/Rider - https://plugins.jetbrains.com/plugin/10803-nuke-support
  25. VSCode - https://marketplace.visualstudio.com/items?itemName=nuke.support
  26. */
  27. partial class Build : NukeBuild
  28. {
  29. BuildParameters Parameters { get; set; }
  30. protected override void OnBuildInitialized()
  31. {
  32. Parameters = new BuildParameters(this);
  33. Information("Building version {0} of Avalonia ({1}) using version {2} of Nuke.",
  34. Parameters.Version,
  35. Parameters.Configuration,
  36. typeof(NukeBuild).Assembly.GetName().Version.ToString());
  37. if (Parameters.IsLocalBuild)
  38. {
  39. Information("Repository Name: " + Parameters.RepositoryName);
  40. Information("Repository Branch: " + Parameters.RepositoryBranch);
  41. }
  42. Information("Configuration: " + Parameters.Configuration);
  43. Information("IsLocalBuild: " + Parameters.IsLocalBuild);
  44. Information("IsRunningOnUnix: " + Parameters.IsRunningOnUnix);
  45. Information("IsRunningOnWindows: " + Parameters.IsRunningOnWindows);
  46. Information("IsRunningOnAppVeyor: " + Parameters.IsRunningOnAppVeyor);
  47. Information("IsRunnongOnAzure:" + Parameters.IsRunningOnAzure);
  48. Information("IsPullRequest: " + Parameters.IsPullRequest);
  49. Information("IsMainRepo: " + Parameters.IsMainRepo);
  50. Information("IsMasterBranch: " + Parameters.IsMasterBranch);
  51. Information("IsReleaseBranch: " + Parameters.IsReleaseBranch);
  52. Information("IsTagged: " + Parameters.IsTagged);
  53. Information("IsReleasable: " + Parameters.IsReleasable);
  54. Information("IsMyGetRelease: " + Parameters.IsMyGetRelease);
  55. Information("IsNuGetRelease: " + Parameters.IsNuGetRelease);
  56. }
  57. Target Clean => _ => _.Executes(() =>
  58. {
  59. var data = Parameters;
  60. DeleteDirectories(data.BuildDirs);
  61. EnsureCleanDirectories(data.BuildDirs);
  62. EnsureCleanDirectory(data.ArtifactsDir);
  63. EnsureCleanDirectory(data.NugetRoot);
  64. EnsureCleanDirectory(data.ZipRoot);
  65. EnsureCleanDirectory(data.TestResultsRoot);
  66. });
  67. Target Compile => _ => _
  68. .DependsOn(Clean)
  69. .Executes(() =>
  70. {
  71. var data = Parameters;
  72. if (data.IsRunningOnWindows)
  73. MSBuild(data.MSBuildSolution, c => c
  74. .SetConfiguration(data.Configuration)
  75. .SetVerbosity(MSBuildVerbosity.Minimal)
  76. .AddProperty("PackageVersion", Parameters.Version)
  77. .AddProperty("iOSRoslynPathHackRequired", "true")
  78. .SetToolsVersion(MSBuildToolsVersion._15_0)
  79. .AddTargets("Restore", "Build")
  80. );
  81. else
  82. DotNetBuild(Parameters.MSBuildSolution, c => c
  83. .AddProperty("PackageVersion", Parameters.Version)
  84. .SetConfiguration(Parameters.Configuration)
  85. );
  86. });
  87. void RunCoreTest(string project, bool coreOnly = false)
  88. {
  89. if(!project.EndsWith(".csproj"))
  90. project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj");
  91. Information("Running tests from " + project);
  92. var frameworks = new List<string>(){"netcoreapp2.0"};
  93. foreach(var fw in frameworks)
  94. {
  95. if(!fw.StartsWith("netcoreapp") && coreOnly)
  96. continue;
  97. Information("Running for " + fw);
  98. DotNetTest(c =>
  99. {
  100. c = c
  101. .SetProjectFile(project)
  102. .SetConfiguration(Parameters.Configuration)
  103. .SetFramework(fw)
  104. .EnableNoBuild()
  105. .EnableNoRestore();
  106. // NOTE: I can see that we could maybe add another extension method "Switch" or "If" to make this more convenient
  107. if (Parameters.PublishTestResults)
  108. c = c.SetLogger("trx").SetResultsDirectory(Parameters.TestResultsRoot);
  109. return c;
  110. });
  111. }
  112. }
  113. Target RunCoreLibsTests => _ => _
  114. .OnlyWhen(() => !Parameters.SkipTests)
  115. .DependsOn(Compile)
  116. .Executes(() =>
  117. {
  118. RunCoreTest("./tests/Avalonia.Base.UnitTests", false);
  119. RunCoreTest("./tests/Avalonia.Controls.UnitTests", false);
  120. RunCoreTest("./tests/Avalonia.Input.UnitTests", false);
  121. RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", false);
  122. RunCoreTest("./tests/Avalonia.Layout.UnitTests", false);
  123. RunCoreTest("./tests/Avalonia.Markup.UnitTests", false);
  124. RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", false);
  125. RunCoreTest("./tests/Avalonia.Styling.UnitTests", false);
  126. RunCoreTest("./tests/Avalonia.Visuals.UnitTests", false);
  127. RunCoreTest("./tests/Avalonia.Skia.UnitTests", false);
  128. RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", false);
  129. });
  130. Target RunRenderTests => _ => _
  131. .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
  132. .DependsOn(Compile)
  133. .Executes(() =>
  134. {
  135. RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", true);
  136. RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", true);
  137. });
  138. Target RunDesignerTests => _ => _
  139. .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
  140. .DependsOn(Compile)
  141. .Executes(() =>
  142. {
  143. RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", false);
  144. });
  145. [PackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe")] readonly Tool DotMemoryUnit;
  146. Target RunLeakTests => _ => _
  147. .OnlyWhen(() => !Parameters.SkipTests && Parameters.IsRunningOnWindows)
  148. .DependsOn(Compile)
  149. .Executes(() =>
  150. {
  151. var dotMemoryUnitPath =
  152. ToolPathResolver.GetPackageExecutable("JetBrains.dotMemoryUnit", "dotMemoryUnit.exe");
  153. var xunitRunnerPath =
  154. ToolPathResolver.GetPackageExecutable("xunit.runner.console", "xunit.console.x86.exe");
  155. var args = new[]
  156. {
  157. Path.GetFullPath(xunitRunnerPath),
  158. "--propagate-exit-code",
  159. "--",
  160. "tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll"
  161. };
  162. var cargs = string.Join(" ", args.Select(a => '"' + a + '"'));
  163. var proc = Process.Start(new ProcessStartInfo(dotMemoryUnitPath, cargs)
  164. {
  165. UseShellExecute = false
  166. });
  167. if (!proc.WaitForExit(120000))
  168. {
  169. proc.Kill();
  170. throw new Exception("Leak tests timed out");
  171. }
  172. var leakTestsExitCode = proc.ExitCode;
  173. if (leakTestsExitCode != 0)
  174. {
  175. throw new Exception("Leak Tests failed");
  176. }
  177. var testAssembly = "tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll";
  178. DotMemoryUnit(
  179. $"{XunitPath.DoubleQuoteIfNeeded()} --propagate-exit-code -- {testAssembly}",
  180. timeout: 120_000);
  181. });
  182. Target ZipFiles => _ => _
  183. .After(CreateNugetPackages, Compile, RunCoreLibsTests, Package)
  184. .Executes(() =>
  185. {
  186. var data = Parameters;
  187. Zip(data.ZipCoreArtifacts, data.BinRoot);
  188. Zip(data.ZipNuGetArtifacts, data.NugetRoot);
  189. Zip(data.ZipTargetControlCatalogDesktopDir,
  190. GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.dll").Concat(
  191. GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.config")).Concat(
  192. GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.so")).Concat(
  193. GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.dylib")).Concat(
  194. GlobFiles(data.ZipSourceControlCatalogDesktopDir, "*.exe")));
  195. });
  196. Target CreateNugetPackages => _ => _
  197. .DependsOn(Compile)
  198. .After(RunTests)
  199. .Executes(() =>
  200. {
  201. if (Parameters.IsRunningOnWindows)
  202. MSBuild(Parameters.MSBuildSolution, c => c
  203. .SetConfiguration(Parameters.Configuration)
  204. .SetVerbosity(MSBuildVerbosity.Minimal)
  205. .AddProperty("PackageVersion", Parameters.Version)
  206. .AddProperty("iOSRoslynPathHackRequired", "true")
  207. .SetToolsVersion(MSBuildToolsVersion._15_0)
  208. .AddTargets("Restore", "Pack"));
  209. else
  210. DotNetPack(Parameters.MSBuildSolution, c =>
  211. c.SetConfiguration(Parameters.Configuration)
  212. .AddProperty("PackageVersion", Parameters.Version));
  213. });
  214. Target RunTests => _ => _
  215. .DependsOn(RunCoreLibsTests)
  216. .DependsOn(RunRenderTests)
  217. .DependsOn(RunDesignerTests)
  218. .DependsOn(RunLeakTests);
  219. Target Package => _ => _
  220. .DependsOn(RunTests)
  221. .DependsOn(CreateNugetPackages);
  222. Target CiAppVeyor => _ => _
  223. .DependsOn(Package)
  224. .DependsOn(ZipFiles);
  225. Target CiTravis => _ => _
  226. .DependsOn(RunTests);
  227. Target CiAsuzeLinux => _ => _
  228. .DependsOn(RunTests);
  229. Target CiAsuzeOSX => _ => _
  230. .DependsOn(Package)
  231. .DependsOn(ZipFiles);
  232. Target CiAsuzeWindows => _ => _
  233. .DependsOn(Package)
  234. .DependsOn(ZipFiles);
  235. public static int Main() =>
  236. RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
  237. ? Execute<Build>(x => x.Package)
  238. : Execute<Build>(x => x.RunTests);
  239. }