public static AngularWorkspace Create(StandardGlobalInfo globalInfo, NPMSolution npmSolution, NormalizedPath path, NormalizedPath outputFolder) { NormalizedPath packageJsonPath = path.AppendPart("package.json"); NormalizedPath angularJsonPath = path.AppendPart("angular.json"); JObject packageJson = JObject.Parse(File.ReadAllText(packageJsonPath)); JObject angularJson = JObject.Parse(File.ReadAllText(angularJsonPath)); if (!(packageJson["private"]?.ToObject <bool>() ?? false)) { throw new InvalidDataException("A workspace project should be private."); } string solutionName = packageJson["name"].ToString(); List <string> unscopedNames = angularJson["projects"].ToObject <JObject>().Properties().Select(p => p.Name).ToList(); List <NPMProject> projects = unscopedNames.Select( p => NPMPublishedProject.Create( globalInfo, npmSolution, path.Combine(new NormalizedPath(angularJson["projects"][p]["root"].ToString())), outputFolder.AppendPart(p) ) ).ToList(); return(new AngularWorkspace(projects.Single(p => p.DirectoryPath == path), projects, outputFolder)); }
public static StandardGlobalInfo AddDotnet(this StandardGlobalInfo globalInfo) { DotnetSolution sln = DotnetSolution.FromSolutionInCurrentWorkingDirectory(globalInfo); globalInfo.RegisterSolution(sln); return(globalInfo); }
/// <summary> /// Pushes components to remote store. See <see cref="CKSetupCakeContextExtensions.CKSetupCreateDefaultConfiguration(ICakeContext)"/>. /// </summary> /// <param name="globalInfo">The configured <see cref="CheckRepositoryInfo"/>.</param> /// <param name="components">The set of component to push. When null (the default), <see cref="GetCKSetupComponents"/> is used.</param> void StandardPushCKSetupComponents(StandardGlobalInfo globalInfo, IEnumerable <CKSetupComponent> components = null) { var storeConf = Cake.CKSetupCreateDefaultConfiguration(); if (globalInfo.IsLocalCIRelease) { storeConf.TargetStoreUrl = Path.Combine(globalInfo.LocalFeedPath, "CKSetupStore"); } if (!storeConf.IsValid) { Cake.Information("CKSetupStoreConfiguration is invalid. Skipped push to remote store."); return; } Cake.Information($"Using CKSetupStoreConfiguration: {storeConf}"); if (components == null) { components = GetCKSetupComponents(); } if (!Cake.CKSetupPublishAndAddComponentFoldersToStore( storeConf, components.Select(c => c.GetBinPath(globalInfo.BuildInfo.BuildConfiguration)))) { Cake.TerminateWithError("Error while registering components in local temporary store."); } if (!Cake.CKSetupPushLocalToRemoteStore(storeConf)) { Cake.TerminateWithError("Error while pushing components to remote store."); } }
public static AngularWorkspace Create(StandardGlobalInfo globalInfo, NPMSolution npmSolution, NormalizedPath path) { NormalizedPath packageJsonPath = path.AppendPart("package.json"); NormalizedPath angularJsonPath = path.AppendPart("angular.json"); JObject packageJson = JObject.Parse(File.ReadAllText(packageJsonPath)); JObject angularJson = JObject.Parse(File.ReadAllText(angularJsonPath)); if (!(packageJson["private"]?.ToObject <bool>() ?? false)) { throw new InvalidDataException("A workspace project should be private."); } List <NPMProject> projects = new List <NPMProject>(); var jsonProject = angularJson["projects"].ToObject <JObject>(); foreach (var project in jsonProject.Properties()) { var projectPath = project.Value["root"].ToString(); var options = project.Value["architect"]["build"]["options"]; string outputPathJson = options["outputPath"]?.Value <string>(); bool havePath = outputPathJson != null; string ngPackagePath = options["project"]?.Value <string>(); bool haveNgPackageJson = ngPackagePath != null; if (havePath && haveNgPackageJson) { throw new NotImplementedException(); //I don't know what to do in this case. } NormalizedPath outputPath; NormalizedPath ngPackagePathFullPath = path.Combine(ngPackagePath); if (haveNgPackageJson) { JObject ngPackage = JObject.Parse(File.ReadAllText(ngPackagePathFullPath)); string dest = ngPackage["dest"]?.Value <string>(); if (dest == null) { throw new InvalidDataException("ng package does not contain dest path."); } outputPath = ngPackagePathFullPath.RemoveLastPart().Combine(dest).ResolveDots(); } else if (havePath) { outputPath = path.Combine(outputPathJson); } else { globalInfo.Cake.Warning($"No path found for angular project '{path}'."); outputPath = path.Combine(projectPath); } projects.Add( NPMPublishedProject.Create( globalInfo, npmSolution, path.Combine(projectPath), outputPath ) ); } return(new AngularWorkspace(NPMPublishedProject.Create(globalInfo, npmSolution, path, path), projects)); }
/// <summary> /// Create a DotnetSolution from the sln. /// </summary> /// <param name="globalInfo">The StandardGlobalInfo</param> /// <param name="projectToPublishPredicate"> /// The predicate used to filter the project to publish. By default the predicate is p => !p.Path.Segments.Contains /// </param> /// <returns></returns> public static DotnetSolution FromSolutionInCurrentWorkingDirectory( StandardGlobalInfo globalInfo) { string solutionFileName = System.IO.Path.GetFileName( globalInfo.Cake.GetFiles("*.sln", new GlobberSettings { Predicate = p => !System.IO.Path.GetFileName(p.Path.FullPath).EndsWith(".local.sln", StringComparison.OrdinalIgnoreCase) }).Single().FullPath ); var sln = globalInfo.Cake.ParseSolution(solutionFileName); var projects = sln .Projects .Where(p => !(p is SolutionFolder) && p.Name != "CodeCakeBuilder") .ToList(); var projectsToPublish = projects.Where( p => ((bool?)XDocument.Load(p.Path.FullPath) .Root .Elements("PropertyGroup") .Elements("IsPackable").LastOrDefault() ?? true) == true ) .ToList(); return(new DotnetSolution(globalInfo, solutionFileName, projects, projectsToPublish)); }
public static AngularWorkspace Create(StandardGlobalInfo globalInfo, NPMSolution npmSolution, NormalizedPath path) { NormalizedPath packageJsonPath = path.AppendPart("package.json"); NormalizedPath angularJsonPath = path.AppendPart("angular.json"); JObject packageJson = JObject.Parse(File.ReadAllText(packageJsonPath)); JObject angularJson = JObject.Parse(File.ReadAllText(angularJsonPath)); if (!(packageJson["private"]?.ToObject <bool>() ?? false)) { throw new InvalidDataException("A workspace project should be private."); } List <NPMProject> projects = new List <NPMProject>(); var jsonProject = angularJson["projects"].ToObject <JObject>(); foreach (var project in jsonProject.Properties()) { var projectPath = project.Value["root"].ToString(); var outputPath = project.Value["architect"]?["build"]?["options"]?["outputPath"]?.Value <string>() ?? projectPath; projects.Add( NPMPublishedProject.Create( globalInfo, npmSolution, path.Combine(projectPath), path.Combine(outputPath) ) ); } return(new AngularWorkspace(NPMPublishedProject.Create(globalInfo, npmSolution, path, path), projects)); }
public Build() { Cake.Log.Verbosity = Verbosity.Diagnostic; StandardGlobalInfo globalInfo = CreateStandardGlobalInfo() .AddDotnet() .SetCIBuildTag(); Task("Check-Repository") .Does(() => { Console.WriteLine($"Environment.OSVersion: {Environment.OSVersion}"); globalInfo.TerminateIfShouldStop(); }); Task("Clean") .IsDependentOn("Check-Repository") .Does(() => { globalInfo.GetDotnetSolution().Clean(); Cake.CleanDirectories(globalInfo.ReleasesFolder.ToString()); }); Task("Build") .IsDependentOn("Check-Repository") .IsDependentOn("Clean") .Does(() => { globalInfo.GetDotnetSolution().Build(); }); Task("Unit-Testing") .IsDependentOn("Build") .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction || Cake.ReadInteractiveOption("RunUnitTests", "Run Unit Tests?", 'Y', 'N') == 'Y') .Does(() => { globalInfo.GetDotnetSolution().Test(); }); Task("Create-NuGet-Packages") .WithCriteria(() => globalInfo.IsValid) .IsDependentOn("Unit-Testing") .Does(() => { globalInfo.GetDotnetSolution().Pack(); }); Task("Push-Artifacts") .IsDependentOn("Create-NuGet-Packages") .WithCriteria(() => globalInfo.IsValid) .Does(async() => { await globalInfo.PushArtifactsAsync(); }); // The Default task for this script can be set here. Task("Default") .IsDependentOn("Push-Artifacts"); }
public Build() { Cake.Log.Verbosity = Verbosity.Diagnostic; StandardGlobalInfo globalInfo = CreateStandardGlobalInfo() .AddDotnet() .SetCIBuildTag(); Task("Check-Repository") .Does(() => { globalInfo.TerminateIfShouldStop(); }); Task("Clean") .IsDependentOn("Check-Repository") .Does(() => { globalInfo.GetDotnetSolution().Clean(); Cake.CleanDirectories(globalInfo.ReleasesFolder); Cake.DeleteFiles("Tests/**/TestResult*.xml"); }); Task("Build") .IsDependentOn("Check-Repository") .IsDependentOn("Clean") .Does(() => { globalInfo.GetDotnetSolution().Build(); }); Task("Unit-Testing") .IsDependentOn("Build") .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction || Cake.ReadInteractiveOption("RunUnitTests", "Run Unit Tests?", 'Y', 'N') == 'Y') .Does(() => { globalInfo.GetDotnetSolution().Test(); }); Task("Create-NuGet-Packages") .WithCriteria(() => globalInfo.IsValid) .IsDependentOn("Unit-Testing") .Does(() => { globalInfo.GetDotnetSolution().Pack(); }); Task("Push-Artifacts") .IsDependentOn("Create-NuGet-Packages") .WithCriteria(() => globalInfo.IsValid) .Does(() => { globalInfo.PushArtifacts(); }); // The Default task for this script can be set here. Task("Default") .IsDependentOn("Push-Artifacts"); }
public Build() { try { Cake.Log.Verbosity = Verbosity.Diagnostic; StandardGlobalInfo globalInfo = new StandardGlobalInfo(Cake) .AddDotnet(); globalInfo.GetDotnetSolution().Clean(); globalInfo.GetDotnetSolution().Build(); globalInfo.GetDotnetSolution().Test(); Cake.DotNetCorePublish("MarketFlight"); string SourcePath = @"MarketFlight/bin/Debug/netcoreapp3.1/publish/"; string release = "release/"; //Now Create all of the directories foreach (string dirPath in Directory.GetDirectories(SourcePath, "*", SearchOption.AllDirectories)) { Directory.CreateDirectory(dirPath.Replace(SourcePath, release)); } //Copy all the files & Replaces any files with the same name foreach (string newPath in Directory.GetFiles(SourcePath, "*.*", SearchOption.AllDirectories)) { File.Copy(newPath, newPath.Replace(SourcePath, release), true); } } catch (Exception e) { Console.WriteLine(e); throw e; } Task("Default"); }
protected static NPMProject CreateNPMProject( StandardGlobalInfo globalInfo, NPMSolution npmSolution, SimplePackageJsonFile json, NormalizedPath outputPath) { return(new NPMProject(globalInfo, npmSolution, json, outputPath)); }
NPMPublishedProject(StandardGlobalInfo globalInfo, NPMSolution npmSolution, SimplePackageJsonFile json, NormalizedPath outputPath) : base(globalInfo, npmSolution, json, outputPath) { ArtifactInstance = new ArtifactInstance(new Artifact("NPM", json.Name), globalInfo.Version); string tgz = json.Name.Replace("@", "").Replace('/', '-'); TGZName = tgz + "-" + globalInfo.Version.ToString() + ".tgz"; }
NPMPublishedProject(StandardGlobalInfo globalInfo, NPMSolution npmSolution, SimplePackageJsonFile json, NormalizedPath outputPath) : base(globalInfo, npmSolution, json, outputPath) { _ckliLocalFeedMode = json.CKliLocalFeedMode; ArtifactInstance = new ArtifactInstance(new Artifact("NPM", json.Name), globalInfo.BuildInfo.Version); string tgz = json.Name.Replace("@", "").Replace('/', '-'); TGZName = tgz + "-" + globalInfo.BuildInfo.Version.WithBuildMetaData("").ToNormalizedString() + ".tgz"; }
DotnetSolution(StandardGlobalInfo globalInfo, string solutionFileName, IReadOnlyList <SolutionProject> projects, IReadOnlyList <SolutionProject> projectsToPublish) { _globalInfo = globalInfo; SolutionFileName = solutionFileName; Projects = projects; ProjectsToPublish = projectsToPublish; }
/// <summary> /// Adds the <see cref="NPMSolution"/> to the <paramref name="globalInfo"/> /// </summary> /// <param name="this">This global info.</param> /// <param name="solution">The NPM solution.</param> /// <returns>This info.</returns> public static StandardGlobalInfo AddNPM(this StandardGlobalInfo globalInfo, NPMSolution solution) { SVersion minmimalNpmVersionRequired = SVersion.Create(6, 7, 0); string npmVersion = globalInfo.Cake.NpmGetNpmVersion(); if (SVersion.Parse(npmVersion) < minmimalNpmVersionRequired) { globalInfo.Cake.TerminateWithError("Outdated npm. Version older than v6.7.0 are known to fail on publish."); } globalInfo.RegisterSolution(solution); return(globalInfo); }
protected NPMProject( StandardGlobalInfo globalInfo, NPMSolution npmSolution, SimplePackageJsonFile json, NormalizedPath outputPath) { DirectoryPath = json.JsonFilePath.RemoveLastPart(); PackageJson = json; OutputPath = outputPath; NPMRCPath = DirectoryPath.AppendPart(".npmrc"); GlobalInfo = globalInfo; NpmSolution = npmSolution; }
public Build() { Cake.Log.Verbosity = Verbosity.Diagnostic; StandardGlobalInfo globalInfo = CreateStandardGlobalInfo() .AddDotnet() .SetCIBuildTag(); Task("Check-Repository") .Does(() => { globalInfo.TerminateIfShouldStop(); }); Task("Clean") .IsDependentOn("Check-Repository") .Does(() => { globalInfo.GetDotnetSolution().Clean(); Cake.CleanDirectories(globalInfo.ReleasesFolder); }); Task("Build") .IsDependentOn("Check-Repository") .IsDependentOn("Clean") .Does(() => { globalInfo.GetDotnetSolution().Build(); }); Task("Create-NuGet-Packages") .WithCriteria(() => globalInfo.IsValid) .IsDependentOn("Build") .Does(() => { globalInfo.GetDotnetSolution().Pack(); }); Task("Push-Artifacts") .IsDependentOn("Create-NuGet-Packages") .WithCriteria(() => globalInfo.IsValid) .Does(() => { globalInfo.PushArtifacts(); }); // The Default task for this script can be set here. Task("Default") .IsDependentOn("Push-Artifacts"); }
/// <summary> /// Create a <see cref="NPMProject"/> that can be a <see cref="NPMPublishedProject"/>. /// </summary> /// <param name="globalInfo">The global info of the CodeCakeBuilder.</param> /// <param name="dirPath">The directory path where is located the npm package.</param> /// <param name="outputPath">The directory path where the build output is. It can be the same than <paramref name="dirPath"/>.</param> /// <returns></returns> public static NPMProject Create(StandardGlobalInfo globalInfo, NPMSolution solution, NormalizedPath dirPath, NormalizedPath outputPath) { var json = SimplePackageJsonFile.Create(globalInfo.Cake, dirPath); NPMProject output; if (json.IsPrivate) { output = CreateNPMProject(globalInfo, solution, json, outputPath); } else { output = new NPMPublishedProject(globalInfo, solution, json, outputPath); } return(output); }
/// <summary> /// Builds the provided .sln without "CodeCakeBuilder" project itself and /// optionally other projects. /// </summary> /// <param name="globalInfo">The current StandardGlobalInfo.</param> /// <param name="solutionFileName">The solution file name to build (relative to the repository root).</param> /// <param name="excludedProjectName">Optional project names (without path nor .csproj extension).</param> void StandardSolutionBuild(StandardGlobalInfo globalInfo, string solutionFileName, params string[] excludedProjectName) { using (var tempSln = Cake.CreateTemporarySolutionFile(solutionFileName)) { var exclude = new List <string>(excludedProjectName) { "CodeCakeBuilder" }; tempSln.ExcludeProjectsFromBuild(exclude.ToArray()); Cake.DotNetCoreBuild(tempSln.FullPath.FullPath, new DotNetCoreBuildSettings().AddVersionArguments(globalInfo.GitInfo, s => { s.Configuration = globalInfo.BuildConfiguration; })); } }
public Build() { Cake.Log.Verbosity = Verbosity.Diagnostic; StandardGlobalInfo globalInfo = CreateStandardGlobalInfo() .AddDotnet() .SetCIBuildTag(); Task("Check-Repository") .Does(() => { // We currently produce nothing so TerminateIfShouldStop // always stops the build script. // globalInfo.TerminateIfShouldStop(); }); Task("Clean") .IsDependentOn("Check-Repository") .Does(() => { globalInfo.GetDotnetSolution().Clean(); Cake.CleanDirectories(globalInfo.ReleasesFolder); }); Task("Build") .IsDependentOn("Check-Repository") .IsDependentOn("Clean") .Does(() => { globalInfo.GetDotnetSolution().Build(); }); Task("Unit-Testing") .IsDependentOn("Build") .WithCriteria(() => Cake.InteractiveMode() == InteractiveMode.NoInteraction || Cake.ReadInteractiveOption("RunUnitTests", "Run Unit Tests?", 'Y', 'N') == 'Y') .Does(() => { globalInfo.GetDotnetSolution().Test(); }); // The Default task for this script can be set here. Task("Default") .IsDependentOn("Unit-Testing"); }
/// <summary> /// Reads the "CodeCakeBuilder/NPMSolution.xml" file that must exist. /// </summary> /// <param name="version">The version of all published packages.</param> /// <returns>The solution object.</returns> public static NPMSolution ReadFromNPMSolutionFile(StandardGlobalInfo globalInfo) { var document = XDocument.Load("CodeCakeBuilder/NPMSolution.xml").Root; var solution = new NPMSolution(globalInfo); foreach (var item in document.Elements("AngularWorkspace")) { solution.Add(AngularWorkspace.Create(globalInfo, solution, (string)item.Attribute("Path"))); } foreach (var item in document.Elements("Project")) { solution.Add(NPMPublishedProject.Create( globalInfo, solution, (string)item.Attribute("Path"), (string)item.Attribute("OutputFolder"))); } return(solution); }
/// <summary> /// Create a DotnetSolution from the sln. /// </summary> /// <param name="globalInfo">The StandardGlobalInfo</param> /// <param name="projectToPublishPredicate"> /// The predicate used to filter the project to publish. By default the predicate is p => !p.Path.Segments.Contains /// </param> /// <returns></returns> public static DotnetSolution FromSolutionInCurrentWorkingDirectory( StandardGlobalInfo globalInfo) { string solutionFileName = "MarketFlight.sln"; SolutionParserResult sln = globalInfo.Cake.ParseSolution(solutionFileName); List <SolutionProject> projects = sln .Projects .Where(p => !(p is SolutionFolder) && p.Name != "CodeCakeBuilder") .ToList(); List <SolutionProject> projectsToPublish = projects.Where( p => ((bool?)XDocument.Load(p.Path.FullPath) .Root .Elements("PropertyGroup") .Elements("IsPackable").LastOrDefault() ?? true) == true ) .ToList(); return(new DotnetSolution(globalInfo, solutionFileName, projects, projectsToPublish)); }
public static DotnetSolution GetDotnetSolution(this StandardGlobalInfo globalInfo) { return(globalInfo.Solutions.OfType <DotnetSolution>().Single()); }
void StandardCreateNuGetPackages(StandardGlobalInfo globalInfo) { globalInfo.GetDotnetSolution().Pack(); }
/// <summary> /// Creates a new <see cref="StandardGlobalInfo"/> initialized by the /// current environment. /// </summary> /// <param name="gitInfo">The git info.</param> /// <returns>A new info object.</returns> StandardGlobalInfo CreateStandardGlobalInfo(SimpleRepositoryInfo gitInfo) { StandardGlobalInfo result = new StandardGlobalInfo(Cake, gitInfo); // By default: if (!gitInfo.IsValid) { if (Cake.InteractiveMode() != InteractiveMode.NoInteraction && Cake.ReadInteractiveOption("PublishDirtyRepo", "Repository is not ready to be published. Proceed anyway?", 'Y', 'N') == 'Y') { Cake.Warning("GitInfo is not valid, but you choose to continue..."); result.IgnoreNoArtifactsToProduce = true; } else { // On Appveyor, we let the build run: this gracefully handles Pull Requests. if (Cake.AppVeyor().IsRunningOnAppVeyor) { result.IgnoreNoArtifactsToProduce = true; } else { Cake.TerminateWithError("Repository is not ready to be published."); } } // When the gitInfo is not valid, we do not try to push any packages, even if the build continues // (either because the user choose to continue or if we are on the CI server). // We don't need to worry about feeds here. } else { // gitInfo is valid: it is either ci or a release build. CSemVer.SVersion v = gitInfo.Info.FinalVersion; // If a /LocalFeed/ directory exists above, we publish the packages in it. string localFeedRoot = Cake.FindSiblingDirectoryAbove(Cake.Environment.WorkingDirectory.FullPath, "LocalFeed"); if (localFeedRoot != null) { if (v.AsCSVersion == null) { if (v.Prerelease.EndsWith(".local")) { // Local releases must not be pushed on any remote and are copied to LocalFeed/Local // feed (if LocalFeed/ directory above exists). result.IsLocalCIRelease = true; result.LocalFeedPath = System.IO.Path.Combine(localFeedRoot, "Local"); } else { // CI build versions are routed to LocalFeed/CI result.LocalFeedPath = System.IO.Path.Combine(localFeedRoot, "CI"); } } else { // Release or prerelease go to LocalFeed/Release result.LocalFeedPath = System.IO.Path.Combine(localFeedRoot, "Release"); } System.IO.Directory.CreateDirectory(result.LocalFeedPath); } else { result.IsLocalCIRelease = v.Prerelease.EndsWith(".local"); } // Creating the right remote feed. if (!result.IsLocalCIRelease && (Cake.InteractiveMode() == InteractiveMode.NoInteraction || Cake.ReadInteractiveOption("PushToRemote", "Push to Remote feeds?", 'Y', 'N') == 'Y')) { result.PushToRemote = true; } } return(result); }
void StandardUnitTests(StandardGlobalInfo globalInfo, IEnumerable <SolutionProject> testProjects) { globalInfo.GetDotnetSolution().Test(); }
/// <summary> /// Initiaizes a new <see cref="NPMSolution" />. /// </summary> /// <param name="projects">Set of projects.</param> NPMSolution( StandardGlobalInfo globalInfo) : base() { _globalInfo = globalInfo; }
/// <summary> /// Gets the NPM solution handled by the single <see cref="Build.NPMArtifactType"/>. /// </summary> /// <param name="this">This global info.</param> /// <returns>The NPM solution.</returns> public static NPMSolution GetNPMSolution(this StandardGlobalInfo @this) { return(@this.Solutions.OfType <NPMSolution>().Single()); }
/// <summary> /// Adds the <see cref="Build.NPMArtifactType"/> for NPM based on <see cref="NPMSolution.ReadFromNPMSolutionFile"/> /// (projects are defined by "CodeCakeBuilder/NPMSolution.xml" file). /// </summary> /// <param name="this">This global info.</param> /// <returns>This info.</returns> public static StandardGlobalInfo AddNPM(this StandardGlobalInfo @this) { return(AddNPM(@this, NPMSolution.ReadFromNPMSolutionFile(@this))); }
public NPMArtifactType(StandardGlobalInfo globalInfo, NPMSolution solution) : base(globalInfo, "NPM") { Solution = solution; }
/// <summary> /// /// </summary> /// <param name="globalInfo"></param> /// <param name="testProjects"></param> /// <param name="useNUnit264ForNet461">Will use nunit 264 for Net461 project if true.</param> void StandardUnitTests(StandardGlobalInfo globalInfo, IEnumerable <SolutionProject> testProjects) { string memoryFilePath = $"CodeCakeBuilder/UnitTestsDone.{globalInfo.GitInfo.CommitSha}.txt"; void WriteTestDone(Cake.Core.IO.FilePath test) { if (globalInfo.GitInfo.IsValid) { File.AppendAllLines(memoryFilePath, new[] { test.ToString() }); } } bool CheckTestDone(Cake.Core.IO.FilePath test) { bool done = File.Exists(memoryFilePath) ? File.ReadAllLines(memoryFilePath).Contains(test.ToString()) : false; if (done) { if (!globalInfo.GitInfo.IsValid) { Cake.Information("Dirty commit: tests are run again (base commit tests were successful)."); done = false; } else { Cake.Information("Test already successful on this commit."); } } return(done); } foreach (SolutionProject project in testProjects) { NormalizedPath projectPath = project.Path.GetDirectory().FullPath; NormalizedPath binDir = projectPath.AppendPart("bin").AppendPart(globalInfo.BuildConfiguration); NormalizedPath objDir = projectPath.AppendPart("obj"); string assetsJson = File.ReadAllText(objDir.AppendPart("project.assets.json")); bool isNunitLite = assetsJson.Contains("NUnitLite"); bool isVSTest = assetsJson.Contains("Microsoft.NET.Test.Sdk"); foreach (NormalizedPath buildDir in Directory.GetDirectories(binDir)) { string framework = buildDir.LastPart; string fileWithoutExtension = buildDir.AppendPart(project.Name); string testBinariesPath = ""; if (isNunitLite) { //we are with nunitLite testBinariesPath = fileWithoutExtension + ".exe"; if (File.Exists(testBinariesPath)) { Cake.Information($"Testing via NUnitLite ({framework}): {testBinariesPath}"); if (CheckTestDone(testBinariesPath)) { return; } Cake.NUnit3(new[] { testBinariesPath }, new NUnit3Settings { Results = new[] { new NUnit3Result() { FileName = FilePath.FromString(projectPath.AppendPart("TestResult.Net461.xml")) } } }); } else { testBinariesPath = fileWithoutExtension + ".dll"; Cake.Information($"Testing via NUnitLite ({framework}): {testBinariesPath}"); if (CheckTestDone(testBinariesPath)) { return; } Cake.DotNetCoreExecute(testBinariesPath); } } if (isVSTest) { testBinariesPath = fileWithoutExtension + ".dll"; //VS Tests Cake.Information($"Testing via VSTest ({framework}): {testBinariesPath}"); if (CheckTestDone(testBinariesPath)) { return; } Cake.DotNetCoreTest(projectPath, new DotNetCoreTestSettings() { Configuration = globalInfo.BuildConfiguration, Framework = framework, NoRestore = true, NoBuild = true, Logger = "trx" }); } if (!isVSTest && !isNunitLite) { testBinariesPath = fileWithoutExtension + ".dll"; Cake.Information("Testing via NUnit: {0}", testBinariesPath); Cake.NUnit(new[] { testBinariesPath }, new NUnitSettings() { Framework = "v4.5", ResultsFile = FilePath.FromString(projectPath.AppendPart("TestResult.Net461.xml")) }); } WriteTestDone(testBinariesPath); } } }