From 4f440711df17b7808f7a31f684fb74785c02ac42 Mon Sep 17 00:00:00 2001 From: Glenn Watson <5834289+glennawatson@users.noreply.github.com> Date: Mon, 31 Dec 2018 14:20:15 -0800 Subject: [PATCH] housekeeping: Add additional information for coveralls upload (#1878) housekeeping: Update opencover to use codecov --- .gitignore | 3 + azure-pipelines.yml | 19 +- build.cake | 190 ++++++++++++------ .../ReactiveUI.Fody.Helpers.csproj | 1 + tools/nuget/nuget.exe | 4 +- 5 files changed, 145 insertions(+), 72 deletions(-) diff --git a/.gitignore b/.gitignore index c293217e4a..3998ec85be 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,9 @@ bld/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ +# Visual Studio code +.vscode/ + # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 614be1286a..07e1a5b8c2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -36,11 +36,12 @@ steps: SIGNCLIENT_USER: $(SignClientUser) VSTS_ACCESS_TOKEN: $(System.AccessToken) COVERALLS_TOKEN: $(COVERALLS_TOKEN) + CODECOV_TOKEN: $(CODECOV_TOKEN) ArtifactDirectory: $(System.DefaultWorkingDirectory)\artifacts - task: CopyFiles@2 inputs: - Contents: 'artifacts/*.nupkg' + Contents: 'artifacts/packages/*.nupkg' TargetFolder: '$(build.artifactstagingdirectory)\packages' flattenFolders: true @@ -53,7 +54,7 @@ steps: - task: CopyFiles@2 inputs: - Contents: '**/bin/*' + Contents: 'artifacts/binaries/**/*' TargetFolder: '$(build.artifactstagingdirectory)\binaries' - task: PublishBuildArtifacts@1 @@ -65,7 +66,7 @@ steps: - task: CopyFiles@2 inputs: - Contents: 'src/ReactiveUI.**/Events_*.cs' + Contents: 'artifacts/Events/*.cs' TargetFolder: '$(build.artifactstagingdirectory)\Events' - task: PublishBuildArtifacts@1 @@ -74,3 +75,15 @@ steps: pathToPublish: '$(build.artifactstagingdirectory)\Events' artifactType: container artifactName: Events + +- task: CopyFiles@2 + inputs: + Contents: 'artifacts/tests/**/*' + TargetFolder: '$(build.artifactstagingdirectory)\Tests' + +- task: PublishBuildArtifacts@1 + displayName: Publish Test Data + inputs: + pathToPublish: '$(build.artifactstagingdirectory)\Tests' + artifactType: container + artifactName: Tests diff --git a/build.cake b/build.cake index 9a9e56988e..360abba3b8 100644 --- a/build.cake +++ b/build.cake @@ -10,6 +10,7 @@ #addin "nuget:?package=Cake.Coveralls&version=0.9.0" #addin "nuget:?package=Cake.PinNuGetDependency&loaddependencies=true&version=3.2.3" #addin "nuget:?package=Cake.Powershell&version=0.4.7" +#addin "nuget:?package=Cake.Codecov&version=0.5.0" ////////////////////////////////////////////////////////////////////// // TOOLS @@ -21,6 +22,7 @@ #tool "nuget:?package=ReportGenerator&version=4.0.4" #tool "nuget:?package=vswhere&version=2.5.2" #tool "nuget:?package=xunit.runner.console&version=2.4.1" +#tool "nuget:?package=Codecov&version=1.1.0" ////////////////////////////////////////////////////////////////////// // ARGUMENTS @@ -57,20 +59,52 @@ var informationalVersion = EnvironmentVariable("GitAssemblyInformationalVersion" // Artifacts var artifactDirectory = "./artifacts/"; var testsArtifactDirectory = artifactDirectory + "tests/"; -var testCoverageOutputFile = testsArtifactDirectory + "OpenCover.xml"; -var packageWhitelist = new[] { "ReactiveUI.Testing", - "ReactiveUI.Events", - "ReactiveUI.Events.WPF", - "ReactiveUI.Events.Winforms", - "ReactiveUI.Events.XamForms", - "ReactiveUI", - "ReactiveUI.Fody", - "ReactiveUI.Fody.Helpers", - "ReactiveUI.AndroidSupport", - "ReactiveUI.Blend", - "ReactiveUI.WPF", - "ReactiveUI.Winforms", - "ReactiveUI.XamForms" }; +var eventsArtifactDirectory = artifactDirectory + "Events/"; +var binariesArtifactDirectory = artifactDirectory + "binaries/"; +var packagesArtifactDirectory = artifactDirectory + "packages/"; + +// OpenCover file location +var testCoverageOutputFile = MakeAbsolute(File(testsArtifactDirectory + "OpenCover.xml")); + +// Whitelisted Packages +var packageWhitelist = new[] +{ + "ReactiveUI", + "ReactiveUI.Testing", + "ReactiveUI.Events", + "ReactiveUI.Events.WPF", + "ReactiveUI.Events.Winforms", + "ReactiveUI.Events.XamForms", + "ReactiveUI.Fody", + "ReactiveUI.Fody.Helpers", + "ReactiveUI.AndroidSupport", + "ReactiveUI.Blend", + "ReactiveUI.WPF", + "ReactiveUI.Winforms", + "ReactiveUI.XamForms", + // TODO: seems the leak tests never worked as part of the CI, fix. For the moment just make sure it compiles. + "ReactiveUI.LeakTests" +}; + +var packageTestWhitelist = new[] +{ + "ReactiveUI.Tests", + "ReactiveUI.Fody.Tests" +}; + +(string targetName, string destination)[] eventGenerators = new[] +{ + ("android", "src/ReactiveUI.Events/"), + ("ios", "src/ReactiveUI.Events/"), + ("mac", "src/ReactiveUI.Events/"), + ("uwp", "src/ReactiveUI.Events/"), + ("tizen4", "src/ReactiveUI.Events/"), + ("wpf", "src/ReactiveUI.Events.WPF/"), + ("xamforms", "src/ReactiveUI.Events.XamForms/"), + ("winforms", "src/ReactiveUI.Events.Winforms/"), + ("essentials", "src/ReactiveUI.Events/"), + ("tvos", "src/ReactiveUI.Events/"), +}; // Define global marcos. Action Abort = () => { throw new Exception("a non-recoverable fatal error occurred."); }; @@ -88,7 +122,11 @@ Setup(context => Information("Building version {0} of ReactiveUI.", informationalVersion); CreateDirectory(artifactDirectory); + CleanDirectories(artifactDirectory); CreateDirectory(testsArtifactDirectory); + CreateDirectory(eventsArtifactDirectory); + CreateDirectory(binariesArtifactDirectory); + CreateDirectory(packagesArtifactDirectory); }); Teardown(context => @@ -100,31 +138,37 @@ Teardown(context => ////////////////////////////////////////////////////////////////////// // HELPER METHODS ////////////////////////////////////////////////////////////////////// -Action Build = (solution, outputFolder, createPackage, forceUseFullDebugType) => +Action Build = (solution, packageOutputPath, createPackage, forceUseFullDebugType) => { - Information("Building {0} using {1}, createPackage = {2}", solution, msBuildPath, createPackage); + Information("Building {0} using {1}, createPackage = {2}, forceUseFullDebugType = {3}", solution, msBuildPath, createPackage, forceUseFullDebugType); var msBuildSettings = new MSBuildSettings() { ToolPath = msBuildPath, - ArgumentCustomization = args => args.Append("/m /restore /NoWarn:VSX1000") + ArgumentCustomization = args => args.Append("/m /NoWarn:VSX1000"), + NodeReuse = false, + Restore = true } .WithProperty("TreatWarningsAsErrors", treatWarningsAsErrors.ToString()) .SetConfiguration("Release") - .SetVerbosity(Verbosity.Minimal) - .SetNodeReuse(false); + .SetVerbosity(Verbosity.Minimal); - if (createPackage) + if (forceUseFullDebugType) { - msBuildSettings = msBuildSettings.WithProperty("PackageOutputPath", MakeAbsolute(Directory(outputFolder)).ToString().Quote()).WithTarget("build;pack"); + msBuildSettings = msBuildSettings.WithProperty("DebugType", "full"); } - else + + if (createPackage) { - msBuildSettings = msBuildSettings.WithProperty("OutputPath", MakeAbsolute(Directory(outputFolder)).ToString().Quote()).WithTarget("build"); + if (!string.IsNullOrWhiteSpace(packageOutputPath)) + { + msBuildSettings = msBuildSettings.WithProperty("PackageOutputPath", MakeAbsolute(Directory(packageOutputPath)).ToString().Quote()); + } + + msBuildSettings = msBuildSettings.WithTarget("build;pack"); } - - if (forceUseFullDebugType) + else { - msBuildSettings = msBuildSettings.WithProperty("DebugType", "full"); + msBuildSettings = msBuildSettings.WithTarget("build"); } MSBuild(solution, msBuildSettings); @@ -135,7 +179,7 @@ Action Build = (solution, outputFolder, createPackag ////////////////////////////////////////////////////////////////////// Task("BuildEventBuilder") - .Does (() => + .Does(() => { Build("./src/EventBuilder.sln", artifactDirectory + "eventbuilder", false, false); }); @@ -144,8 +188,8 @@ Task("GenerateEvents") .IsDependentOn("BuildEventBuilder") .Does (() => { - var workingDirectory = artifactDirectory + "eventbuilder/"; - var eventBuilder = workingDirectory + "EventBuilder.dll"; + var workingDirectory = MakeAbsolute(Directory("./src/EventBuilder/bin/Release/netcoreapp2.1")); + var eventBuilder = workingDirectory + "/EventBuilder.dll"; var referenceAssembliesPath = vsLocation.CombineWithFilePath("./Common7/IDE/ReferenceAssemblies/Microsoft/Framework"); Information(referenceAssembliesPath.ToString()); @@ -172,55 +216,55 @@ Task("GenerateEvents") Information("The events have been written to '{0}'", output); }; - generate("android", "src/ReactiveUI.Events/"); - generate("ios", "src/ReactiveUI.Events/"); - generate("mac", "src/ReactiveUI.Events/"); - generate("uwp", "src/ReactiveUI.Events/"); - generate("tizen4", "src/ReactiveUI.Events/"); - generate("wpf", "src/ReactiveUI.Events.WPF/"); - generate("xamforms", "src/ReactiveUI.Events.XamForms/"); - generate("winforms", "src/ReactiveUI.Events.Winforms/"); - generate("essentials", "src/ReactiveUI.Events/"); - generate("tvos", "src/ReactiveUI.Events/"); + Parallel.ForEach(eventGenerators, arg => generate(arg.targetName, arg.destination)); + + CopyFiles(GetFiles("./src/ReactiveUI.**/Events_*.cs"), Directory(eventsArtifactDirectory)); }); -Task("BuildReactiveUI") +Task("BuildReactiveUIPackages") .IsDependentOn("GenerateEvents") .Does (() => { + // Clean the directories since we'll need to re-generate the debug type. + CleanDirectories("./src/**/obj/Release"); + CleanDirectories("./src/**/bin/Release"); + foreach(var package in packageWhitelist) { - Build("./src/" + package + "/" + package + ".csproj", artifactDirectory, true, false); + Build("./src/" + package + "/" + package + ".csproj", packagesArtifactDirectory, true, false); } + + CopyFiles(GetFiles("./src/**/bin/Release/**/*"), Directory(binariesArtifactDirectory), true); }); Task("RunUnitTests") - .IsDependentOn("BuildReactiveUI") + .IsDependentOn("BuildReactiveUIPackages") .Does(() => { - Action RunTests = (tool, projectName) => { - var testsArtifactProjectDirectory = testsArtifactDirectory + projectName + "/"; - Build("./src/" + projectName + "/" + projectName + ".csproj", testsArtifactProjectDirectory, false, true); - - var xunitSettings = new XUnit2Settings { - OutputDirectory = testsArtifactProjectDirectory, - XmlReport = true, - NoAppDomain = true - }; + var fodyPackages = new string[] + { + "ReactiveUI.Fody", + "ReactiveUI.Fody.Helpers", + }; - tool.XUnit2(testsArtifactProjectDirectory + "**/*.Tests.dll", xunitSettings); - }; + // Clean the directories since we'll need to re-generate the debug type. + CleanDirectories("./src/**/obj/Release"); + CleanDirectories("./src/**/bin/Release"); + + foreach (var package in fodyPackages) + { + Build("./src/" + package + "/" + package + ".csproj", null, true, true); + } var openCoverSettings = new OpenCoverSettings { ReturnTargetCodeOffset = 0, - ArgumentCustomization = args => args.Append("-mergeoutput") + MergeOutput = true, } .WithFilter("+[*]*") .WithFilter("-[*.Testing]*") .WithFilter("-[*.Tests*]*") .WithFilter("-[ReactiveUI.Events]*") .WithFilter("-[Splat*]*") - .WithFilter("-[ApprovalTests*]*") .ExcludeByAttribute("*.ExcludeFromCodeCoverage*") .ExcludeByFile("*/*Designer.cs") .ExcludeByFile("*/*.g.cs") @@ -228,13 +272,25 @@ Task("RunUnitTests") .ExcludeByFile("*splat/splat*") .ExcludeByFile("*ApprovalTests*"); - OpenCover(tool => RunTests(tool, "ReactiveUI.Tests"), testCoverageOutputFile, openCoverSettings); - OpenCover(tool => RunTests(tool, "ReactiveUI.Fody.Tests"), testCoverageOutputFile, openCoverSettings); - // TODO: seems the leak tests never worked as part of the CI, fix. For the moment just make sure it compiles. - // OpenCover(tool => RunTests(tool, "ReactiveUI.LeakTests"), testCoverageOutputFile, openCoverSettings); - Build("./src/ReactiveUI.LeakTests/ReactiveUI.LeakTests.csproj", testsArtifactDirectory + "LeakTests/", false, true); + var xunitSettings = new XUnit2Settings { + HtmlReport = true, + OutputDirectory = testsArtifactDirectory, + NoAppDomain = true + }; + + foreach (var projectName in packageTestWhitelist) + { + OpenCover(tool => + { + Build("./src/" + projectName + "/" + projectName + ".csproj", null, true, true); + + tool.XUnit2("./src/" + projectName + "/bin/" + "**/*.Tests.dll", xunitSettings); + }, + testCoverageOutputFile, + openCoverSettings); + } - ReportGenerator(testCoverageOutputFile, artifactDirectory); + ReportGenerator(testCoverageOutputFile, testsArtifactDirectory + "Report/"); }).ReportError(exception => { var apiApprovals = GetFiles("./**/ApiApprovalTests.*"); @@ -248,13 +304,13 @@ Task("UploadTestCoverage") .Does(() => { // Resolve the API key. - var token = EnvironmentVariable("COVERALLS_TOKEN"); + var token = EnvironmentVariable("CODECOV_TOKEN"); if (!string.IsNullOrEmpty(token)) { - CoverallsIo(testCoverageOutputFile, new CoverallsIoSettings() - { - RepoToken = token - }); + Information("Upload {0} to Codecov server", testCoverageOutputFile); + + // Upload a coverage report. + Codecov(testCoverageOutputFile.ToString(), token); } }); @@ -269,7 +325,7 @@ Task("SignPackages") }); Task("Package") - .IsDependentOn("BuildReactiveUI") + .IsDependentOn("BuildReactiveUIPackages") .IsDependentOn("RunUnitTests") .IsDependentOn("UploadTestCoverage") .IsDependentOn("PinNuGetDependencies") diff --git a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj index dc62c0d1ab..1f86de5026 100644 --- a/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj +++ b/src/ReactiveUI.Fody.Helpers/ReactiveUI.Fody.Helpers.csproj @@ -47,5 +47,6 @@ + diff --git a/tools/nuget/nuget.exe b/tools/nuget/nuget.exe index dd49d258ba..4f9055090c 100644 --- a/tools/nuget/nuget.exe +++ b/tools/nuget/nuget.exe @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2c562c1a18d720d4885546083ec8eaad6773a6b80befb02564088cc1e55b304e -size 5336752 +oid sha256:dd283b92d03faff8f8816d631a8c859feae6c0ce260fe68ae7e61849a157821f +size 5687056