Use dev00001 build of common NUnit cake recipe
This commit is contained in:
Родитель
43310d4216
Коммит
3a021451be
|
@ -19,3 +19,4 @@ environment:
|
|||
secure: aDsu1U+umVYFVybjkBVtVQsatSj3QKbD7VkGQci9mNF3493g9Giao/GABISIaHjT
|
||||
GITHUB_ACCESS_TOKEN:
|
||||
secure: xmGXWrw5Nj3CI3fPxhw/DWIU5YL/1mM06pSmjpkd9LpKs3t3EYXbECbEQs62lU/O
|
||||
IGNORE_NORMALISATION_GIT_HEAD_MOVE: 1
|
24
build.cake
24
build.cake
|
@ -1,14 +1,11 @@
|
|||
#tool NuGet.CommandLine&version=6.9.1
|
||||
#tool nuget:?package=GitVersion.CommandLine&version=5.6.3
|
||||
#tool nuget:?package=GitReleaseManager&version=0.17.0
|
||||
#tool nuget:?package=NUnit.ConsoleRunner&version=3.17.0
|
||||
#tool nuget:?package=NUnit.ConsoleRunner&version=3.15.5
|
||||
#tool nuget:?package=NUnit.ConsoleRUnner&version=3.17.0
|
||||
#tool nuget:?package=NUnit.ConsoleRunner&version=3.18.0-dev00037
|
||||
#tool nuget:?package=NUnit.ConsoleRunner.NetCore&version=3.18.0-dev00037
|
||||
|
||||
// Load scripts
|
||||
#load recipe/*.cake
|
||||
#load nuget:?package=NUnit.Cake.Recipe&version=1.0.0-dev00001
|
||||
//#load ../NUnit.Cake.Recipe/recipe/*.cake
|
||||
|
||||
// Initialize BuildSettings
|
||||
BuildSettings.Initialize(
|
||||
|
@ -16,12 +13,8 @@ BuildSettings.Initialize(
|
|||
"NUnit Project Loader",
|
||||
"nunit-project-loader",
|
||||
solutionFile: "nunit-project-loader.sln",
|
||||
//unitTestRunner: new NUnitLiteRunner(),
|
||||
//unitTests: "**/*.Tests.exe");
|
||||
unitTestRunner: new NUnitConsoleRunner("3.17.0"),
|
||||
unitTests: "**/*.Tests.dll");
|
||||
//unitTestRunner: new NUnitNetCoreConsoleRunner("3.18.0-dev00037"),
|
||||
//unitTests: "**/*.Tests.dll");
|
||||
unitTestRunner: new NUnitLiteRunner(),
|
||||
unitTests: "**/*.Tests.exe");
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// PACKAGE TESTS
|
||||
|
@ -100,11 +93,6 @@ BuildSettings.Packages.Add(
|
|||
HasDirectory("tools/net6.0").WithFiles("nunit-project-loader.dll", "nunit.engine.api.dll") },
|
||||
tests: PackageTests,
|
||||
testRunnerSource: new TestRunnerSource(new NUnitConsoleRunner("3.17.0"), new NUnitConsoleRunner("3.15.5"), new NUnitConsoleRunner("3.18.0-dev00037"))
|
||||
//testRunner: new NUnitConsoleRunner("3.17.0")
|
||||
//testRunner: new NUnitConsoleRunner("3.15.5")
|
||||
//testRunner: new NUnitConsoleRunner("3.18.0-dev00037")
|
||||
//testRunner: new NUnitNetCoreConsoleRunner("3.18.0-dev00037")
|
||||
//testRunner: new EngineExtensionTestRunner()
|
||||
));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
@ -121,10 +109,6 @@ BuildSettings.Packages.Add(
|
|||
HasDirectory("tools/net6.0").WithFiles("nunit-project-loader.dll", "nunit.engine.api.dll") },
|
||||
tests: PackageTests,
|
||||
testRunnerSource: new TestRunnerSource(new NUnitConsoleRunner("3.17.0"), new NUnitConsoleRunner("3.15.5"), new NUnitConsoleRunner("3.18.0-dev00037"))
|
||||
//testRunner: new NUnitConsoleRunner("3.17.0")
|
||||
//testRunner: new NUnitConsoleRunner("3.15.5")
|
||||
//testRunner: new NUnitConsoleRunner("3.18.0-dev00037")
|
||||
//testRunner: new NUnitNetCoreConsoleRunner("3.18.0-dev00037")
|
||||
));
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -29,38 +29,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "test-lib-1", "src\test-lib-
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "test-lib-2", "src\test-lib-2\test-lib-2.csproj", "{7808DEA9-FB13-47FC-823F-DC78C1057061}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "recipe", "recipe", "{7EE5FBD2-CD4B-4FB0-9F36-29665955E8BE}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
recipe\banner.cake = recipe\banner.cake
|
||||
recipe\build-settings.cake = recipe\build-settings.cake
|
||||
recipe\builder.cake = recipe\builder.cake
|
||||
recipe\chocolatey-package.cake = recipe\chocolatey-package.cake
|
||||
recipe\command-line-options.cake = recipe\command-line-options.cake
|
||||
recipe\constants.cake = recipe\constants.cake
|
||||
recipe\dotnet.cake = recipe\dotnet.cake
|
||||
recipe\extending.cake = recipe\extending.cake
|
||||
recipe\headers.cake = recipe\headers.cake
|
||||
recipe\help-messages.cake = recipe\help-messages.cake
|
||||
recipe\known-extensions.cake = recipe\known-extensions.cake
|
||||
recipe\nuget-package.cake = recipe\nuget-package.cake
|
||||
recipe\package-checks.cake = recipe\package-checks.cake
|
||||
recipe\package-reference.cake = recipe\package-reference.cake
|
||||
recipe\package-definition.cake = recipe\package-definition.cake
|
||||
recipe\package-test.cake = recipe\package-test.cake
|
||||
recipe\publishing.cake = recipe\publishing.cake
|
||||
recipe\setup.cake = recipe\setup.cake
|
||||
recipe\task-builders.cake = recipe\task-builders.cake
|
||||
recipe\task-definitions.cake = recipe\task-definitions.cake
|
||||
recipe\test-reports.cake = recipe\test-reports.cake
|
||||
recipe\test-results.cake = recipe\test-results.cake
|
||||
recipe\test-runners.cake = recipe\test-runners.cake
|
||||
recipe\tools.cake = recipe\tools.cake
|
||||
recipe\unit-testing.cake = recipe\unit-testing.cake
|
||||
recipe\utilities.cake = recipe\utilities.cake
|
||||
recipe\versioning.cake = recipe\versioning.cake
|
||||
recipe\zip-package.cake = recipe\zip-package.cake
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{6C381491-0062-4276-B884-86A6A175FFF5}"
|
||||
ProjectSection(SolutionItems) = preProject
|
||||
nuget\nunit-project-loader.legacy.addins = nuget\nunit-project-loader.legacy.addins
|
||||
|
@ -101,7 +69,6 @@ Global
|
|||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(NestedProjects) = preSolution
|
||||
{7EE5FBD2-CD4B-4FB0-9F36-29665955E8BE} = {3B28CF0C-D613-4971-9D8F-00C960C656E2}
|
||||
{6C381491-0062-4276-B884-86A6A175FFF5} = {3B28CF0C-D613-4971-9D8F-00C960C656E2}
|
||||
{2DA8DF86-18D3-4832-970C-A0B26498B93D} = {3B28CF0C-D613-4971-9D8F-00C960C656E2}
|
||||
EndGlobalSection
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
// Banner class displays banners similar to those created by Cake
|
||||
// We use this to display intermediate steps within a task
|
||||
public static class Banner
|
||||
{
|
||||
public static void Display(string message, char barChar='-', int length=0)
|
||||
{
|
||||
if (length == 0) length = MaxLineLength(message);
|
||||
var bar = new string(barChar, length);
|
||||
|
||||
Console.WriteLine();
|
||||
Console.WriteLine(bar);
|
||||
Console.WriteLine(message);
|
||||
Console.WriteLine(bar);
|
||||
|
||||
int MaxLineLength(string message)
|
||||
{
|
||||
int length = 0;
|
||||
foreach (string line in message.Split(Environment.NewLine, StringSplitOptions.RemoveEmptyEntries))
|
||||
length = Math.Max(length, line.Length);
|
||||
return length;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,342 +0,0 @@
|
|||
public static class BuildSettings
|
||||
{
|
||||
private static BuildSystem _buildSystem;
|
||||
|
||||
public static void Initialize(
|
||||
// Required parameters
|
||||
ICakeContext context,
|
||||
string title,
|
||||
string githubRepository,
|
||||
|
||||
// Optional Parameters
|
||||
bool suppressHeaderCheck = false,
|
||||
string[] standardHeader = null,
|
||||
string[] exemptFiles = null,
|
||||
|
||||
string solutionFile = null,
|
||||
string[] validConfigurations = null,
|
||||
string githubOwner = "NUnit",
|
||||
|
||||
bool msbuildAllowPreviewVersion = false,
|
||||
Verbosity msbuildVerbosity = Verbosity.Minimal,
|
||||
|
||||
string unitTests = null, // Defaults to "**/*.tests.dll|**/*.tests.exe" (case insensitive)
|
||||
IUnitTestRunner unitTestRunner = null, // If not set, NUnitLite is used
|
||||
string unitTestArguments = null
|
||||
)
|
||||
{
|
||||
// Required arguments
|
||||
Context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
Title = title ?? throw new ArgumentNullException(nameof(title));
|
||||
GitHubRepository = githubRepository ?? throw new ArgumentNullException(nameof(githubRepository));
|
||||
|
||||
// NOTE: Order of initialization can be sensitive. Obviously,
|
||||
// we have to set any properties in this method before we
|
||||
// make use of them. Less obviously, some of the classes we
|
||||
// construct here have dependencies on certain properties
|
||||
// being set before the constructor is called. I have
|
||||
// tried to annotate such dependencies below.
|
||||
|
||||
_buildSystem = context.BuildSystem();
|
||||
|
||||
SolutionFile = solutionFile ?? DeduceSolutionFile();
|
||||
|
||||
ValidConfigurations = validConfigurations ?? DEFAULT_VALID_CONFIGS;
|
||||
|
||||
UnitTests = unitTests;
|
||||
// NUnitLiteRunner depends indirectly on ValidConfigurations
|
||||
UnitTestRunner = unitTestRunner ?? new NUnitLiteRunner();
|
||||
UnitTestArguments = unitTestArguments;
|
||||
|
||||
BuildVersion = new BuildVersion(context);
|
||||
|
||||
GitHubOwner = githubOwner;
|
||||
|
||||
// File Header Checks
|
||||
SuppressHeaderCheck = suppressHeaderCheck && !CommandLineOptions.NoBuild;
|
||||
StandardHeader = standardHeader ?? DEFAULT_STANDARD_HEADER;
|
||||
ExemptFiles = exemptFiles ?? new string[0];
|
||||
|
||||
//if (defaultTarget != null)
|
||||
// BuildTasks.DefaultTask.IsDependentOn(defaultTarget);
|
||||
|
||||
// Skip remaining initialization if help was requested
|
||||
if (CommandLineOptions.Usage)
|
||||
return;
|
||||
|
||||
ValidateSettings();
|
||||
|
||||
context.Information($"{Title} {Configuration} version {PackageVersion}");
|
||||
|
||||
// Output like this should go after the run title display
|
||||
if (solutionFile == null && SolutionFile != null)
|
||||
Context.Warning($" SolutionFile: '{SolutionFile}'");
|
||||
Context.Information($" PackageTestLevel: {PackageTestLevel}");
|
||||
|
||||
// Keep this last
|
||||
if (IsRunningOnAppVeyor)
|
||||
{
|
||||
var buildNumber = _buildSystem.AppVeyor.Environment.Build.Number;
|
||||
_buildSystem.AppVeyor.UpdateBuildVersion($"{PackageVersion}-{buildNumber}");
|
||||
}
|
||||
}
|
||||
|
||||
// If solution file was not provided, uses TITLE.sln if it exists or
|
||||
// the solution found in the root directory provided there is only one.
|
||||
private static string DeduceSolutionFile()
|
||||
{
|
||||
if (SIO.File.Exists(Title + ".sln"))
|
||||
return Title + ".sln";
|
||||
|
||||
var files = SIO.Directory.GetFiles(ProjectDirectory, "*.sln");
|
||||
if (files.Length == 1 && SIO.File.Exists(files[0]))
|
||||
return files[0];
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int CalcPackageTestLevel()
|
||||
{
|
||||
if (!BuildVersion.IsPreRelease)
|
||||
return 3;
|
||||
|
||||
// TODO: The prerelease label is no longer being set to pr by GitVersion
|
||||
// for some reason. This check in AppVeyor is a workaround.
|
||||
if (IsRunningOnAppVeyor && _buildSystem.AppVeyor.Environment.PullRequest.IsPullRequest)
|
||||
return 2;
|
||||
|
||||
switch (BuildVersion.PreReleaseLabel)
|
||||
{
|
||||
case "pre":
|
||||
case "rc":
|
||||
case "alpha":
|
||||
case "beta":
|
||||
return 3;
|
||||
|
||||
case "dev":
|
||||
case "pr":
|
||||
return 2;
|
||||
|
||||
case "ci":
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Cake Context
|
||||
public static ICakeContext Context { get; private set; }
|
||||
|
||||
// NOTE: These are set in setup.cake
|
||||
public static string Target { get; set; }
|
||||
public static IEnumerable<string> TasksToExecute { get; set; }
|
||||
|
||||
// Arguments
|
||||
public static string Configuration
|
||||
{
|
||||
get
|
||||
{
|
||||
// Correct casing on user-provided config if necessary
|
||||
foreach (string config in ValidConfigurations)
|
||||
if (string.Equals(config, CommandLineOptions.Configuration.Value, StringComparison.OrdinalIgnoreCase))
|
||||
return config;
|
||||
|
||||
// Return the (invalid) user-provided config
|
||||
return CommandLineOptions.Configuration.Value;
|
||||
}
|
||||
}
|
||||
|
||||
// Build Environment
|
||||
public static bool IsLocalBuild => _buildSystem.IsLocalBuild;
|
||||
public static bool IsRunningOnUnix => Context.IsRunningOnUnix();
|
||||
public static bool IsRunningOnWindows => Context.IsRunningOnWindows();
|
||||
public static bool IsRunningOnAppVeyor => _buildSystem.AppVeyor.IsRunningOnAppVeyor;
|
||||
|
||||
// Versioning
|
||||
public static BuildVersion BuildVersion { get; private set;}
|
||||
public static string BranchName => BuildVersion.BranchName;
|
||||
public static bool IsReleaseBranch => BuildVersion.IsReleaseBranch;
|
||||
public static string PackageVersion => BuildVersion.PackageVersion;
|
||||
public static string AssemblyVersion => BuildVersion.AssemblyVersion;
|
||||
public static string AssemblyFileVersion => BuildVersion.AssemblyFileVersion;
|
||||
public static string AssemblyInformationalVersion => BuildVersion.AssemblyInformationalVersion;
|
||||
public static bool IsDevelopmentRelease => PackageVersion.Contains("-dev");
|
||||
|
||||
// Standard Directory Structure - not changeable by user
|
||||
public static string ProjectDirectory => Context.Environment.WorkingDirectory.FullPath + "/";
|
||||
public static string SourceDirectory => ProjectDirectory + SRC_DIR;
|
||||
public static string OutputDirectory => ProjectDirectory + BIN_DIR + Configuration + "/";
|
||||
public static string NuGetDirectory => ProjectDirectory + NUGET_DIR;
|
||||
public static string ChocolateyDirectory => ProjectDirectory + CHOCO_DIR;
|
||||
public static string ZipDirectory => ProjectDirectory + ZIP_DIR;
|
||||
public static string PackageDirectory => ProjectDirectory + PACKAGE_DIR;
|
||||
public static string PackageTestDirectory => ProjectDirectory + PKG_TEST_DIR;
|
||||
public static string NuGetTestDirectory => ProjectDirectory + NUGET_TEST_DIR;
|
||||
public static string ChocolateyTestDirectory => ProjectDirectory + CHOCO_TEST_DIR;
|
||||
public static string ZipTestDirectory => ProjectDirectory + ZIP_TEST_DIR;
|
||||
public static string PackageResultDirectory => ProjectDirectory + PKG_RSLT_DIR;
|
||||
public static string NuGetResultDirectory => ProjectDirectory + NUGET_RSLT_DIR;
|
||||
public static string ChocolateyResultDirectory => ProjectDirectory + CHOCO_RSLT_DIR;
|
||||
public static string ZipResultDirectory => ProjectDirectory + ZIP_RSLT_DIR;
|
||||
public static string ImageDirectory => ProjectDirectory + IMAGE_DIR;
|
||||
public static string ZipImageDirectory => ProjectDirectory + ZIP_IMG_DIR;
|
||||
public static string ExtensionsDirectory => ProjectDirectory + "bundled-extensions/";
|
||||
public static string ToolsDirectory => ProjectDirectory + "tools/";
|
||||
|
||||
// Files
|
||||
public static string SolutionFile { get; set; }
|
||||
|
||||
// Building
|
||||
public static string[] ValidConfigurations { get; set; }
|
||||
public static bool MSBuildAllowPreviewVersion { get; set; }
|
||||
public static Verbosity MSBuildVerbosity { get; set; }
|
||||
public static MSBuildSettings MSBuildSettings => new MSBuildSettings {
|
||||
Verbosity = MSBuildVerbosity,
|
||||
Configuration = Configuration,
|
||||
PlatformTarget = PlatformTarget.MSIL,
|
||||
AllowPreviewVersion = MSBuildAllowPreviewVersion
|
||||
};
|
||||
|
||||
// File Header Checks
|
||||
public static bool SuppressHeaderCheck { get; private set; }
|
||||
public static string[] StandardHeader { get; private set; }
|
||||
public static string[] ExemptFiles { get; private set; }
|
||||
|
||||
//Testing
|
||||
public static string UnitTests { get; set; }
|
||||
public static IUnitTestRunner UnitTestRunner { get; private set; }
|
||||
public static string UnitTestArguments { get; private set; }
|
||||
|
||||
// Packaging
|
||||
public static string Title { get; private set; }
|
||||
public static List<PackageDefinition> Packages { get; } = new List<PackageDefinition>();
|
||||
|
||||
// Package Testing
|
||||
public static int PackageTestLevel =>
|
||||
CommandLineOptions.TestLevel.Value > 0
|
||||
? CommandLineOptions.TestLevel.Value
|
||||
: CalcPackageTestLevel();
|
||||
|
||||
// Publishing - MyGet
|
||||
public static string MyGetPushUrl => MYGET_PUSH_URL;
|
||||
public static string MyGetApiKey => Context.EnvironmentVariable(MYGET_API_KEY);
|
||||
|
||||
// Publishing - NuGet
|
||||
public static string NuGetPushUrl => NUGET_PUSH_URL;
|
||||
public static string NuGetApiKey => Context.EnvironmentVariable(NUGET_API_KEY);
|
||||
|
||||
// Publishing - Chocolatey
|
||||
public static string ChocolateyPushUrl => CHOCO_PUSH_URL;
|
||||
public static string ChocolateyApiKey => Context.EnvironmentVariable(CHOCO_API_KEY);
|
||||
|
||||
// Publishing - GitHub
|
||||
public static string GitHubOwner { get; set; }
|
||||
public static string GitHubRepository { get; set; }
|
||||
public static string GitHubAccessToken => Context.EnvironmentVariable(GITHUB_ACCESS_TOKEN);
|
||||
|
||||
public static bool IsPreRelease => BuildVersion.IsPreRelease;
|
||||
public static bool ShouldPublishToMyGet =>
|
||||
!IsPreRelease || LABELS_WE_PUBLISH_ON_MYGET.Contains(BuildVersion.PreReleaseLabel);
|
||||
public static bool ShouldPublishToNuGet =>
|
||||
!IsPreRelease || LABELS_WE_PUBLISH_ON_NUGET.Contains(BuildVersion.PreReleaseLabel);
|
||||
public static bool ShouldPublishToChocolatey =>
|
||||
!IsPreRelease || LABELS_WE_PUBLISH_ON_CHOCOLATEY.Contains(BuildVersion.PreReleaseLabel);
|
||||
public static bool IsProductionRelease =>
|
||||
!IsPreRelease || LABELS_WE_RELEASE_ON_GITHUB.Contains(BuildVersion.PreReleaseLabel);
|
||||
|
||||
private static void ValidateSettings()
|
||||
{
|
||||
var validationErrors = new List<string>();
|
||||
|
||||
if (!ValidConfigurations.Contains(Configuration))
|
||||
validationErrors.Add($"Invalid configuration: {Configuration}");
|
||||
|
||||
if (validationErrors.Count > 0)
|
||||
{
|
||||
DumpSettings();
|
||||
|
||||
var msg = new StringBuilder("Parameter validation failed! See settings above.\n\nErrors found:\n");
|
||||
foreach (var error in validationErrors)
|
||||
msg.AppendLine(" " + error);
|
||||
|
||||
throw new InvalidOperationException(msg.ToString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void DumpSettings()
|
||||
{
|
||||
Console.WriteLine("\nTASKS");
|
||||
Console.WriteLine("Target: " + Target);
|
||||
Console.WriteLine("TasksToExecute: " + string.Join(", ", TasksToExecute));
|
||||
|
||||
Console.WriteLine("\nENVIRONMENT");
|
||||
Console.WriteLine("IsLocalBuild: " + IsLocalBuild);
|
||||
Console.WriteLine("IsRunningOnWindows: " + IsRunningOnWindows);
|
||||
Console.WriteLine("IsRunningOnUnix: " + IsRunningOnUnix);
|
||||
Console.WriteLine("IsRunningOnAppVeyor: " + IsRunningOnAppVeyor);
|
||||
|
||||
Console.WriteLine("\nVERSIONING");
|
||||
Console.WriteLine("PackageVersion: " + PackageVersion);
|
||||
Console.WriteLine("AssemblyVersion: " + AssemblyVersion);
|
||||
Console.WriteLine("AssemblyFileVersion: " + AssemblyFileVersion);
|
||||
Console.WriteLine("AssemblyInformationalVersion: " + AssemblyInformationalVersion);
|
||||
Console.WriteLine("SemVer: " + BuildVersion.SemVer);
|
||||
Console.WriteLine("IsPreRelease: " + BuildVersion.IsPreRelease);
|
||||
Console.WriteLine("PreReleaseLabel: " + BuildVersion.PreReleaseLabel);
|
||||
Console.WriteLine("PreReleaseSuffix: " + BuildVersion.PreReleaseSuffix);
|
||||
|
||||
Console.WriteLine("\nDIRECTORIES");
|
||||
Console.WriteLine("Project: " + ProjectDirectory);
|
||||
Console.WriteLine("Output: " + OutputDirectory);
|
||||
Console.WriteLine("Source: " + SourceDirectory);
|
||||
Console.WriteLine("NuGet: " + NuGetDirectory);
|
||||
Console.WriteLine("Chocolatey: " + ChocolateyDirectory);
|
||||
Console.WriteLine("Package: " + PackageDirectory);
|
||||
Console.WriteLine("PackageTest: " + PackageTestDirectory);
|
||||
Console.WriteLine("NuGetTest: " + NuGetTestDirectory);
|
||||
Console.WriteLine("ChocoTest: " + ChocolateyTestDirectory);
|
||||
Console.WriteLine("ZipTest: " + ZipTestDirectory);
|
||||
Console.WriteLine("PackageResult: " + PackageResultDirectory);
|
||||
Console.WriteLine("NuGetResult: " + NuGetResultDirectory);
|
||||
Console.WriteLine("ChocoResult: " + ChocolateyResultDirectory);
|
||||
Console.WriteLine("ZipResult: " + ZipResultDirectory);
|
||||
Console.WriteLine("Image: " + ImageDirectory);
|
||||
Console.WriteLine("ZipImage: " + ZipImageDirectory);
|
||||
|
||||
Console.WriteLine("\nBUILD");
|
||||
Console.WriteLine("Configuration: " + Configuration);
|
||||
|
||||
Console.WriteLine("\nUNIT TESTS");
|
||||
Console.WriteLine("UnitTests: " + UnitTests);
|
||||
Console.WriteLine("UnitTestRunner: " + UnitTestRunner?.GetType().Name ?? "<NUnitLiteRunner>");
|
||||
|
||||
Console.WriteLine("\nPACKAGING");
|
||||
Console.WriteLine("PackageTestLevel: " + PackageTestLevel);
|
||||
Console.WriteLine("MyGetPushUrl: " + MyGetPushUrl);
|
||||
Console.WriteLine("NuGetPushUrl: " + NuGetPushUrl);
|
||||
Console.WriteLine("ChocolateyPushUrl: " + ChocolateyPushUrl);
|
||||
Console.WriteLine("MyGetApiKey: " + (!string.IsNullOrEmpty(MyGetApiKey) ? "AVAILABLE" : "NOT AVAILABLE"));
|
||||
Console.WriteLine("NuGetApiKey: " + (!string.IsNullOrEmpty(NuGetApiKey) ? "AVAILABLE" : "NOT AVAILABLE"));
|
||||
Console.WriteLine("ChocolateyApiKey: " + (!string.IsNullOrEmpty(ChocolateyApiKey) ? "AVAILABLE" : "NOT AVAILABLE"));
|
||||
Console.WriteLine("GitHubAccessToken: " + (!string.IsNullOrEmpty(GitHubAccessToken) ? "AVAILABLE" : "NOT AVAILABLE"));
|
||||
|
||||
Console.WriteLine("\nPACKAGES");
|
||||
foreach (var package in Packages)
|
||||
{
|
||||
Console.WriteLine(package.PackageId);
|
||||
Console.WriteLine(" PackageType: " + package.PackageType);
|
||||
Console.WriteLine(" PackageFileName: " + package.PackageFileName);
|
||||
Console.WriteLine(" PackageInstallDirectory: " + package.PackageInstallDirectory);
|
||||
Console.WriteLine(" PackageTestDirectory: " + package.PackageTestDirectory);
|
||||
}
|
||||
|
||||
Console.WriteLine("\nPUBLISHING");
|
||||
Console.WriteLine("ShouldPublishToMyGet: " + ShouldPublishToMyGet);
|
||||
Console.WriteLine("ShouldPublishToNuGet: " + ShouldPublishToNuGet);
|
||||
Console.WriteLine("ShouldPublishToChocolatey: " + ShouldPublishToChocolatey);
|
||||
|
||||
Console.WriteLine("\nRELEASING");
|
||||
Console.WriteLine("BranchName: " + BranchName);
|
||||
Console.WriteLine("IsReleaseBranch: " + IsReleaseBranch);
|
||||
Console.WriteLine("IsProductionRelease: " + IsProductionRelease);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// EXECUTION
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public Builder Build => CommandLineOptions.Usage
|
||||
? new Builder(() => Information(HelpMessages.Usage))
|
||||
: new Builder(() => RunTarget(CommandLineOptions.Target.Value));
|
||||
|
||||
public class Builder
|
||||
{
|
||||
private Action _action;
|
||||
|
||||
public Builder(Action action)
|
||||
{
|
||||
_action = action;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
_action();
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
public class ChocolateyPackage : PackageDefinition
|
||||
{
|
||||
public ChocolateyPackage(
|
||||
string id,
|
||||
string source,
|
||||
IPackageTestRunner testRunner = null,
|
||||
TestRunnerSource testRunnerSource = null,
|
||||
PackageCheck[] checks = null,
|
||||
IEnumerable<PackageTest> tests = null)
|
||||
: base(
|
||||
PackageType.Chocolatey,
|
||||
id,
|
||||
source,
|
||||
testRunner: testRunner,
|
||||
testRunnerSource: testRunnerSource,
|
||||
checks: checks,
|
||||
tests: tests)
|
||||
{
|
||||
if (!source.EndsWith(".nuspec"))
|
||||
throw new ArgumentException("Source must be a nuspec file", nameof(source));
|
||||
}
|
||||
|
||||
// The file name of this package, including extension
|
||||
public override string PackageFileName => $"{PackageId}.{PackageVersion}.nupkg";
|
||||
// The file name of any symbol package, including extension
|
||||
public override string SymbolPackageName => SIO.Path.ChangeExtension(PackageFileName, ".snupkg");
|
||||
// The directory into which this package is installed
|
||||
public override string PackageInstallDirectory => BuildSettings.ChocolateyTestDirectory;
|
||||
// The directory used to contain results of package tests for this package
|
||||
public override string PackageResultDirectory => BuildSettings.ChocolateyResultDirectory + PackageId + "/";
|
||||
// The directory into which extensions to the test runner are installed
|
||||
public override string ExtensionInstallDirectory => BuildSettings.PackageTestDirectory;
|
||||
|
||||
public override void BuildPackage()
|
||||
{
|
||||
_context.ChocolateyPack(PackageSource,
|
||||
new ChocolateyPackSettings()
|
||||
{
|
||||
Version = PackageVersion,
|
||||
OutputDirectory = BuildSettings.PackageDirectory,
|
||||
ArgumentCustomization = args => args.Append($"BIN_DIR={BuildSettings.OutputDirectory}")
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
// ***********************************************************************
|
||||
// Copyright (c) Charlie Poole and TestCentric GUI contributors.
|
||||
// Licensed under the MIT License. See LICENSE.txt in root directory.
|
||||
// ***********************************************************************
|
||||
|
||||
CommandLineOptions.Initialize(Context);
|
||||
|
||||
public static class CommandLineOptions
|
||||
{
|
||||
static private ICakeContext _context;
|
||||
|
||||
static public ValueOption<string> Target;
|
||||
static public ValueOption<string> Configuration;
|
||||
static public ValueOption<string> PackageVersion;
|
||||
static public ValueOption<string> PackageSelector;
|
||||
static public ValueOption<int> TestLevel;
|
||||
static public ValueOption<string> TraceLevel;
|
||||
static public SimpleOption NoBuild;
|
||||
static public SimpleOption NoPush;
|
||||
static public SimpleOption Usage;
|
||||
|
||||
public static void Initialize(ICakeContext context)
|
||||
{
|
||||
_context = context;
|
||||
|
||||
// The name of the TARGET task to be run, e.g. Test.
|
||||
Target = new ValueOption<string>("target", "Default", 1);
|
||||
|
||||
Configuration = new ValueOption<String>("configuration", DEFAULT_CONFIGURATION, 1);
|
||||
|
||||
PackageVersion = new ValueOption<string>("packageVersion", null, 4);
|
||||
|
||||
PackageSelector = new ValueOption<string>("where", null, 1);
|
||||
|
||||
TestLevel = new ValueOption<int>("level", 0, 3);
|
||||
|
||||
TraceLevel = new ValueOption<string>("trace", "Off", 2);
|
||||
|
||||
NoBuild = new SimpleOption("nobuild", 3);
|
||||
|
||||
NoPush = new SimpleOption("nopush", 3);
|
||||
|
||||
Usage = new SimpleOption("usage", 2);
|
||||
}
|
||||
|
||||
// Nested classes to represent individual options
|
||||
|
||||
// AbstractOption has a name and can tell us if it exists.
|
||||
public abstract class AbstractOption
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public int MinimumAbbreviation { get; internal set; }
|
||||
|
||||
public bool Exists
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int len = Name.Length; len >= MinimumAbbreviation; len--)
|
||||
if (_context.HasArgument(Name.Substring(0,len)))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public string Description { get; }
|
||||
|
||||
public AbstractOption(string name, int minimumAbbreviation = 0, string description = null)
|
||||
{
|
||||
Name = name;
|
||||
MinimumAbbreviation = minimumAbbreviation > 0 && minimumAbbreviation <= name.Length
|
||||
? minimumAbbreviation
|
||||
: name.Length;
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
|
||||
// Simple Option adds an implicit boolean conversion operator.
|
||||
// It throws an exception if you gave it a value on the command-line.
|
||||
public class SimpleOption : AbstractOption
|
||||
{
|
||||
static public implicit operator bool(SimpleOption o) => o.Exists;
|
||||
|
||||
public SimpleOption(string name, int minimumAbbreviation = 0, string description = null)
|
||||
: base(name, minimumAbbreviation, description)
|
||||
{
|
||||
if (_context.Argument(name, (string)null) != null)
|
||||
throw new Exception($"Option --{name} does not take a value.");
|
||||
}
|
||||
}
|
||||
|
||||
// Generic ValueOption adds Value as well as a default value
|
||||
public class ValueOption<T> : AbstractOption
|
||||
{
|
||||
public T DefaultValue { get; }
|
||||
|
||||
public ValueOption(string name, T defaultValue, int minimumAbbreviation = 0, string description = null)
|
||||
: base(name, minimumAbbreviation, description)
|
||||
{
|
||||
DefaultValue = defaultValue;
|
||||
}
|
||||
|
||||
public T Value
|
||||
{
|
||||
get
|
||||
{
|
||||
for (int len = Name.Length; len >= MinimumAbbreviation; len--)
|
||||
{
|
||||
string abbrev = Name.Substring(0,len);
|
||||
if (_context.HasArgument(abbrev))
|
||||
return _context.Argument<T>(abbrev);
|
||||
}
|
||||
|
||||
return DefaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,53 +0,0 @@
|
|||
// This file contains both real constants and static readonly variables used
|
||||
// as constants. All values are initialized before any instance variables.
|
||||
|
||||
// Alias used throughout the recipe
|
||||
using SIO = System.IO;
|
||||
|
||||
// GitHub owner is the NUnit organization
|
||||
const string GITHUB_OWNER = "nunit";
|
||||
|
||||
// Defaults
|
||||
const string DEFAULT_CONFIGURATION = "Release";
|
||||
private static readonly string[] DEFAULT_VALID_CONFIGS = { "Release", "Debug" };
|
||||
static readonly string[] DEFAULT_STANDARD_HEADER = new[] {
|
||||
"// Copyright (c) Charlie Poole, Rob Prouse and Contributors. MIT License - see LICENSE.txt" };
|
||||
const string DEFAULT_TEST_RESULT_FILE = "TestResult.xml";
|
||||
|
||||
// Standardized project directory structure - not changeable by user
|
||||
const string SRC_DIR = "src/";
|
||||
const string BIN_DIR = "bin/";
|
||||
const string NUGET_DIR = "nuget/";
|
||||
const string CHOCO_DIR = "choco/";
|
||||
const string ZIP_DIR = "zip/";
|
||||
const string PACKAGE_DIR = "package/";
|
||||
const string PKG_TEST_DIR = "package/tests/";
|
||||
const string NUGET_TEST_DIR = "package/tests/nuget/";
|
||||
//const string NUGET_RUNNER_DIR = "package/tests/nuget/runners/";
|
||||
const string CHOCO_TEST_DIR = "package/tests/choco/";
|
||||
//const string CHOCO_RUNNER_DIR = "package/tests/choco/runners/";
|
||||
const string ZIP_TEST_DIR = "package/tests/zip/";
|
||||
const string PKG_RSLT_DIR = "package/results/";
|
||||
const string NUGET_RSLT_DIR = "package/results/nuget/";
|
||||
const string CHOCO_RSLT_DIR = "package/results/choco/";
|
||||
const string ZIP_RSLT_DIR = "package/results/zip/";
|
||||
const string IMAGE_DIR = "package/images";
|
||||
const string ZIP_IMG_DIR = "package/images/zip/";
|
||||
const string TOOLS_DIR = "tools/";
|
||||
|
||||
// URLs for uploading packages
|
||||
private const string MYGET_PUSH_URL = "https://www.myget.org/F/nunit/api/v2";
|
||||
private const string NUGET_PUSH_URL = "https://api.nuget.org/v3/index.json";
|
||||
private const string CHOCO_PUSH_URL = "https://push.chocolatey.org/";
|
||||
|
||||
// Environment Variable names holding API keys
|
||||
private const string MYGET_API_KEY = "MYGET_API_KEY";
|
||||
private const string NUGET_API_KEY = "NUGET_API_KEY";
|
||||
private const string CHOCO_API_KEY = "CHOCO_API_KEY";
|
||||
private const string GITHUB_ACCESS_TOKEN = "GITHUB_ACCESS_TOKEN";
|
||||
|
||||
// Pre-release labels that we publish
|
||||
private static readonly string[] LABELS_WE_PUBLISH_ON_MYGET = { "dev" };
|
||||
private static readonly string[] LABELS_WE_PUBLISH_ON_NUGET = { "alpha", "beta", "rc" };
|
||||
private static readonly string[] LABELS_WE_PUBLISH_ON_CHOCOLATEY = { "alpha", "beta", "rc" };
|
||||
private static readonly string[] LABELS_WE_RELEASE_ON_GITHUB = { "alpha", "beta", "rc" };
|
|
@ -1,88 +0,0 @@
|
|||
public class DotnetInfo
|
||||
{
|
||||
// Experimenting with finding dotnet installs for X64 vs x86
|
||||
// This code will end up moved into the engine as well.
|
||||
|
||||
private ICakeContext _context;
|
||||
private bool _onWindows;
|
||||
|
||||
public DotnetInfo(ICakeContext context)
|
||||
{
|
||||
_context = context;
|
||||
_onWindows = context.IsRunningOnWindows();
|
||||
|
||||
InstallPath = GetDotnetInstallDirectory(false);
|
||||
X86InstallPath = GetDotnetInstallDirectory(true);
|
||||
}
|
||||
|
||||
// NOTES:
|
||||
// * We don't need an IsInstalled property because our scripts all run under dotnet.
|
||||
|
||||
public bool IsX86Installed => SIO.Directory.Exists(X86InstallPath) && SIO.File.Exists(X86Executable);
|
||||
|
||||
public string InstallPath { get; }
|
||||
public string Executable => InstallPath + "dotnet.exe";
|
||||
public List<string> Runtimes { get; }
|
||||
|
||||
public string X86InstallPath { get; }
|
||||
public string X86Executable => X86InstallPath + "dotnet.exe";
|
||||
public List<string> X86Runtimes { get; }
|
||||
|
||||
public void Display()
|
||||
{
|
||||
_context.Information($"Install Path: {InstallPath}");
|
||||
_context.Information($"Executable: {Executable}");
|
||||
_context.Information("Runtimes:");
|
||||
foreach (string dir in SIO.Directory.GetDirectories(SIO.Path.Combine(InstallPath, "shared")))
|
||||
{
|
||||
string runtime = SIO.Path.GetFileName(dir);
|
||||
foreach (string dir2 in SIO.Directory.GetDirectories(dir))
|
||||
{
|
||||
string version = SIO.Path.GetFileName(dir2);
|
||||
_context.Information($" {runtime} {version}");
|
||||
}
|
||||
}
|
||||
|
||||
if (IsX86Installed)
|
||||
{
|
||||
_context.Information($"\nX86 Install Path: {X86InstallPath}");
|
||||
_context.Information($"X86 Executable: {X86Executable}");
|
||||
_context.Information("Runtimes:");
|
||||
foreach (var dir in SIO.Directory.GetDirectories(SIO.Path.Combine(X86InstallPath, "shared")))
|
||||
{
|
||||
string runtime = SIO.Path.GetFileName(dir);
|
||||
foreach (string dir2 in SIO.Directory.GetDirectories(dir))
|
||||
{
|
||||
string version = SIO.Path.GetFileName(dir2);
|
||||
_context.Information($" {runtime} {version}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
_context.Information("\nDotnet X86 is not installed");
|
||||
}
|
||||
|
||||
private string GetDotnetInstallDirectory(bool forX86 = false)
|
||||
{
|
||||
if (_onWindows)
|
||||
{
|
||||
if (forX86)
|
||||
{
|
||||
Microsoft.Win32.RegistryKey key =
|
||||
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\dotnet\SetUp\InstalledVersions\x86\");
|
||||
return (string)key?.GetValue("InstallLocation");
|
||||
}
|
||||
else
|
||||
{
|
||||
Microsoft.Win32.RegistryKey key =
|
||||
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SOFTWARE\dotnet\SetUp\InstalledVersions\x64\sharedHost\");
|
||||
return (string)key?.GetValue("Path");
|
||||
}
|
||||
}
|
||||
else // Assuming linux for now
|
||||
return "/usr/shared/dotnet/";
|
||||
}
|
||||
}
|
||||
|
||||
// Use this task to verify that the script understands the dotnet environment
|
||||
Task("DotnetInfo").Does(() => { new DotnetInfo(Context).Display(); });
|
|
@ -1,57 +0,0 @@
|
|||
// This file provides information on how to change the pre-defined tasks in
|
||||
// the NUnit Cake Recipe for a particular project, without changing the
|
||||
// recipe files themselves. Those files should not be changed unless you
|
||||
// are trying to make changes for all projects, which use the recipe.
|
||||
//
|
||||
// In addition, this file defines a few static methods intended to make it
|
||||
// easier to override task definitions for a project.
|
||||
//
|
||||
// Code given in the following examples should be added to your file after
|
||||
// the recipe itself has been loaded.
|
||||
//
|
||||
// SIMPLE EXAMPLES:
|
||||
//
|
||||
// Adding a new dependency after those already present
|
||||
// BuildTasks.SomeTask.IsDependentOn("SomeOtherTask");
|
||||
//
|
||||
// Adding a new action, which will be performed after the existing action.
|
||||
// BuildTasks.SomeTask.Does(() => {
|
||||
// // Code here to do something
|
||||
// });
|
||||
//
|
||||
// MORE COMPLEX EXAMPLES:
|
||||
//
|
||||
// Replacing the existing dependencies, criteria or actions is a bit harder.
|
||||
// You must first clear the relevant items and then re-add them in the desired
|
||||
// order along with any new items. The following static methods allow you to do
|
||||
// so a bit more simply than would otherwise be possible.
|
||||
|
||||
public static void ClearCriteria(CakeTaskBuilder builder) => ((CakeTask)builder.Task).Criterias.Clear();
|
||||
public static void ClearDependencies(CakeTaskBuilder builder) => ((CakeTask)builder.Task).Dependencies.Clear();
|
||||
public static void ClearActions(CakeTaskBuilder builder) => ((CakeTask)builder.Task).Actions.Clear();
|
||||
|
||||
// Redefining the action of the build task. Note that dependencies will still run, since we haven't changed them.
|
||||
// ClearActions(BuildTasks.Build);
|
||||
// BuildTasks.Build.Does(() => Information("I'm not building today!"));
|
||||
//
|
||||
// In some cases, you may wish to completely redefine what a task does. The following static method
|
||||
// supports a fluent syntax for doing just that
|
||||
|
||||
public static CakeTaskBuilder Redefine(CakeTaskBuilder builder)
|
||||
{
|
||||
ClearCriteria(builder);
|
||||
ClearDependencies(builder);
|
||||
ClearActions(builder);
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
// Redefine the build task completely. Note that in this case, dependencies are not run.
|
||||
// Redefine(BuildTasks.BuildTask)
|
||||
// .Does(() => {
|
||||
// Information("Not Building today!");
|
||||
// });
|
||||
//
|
||||
// Modify the Default task for a project to run "Test" rather than "Build".
|
||||
// Redefine(BuildTasks.DefaultTask)
|
||||
// .IsDependentOn("Test");
|
|
@ -1,115 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// CHECK FOR MISSING AND NON-STANDARD FILE HEADERS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class Headers
|
||||
{
|
||||
private static ICakeContext _context;
|
||||
|
||||
static Headers()
|
||||
{
|
||||
_context = BuildSettings.Context;
|
||||
}
|
||||
|
||||
public static void Check()
|
||||
{
|
||||
var NoHeader = new List<FilePath>();
|
||||
var NonStandard = new List<FilePath>();
|
||||
var Exempted = new List<FilePath>();
|
||||
int examined = 0;
|
||||
|
||||
var sourceFiles = _context.GetFiles(BuildSettings.SourceDirectory + "**/*.cs");
|
||||
var exemptFiles = BuildSettings.ExemptFiles;
|
||||
foreach (var file in sourceFiles)
|
||||
{
|
||||
var path = file.ToString();
|
||||
|
||||
// Ignore autogenerated files in an obj directory
|
||||
if (path.Contains("/obj/"))
|
||||
continue;
|
||||
|
||||
// Ignore designer files
|
||||
if (path.EndsWith(".Designer.cs"))
|
||||
continue;
|
||||
|
||||
// Ignore AssemblyInfo files
|
||||
if (SIO.Path.GetFileName(path) == "AssemblyInfo.cs")
|
||||
continue;
|
||||
|
||||
examined++;
|
||||
var header = GetHeader(file);
|
||||
if (exemptFiles.Contains(file.GetFilename().ToString()))
|
||||
Exempted.Add(file);
|
||||
else if (header.Count == 0)
|
||||
NoHeader.Add(file);
|
||||
else if (!header.SequenceEqual(BuildSettings.StandardHeader))
|
||||
NonStandard.Add(file);
|
||||
}
|
||||
|
||||
_context.Information("\nSTANDARD HEADER\n");
|
||||
foreach (string line in BuildSettings.StandardHeader)
|
||||
_context.Information(line);
|
||||
_context.Information("");
|
||||
|
||||
if (NoHeader.Count > 0)
|
||||
{
|
||||
_context.Information("\nFILES WITH NO HEADER\n");
|
||||
foreach (var file in NoHeader)
|
||||
_context.Information(RelPathTo(file));
|
||||
}
|
||||
|
||||
if (NonStandard.Count > 0)
|
||||
{
|
||||
_context.Information("\nFILES WITH A NON-STANDARD HEADER\n");
|
||||
foreach (var file in NonStandard)
|
||||
{
|
||||
_context.Information(RelPathTo(file));
|
||||
_context.Information("");
|
||||
foreach (string line in GetHeader(file))
|
||||
_context.Information(line);
|
||||
_context.Information("");
|
||||
}
|
||||
}
|
||||
|
||||
if (Exempted.Count > 0)
|
||||
{
|
||||
_context.Information("\nEXEMPTED FILES (NO CHECK MADE)\n");
|
||||
foreach (var file in Exempted)
|
||||
_context.Information(RelPathTo(file));
|
||||
}
|
||||
|
||||
_context.Information($"\nFiles Examined: {examined}");
|
||||
_context.Information($"Missing Headers: {NoHeader.Count}");
|
||||
_context.Information($"Non-Standard Headers: {NonStandard.Count}");
|
||||
_context.Information($"Exempted Files: {Exempted.Count}");
|
||||
|
||||
if (NoHeader.Count > 0 || NonStandard.Count > 0)
|
||||
throw new Exception("Missing or invalid file headers found");
|
||||
|
||||
if (examined == 0)
|
||||
_context.Warning("\nWARNING: There were no '*.cs' files in the source directory. Use of the 'CheckHeaders' task may not make sense for this project.");
|
||||
|
||||
List<string> GetHeader(FilePath file)
|
||||
{
|
||||
var header = new List<string>();
|
||||
var lines = SIO.File.ReadLines(file.ToString());
|
||||
|
||||
foreach (string line in lines)
|
||||
{
|
||||
if (!line.StartsWith("//"))
|
||||
break;
|
||||
|
||||
header.Add(line);
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
|
||||
string RelPathTo(FilePath file)
|
||||
{
|
||||
int CD_LENGTH = Environment.CurrentDirectory.Length + 1;
|
||||
|
||||
return file.ToString().Substring(CD_LENGTH);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +0,0 @@
|
|||
static public class HelpMessages
|
||||
{
|
||||
static public string Usage => $"""
|
||||
BUILD.CAKE
|
||||
|
||||
This script builds the {BuildSettings.Title} project. It makes use of
|
||||
NUnit.Cake.Recipe, which provides a number of built-in options and
|
||||
tasks. You may define additional options and tasks in build.cake or
|
||||
in additional cake files you load from build.cake. Recipe options may
|
||||
be specified in abbreviated form, down to the minimum length shown in
|
||||
square braces. Single character abbreviations use a single dash.
|
||||
|
||||
Usage: build [options]
|
||||
|
||||
Options:
|
||||
|
||||
--target=TARGET [-t]
|
||||
The TARGET task to be run, e.g. Test. Default is Build.
|
||||
|
||||
--configuration=CONFIG [-c]
|
||||
The name of the configuration to build. Default is Release.
|
||||
|
||||
--packageVersion [--pack]
|
||||
Specifies the full package version, including any pre-release
|
||||
suffix. If provided, this version is used directly in place of
|
||||
the default version calculated by the script.
|
||||
|
||||
--where=SELECTION [-w]
|
||||
Specifies a selction expression used to choose which packages
|
||||
to build and test, for use in debugging. Consists of one or
|
||||
more specifications, separated by '|' and '&'. Each specification
|
||||
is of the form "prop=value", where prop may be either id or type.
|
||||
Examples:
|
||||
--where type=nuget
|
||||
--where id=NUnit.Engine.Api
|
||||
--where "type=nuget|type=choco"
|
||||
|
||||
--level=LEVEL [--lev]
|
||||
Specifies the level of package testing, 1, 2 or 3. Defaults are
|
||||
1 = for normal CI tests run every time you build a package
|
||||
2 = for PRs and Dev builds uploaded to MyGet
|
||||
3 = prior to publishing a release
|
||||
|
||||
--trace=LEVEL [--tr]
|
||||
Specifies the default trace level for this run. Values are Off,
|
||||
Error, Warning, Info or Debug. Default is value of environment
|
||||
variable NUNIT_INTERNAL_TRACE_LEVEL if set. If not,
|
||||
tracing is turned Off.
|
||||
|
||||
--nobuild [--nob]
|
||||
Indicates that the Build task should not be run even if other
|
||||
tasks depend on it. The existing build is used instead.
|
||||
|
||||
--nopush [--nop]
|
||||
Indicates that no publishing or releasing should be done. If
|
||||
publish or release targets are run, a message is displayed.
|
||||
|
||||
--usage [--us]
|
||||
Displays this help message. No targets are run.
|
||||
|
||||
Selected Cake Options:
|
||||
|
||||
--version
|
||||
Displays the cake version in use.
|
||||
|
||||
--description
|
||||
Displays a list of the available tasks (targets).
|
||||
|
||||
--tree
|
||||
Displays the task dependency tree
|
||||
|
||||
--help
|
||||
Displays help information for cake itself.
|
||||
|
||||
NOTE: The above Cake options bypass execution of the script.
|
||||
""";
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
// Static class holding information about known extensions.
|
||||
public static class KnownExtensions
|
||||
{
|
||||
// Static Variables representing well-known Extensions with the latest tested version
|
||||
public static ExtensionSpecifier NUnitV2Driver = new ExtensionSpecifier(
|
||||
"NUnit.Extension.NUnitV2Driver", "nunit-extension-nunit-v2-driver", "3.9.0");
|
||||
public static ExtensionSpecifier NUnitProjectLoader = new ExtensionSpecifier(
|
||||
"NUnit.Extension.NUnitProjectLoader", "nunit-extension-nunit-project-loader", "3.7.1");
|
||||
}
|
||||
|
||||
// Representation of an extension, for use by PackageTests. Because our
|
||||
// extensions usually exist as both nuget and chocolatey packages, each
|
||||
// extension may have a nuget id, a chocolatey id or both. A default version
|
||||
// is used unless the user overrides it using SetVersion.
|
||||
public class ExtensionSpecifier
|
||||
{
|
||||
public ExtensionSpecifier(string nugetId, string chocoId, string version)
|
||||
{
|
||||
NuGetId = nugetId;
|
||||
ChocoId = chocoId;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public string NuGetId { get; }
|
||||
public string ChocoId { get; }
|
||||
public string Version { get; }
|
||||
|
||||
public PackageReference NuGetPackage => new PackageReference(NuGetId, Version);
|
||||
public PackageReference ChocoPackage => new PackageReference(ChocoId, Version);
|
||||
public PackageReference LatestChocolateyRelease => ChocoPackage.LatestRelease;
|
||||
|
||||
// Return an extension specifier using the same package ids as this
|
||||
// one but specifying a particular version to be used.
|
||||
public ExtensionSpecifier SetVersion(string version)
|
||||
{
|
||||
return new ExtensionSpecifier(NuGetId, ChocoId, version);
|
||||
}
|
||||
|
||||
// Install this extension for a package
|
||||
public void InstallExtension(PackageDefinition targetPackage)
|
||||
{
|
||||
PackageReference extensionPackage = targetPackage.PackageType == PackageType.Chocolatey
|
||||
? ChocoPackage
|
||||
: NuGetPackage;
|
||||
|
||||
extensionPackage.Install(targetPackage.ExtensionInstallDirectory);
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
public class NuGetPackage : PackageDefinition
|
||||
{
|
||||
public NuGetPackage(
|
||||
string id,
|
||||
string source,
|
||||
IPackageTestRunner testRunner = null,
|
||||
TestRunnerSource testRunnerSource = null,
|
||||
PackageCheck[] checks = null,
|
||||
PackageCheck[] symbols = null,
|
||||
IEnumerable<PackageTest> tests = null)
|
||||
: base(
|
||||
PackageType.NuGet,
|
||||
id,
|
||||
source,
|
||||
testRunner: testRunner,
|
||||
testRunnerSource: testRunnerSource,
|
||||
checks: checks,
|
||||
symbols: symbols,
|
||||
tests: tests)
|
||||
{
|
||||
if (!source.EndsWith(".nuspec"))
|
||||
throw new ArgumentException("Source must be a nuspec file", nameof(source));
|
||||
|
||||
if (symbols != null)
|
||||
{
|
||||
HasSymbols = true;
|
||||
SymbolChecks = symbols;
|
||||
}
|
||||
}
|
||||
|
||||
// The file name of this package, including extension
|
||||
public override string PackageFileName => $"{PackageId}.{PackageVersion}.nupkg";
|
||||
// The file name of any symbol package, including extension
|
||||
public override string SymbolPackageName => SIO.Path.ChangeExtension(PackageFileName, ".snupkg");
|
||||
// The directory into which this package is installed
|
||||
public override string PackageInstallDirectory => BuildSettings.NuGetTestDirectory;
|
||||
// The directory used to contain results of package tests for this package
|
||||
public override string PackageResultDirectory => BuildSettings.NuGetResultDirectory + PackageId + "/";
|
||||
// The directory into which extensions to the test runner are installed
|
||||
public override string ExtensionInstallDirectory => BuildSettings.PackageTestDirectory;
|
||||
|
||||
public override void BuildPackage()
|
||||
{
|
||||
var nugetPackSettings = new NuGetPackSettings()
|
||||
{
|
||||
Version = PackageVersion,
|
||||
BasePath = BuildSettings.OutputDirectory,
|
||||
OutputDirectory = BuildSettings.PackageDirectory,
|
||||
NoPackageAnalysis = true,
|
||||
Symbols = HasSymbols
|
||||
};
|
||||
|
||||
if (HasSymbols)
|
||||
nugetPackSettings.SymbolPackageFormat = "snupkg";
|
||||
|
||||
_context.NuGetPack(PackageSource, nugetPackSettings);
|
||||
}
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// SYNTAX FOR EXPRESSING CHECKS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class Check
|
||||
{
|
||||
public static void That(DirectoryPath testDirPath, IList<PackageCheck> checks)
|
||||
{
|
||||
if (checks == null)
|
||||
throw new ArgumentNullException(nameof(checks));
|
||||
|
||||
bool allOK = true;
|
||||
|
||||
foreach (var check in checks)
|
||||
allOK &= check.ApplyTo(testDirPath);
|
||||
|
||||
if (!allOK) throw new Exception("Verification failed!");
|
||||
}
|
||||
}
|
||||
|
||||
private static FileCheck HasFile(FilePath file) => HasFiles(new[] { file });
|
||||
private static FileCheck HasFiles(params FilePath[] files) => new FileCheck(files);
|
||||
|
||||
private static DirectoryCheck HasDirectory(string dir) => new DirectoryCheck(dir);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// PACKAGECHECK CLASS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public abstract class PackageCheck
|
||||
{
|
||||
protected ICakeContext _context;
|
||||
|
||||
public PackageCheck()
|
||||
{
|
||||
_context = BuildSettings.Context;
|
||||
}
|
||||
|
||||
public abstract bool ApplyTo(DirectoryPath testDirPath);
|
||||
|
||||
protected bool CheckDirectoryExists(DirectoryPath dirPath)
|
||||
{
|
||||
if (!_context.DirectoryExists(dirPath))
|
||||
{
|
||||
DisplayError($"Directory {dirPath} was not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool CheckFileExists(FilePath filePath)
|
||||
{
|
||||
if (!_context.FileExists(filePath))
|
||||
{
|
||||
DisplayError($"File {filePath} was not found.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected bool CheckFilesExist(IEnumerable<FilePath> filePaths)
|
||||
{
|
||||
bool isOK = true;
|
||||
|
||||
foreach (var filePath in filePaths)
|
||||
isOK &= CheckFileExists(filePath);
|
||||
|
||||
return isOK;
|
||||
}
|
||||
|
||||
protected bool DisplayError(string msg)
|
||||
{
|
||||
_context.Error(" ERROR: " + msg);
|
||||
|
||||
// The return value may be ignored or used as a shortcut
|
||||
// for an immediate return from ApplyTo as in
|
||||
// return DisplayError(...)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// FILECHECK CLASS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public class FileCheck : PackageCheck
|
||||
{
|
||||
FilePath[] _files;
|
||||
|
||||
public FileCheck(FilePath[] files)
|
||||
{
|
||||
_files = files;
|
||||
}
|
||||
|
||||
public override bool ApplyTo(DirectoryPath testDirPath)
|
||||
{
|
||||
return CheckFilesExist(_files.Select(file => testDirPath.CombineWithFilePath(file)));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// DIRECTORYCHECK CLASS
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public class DirectoryCheck : PackageCheck
|
||||
{
|
||||
private DirectoryPath _relDirPath;
|
||||
private List<FilePath> _files = new List<FilePath>();
|
||||
|
||||
public DirectoryCheck(DirectoryPath relDirPath)
|
||||
{
|
||||
_relDirPath = relDirPath;
|
||||
}
|
||||
|
||||
public DirectoryCheck WithFiles(params FilePath[] files)
|
||||
{
|
||||
_files.AddRange(files);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DirectoryCheck AndFiles(params FilePath[] files)
|
||||
{
|
||||
return WithFiles(files);
|
||||
}
|
||||
|
||||
public DirectoryCheck WithFile(FilePath file)
|
||||
{
|
||||
_files.Add(file);
|
||||
return this;
|
||||
}
|
||||
|
||||
public DirectoryCheck AndFile(FilePath file)
|
||||
{
|
||||
return AndFiles(file);
|
||||
}
|
||||
|
||||
public override bool ApplyTo(DirectoryPath testDirPath)
|
||||
{
|
||||
DirectoryPath absDirPath = testDirPath.Combine(_relDirPath);
|
||||
|
||||
if (!CheckDirectoryExists(absDirPath))
|
||||
return false;
|
||||
|
||||
return CheckFilesExist(_files.Select(file => absDirPath.CombineWithFilePath(file)));
|
||||
}
|
||||
}
|
|
@ -1,313 +0,0 @@
|
|||
public enum PackageType
|
||||
{
|
||||
NuGet,
|
||||
Chocolatey,
|
||||
Zip
|
||||
}
|
||||
|
||||
public abstract class PackageDefinition
|
||||
{
|
||||
protected ICakeContext _context;
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
/// <param name="packageType">A PackageType value specifying one of the four known package types</param>
|
||||
/// <param name="id">A string containing the package ID, used as the root of the PackageName</param>
|
||||
/// <param name="source">A string representing the source used to create the package, e.g. a nuspec file</param>
|
||||
/// <param name="testRunner">A TestRunner instance used to run package tests.</param>
|
||||
/// <param name="checks">An array of PackageChecks be made on the content of the package. Optional.</param>
|
||||
/// <param name="symbols">An array of PackageChecks to be made on the symbol package, if one is created. Optional. Only supported for nuget packages.</param>
|
||||
/// <param name="tests">An array of PackageTests to be run against the package. Optional.</param>
|
||||
protected PackageDefinition(
|
||||
PackageType packageType,
|
||||
string id,
|
||||
string source,
|
||||
IPackageTestRunner testRunner = null,
|
||||
TestRunnerSource testRunnerSource = null,
|
||||
string extraTestArguments = null,
|
||||
PackageCheck[] checks = null,
|
||||
PackageCheck[] symbols = null,
|
||||
IEnumerable<PackageTest> tests = null)
|
||||
{
|
||||
if (testRunner == null && testRunnerSource == null && tests != null)
|
||||
throw new System.InvalidOperationException($"Unable to create {packageType} package {id}: TestRunner or TestRunnerSource must be provided if there are tests.");
|
||||
if (testRunner != null && testRunnerSource != null)
|
||||
throw new System.InvalidOperationException($"Unable to create {packageType} package {id}: Either TestRunner or TestRunnerSource must be provided, but not both.");
|
||||
|
||||
_context = BuildSettings.Context;
|
||||
|
||||
PackageType = packageType;
|
||||
PackageId = id;
|
||||
PackageVersion = BuildSettings.PackageVersion;
|
||||
PackageSource = source;
|
||||
BasePath = BuildSettings.OutputDirectory;
|
||||
TestRunner = testRunner;
|
||||
TestRunnerSource = testRunnerSource;
|
||||
ExtraTestArguments = extraTestArguments;
|
||||
PackageChecks = checks;
|
||||
SymbolChecks = symbols;
|
||||
PackageTests = tests;
|
||||
}
|
||||
|
||||
public PackageType PackageType { get; }
|
||||
public string PackageId { get; }
|
||||
public string PackageVersion { get; protected set; }
|
||||
public string PackageSource { get; }
|
||||
public string BasePath { get; }
|
||||
public IPackageTestRunner TestRunner { get; }
|
||||
public TestRunnerSource TestRunnerSource { get; }
|
||||
public string ExtraTestArguments { get; }
|
||||
public PackageCheck[] PackageChecks { get; }
|
||||
public PackageCheck[] SymbolChecks { get; protected set; }
|
||||
public IEnumerable<PackageTest> PackageTests { get; }
|
||||
|
||||
public bool HasSymbols { get; protected set; } = false;
|
||||
public virtual string SymbolPackageName => throw new System.NotImplementedException($"Symbols are not available for {PackageType} packages.");
|
||||
|
||||
// The file name of this package, including extension
|
||||
public abstract string PackageFileName { get; }
|
||||
// The directory into which this package is installed
|
||||
public abstract string PackageInstallDirectory { get; }
|
||||
// The directory used to contain results of package tests for this package
|
||||
public abstract string PackageResultDirectory { get; }
|
||||
// The directory into which extensions to the test runner are installed
|
||||
public abstract string ExtensionInstallDirectory { get; }
|
||||
|
||||
public string PackageFilePath => BuildSettings.PackageDirectory + PackageFileName;
|
||||
public string PackageTestDirectory => $"{PackageInstallDirectory}{PackageId}.{PackageVersion}/";
|
||||
|
||||
public bool IsSelectedBy(string selectionExpression)
|
||||
{
|
||||
return IsSelectedByAny(selectionExpression.Split("|", StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
bool IsSelectedByAny(string[] terms)
|
||||
{
|
||||
foreach (var term in terms)
|
||||
if (IsSelectedByAll(term.Split("&", StringSplitOptions.RemoveEmptyEntries)))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsSelectedByAll(string[] factors)
|
||||
{
|
||||
foreach (string factor in factors)
|
||||
{
|
||||
int index = factor.IndexOf("=");
|
||||
if (index <= 0)
|
||||
throw new ArgumentException("Selection expression does not contain =", "where");
|
||||
string prop = factor.Substring(0, index).Trim();
|
||||
string val = factor.Substring(index+1).Trim();
|
||||
|
||||
switch(prop.ToUpper())
|
||||
{
|
||||
case "ID":
|
||||
return PackageId.ToLower() == val.ToLower();
|
||||
case "TYPE":
|
||||
return PackageType.ToString().ToLower() == val.ToLower();
|
||||
default:
|
||||
throw new Exception($"Not a valid selection property: {prop}");
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void BuildVerifyAndTest()
|
||||
{
|
||||
_context.EnsureDirectoryExists(BuildSettings.PackageDirectory);
|
||||
|
||||
Banner.Display($"Building {PackageFileName}");
|
||||
BuildPackage();
|
||||
|
||||
Banner.Display($"Installing {PackageFileName}");
|
||||
InstallPackage();
|
||||
|
||||
if (PackageChecks != null)
|
||||
{
|
||||
Banner.Display($"Verifying {PackageFileName}");
|
||||
VerifyPackage();
|
||||
}
|
||||
|
||||
if (SymbolChecks != null)
|
||||
{
|
||||
// TODO: Override this in NuGetPackage
|
||||
VerifySymbolPackage();
|
||||
}
|
||||
|
||||
if (PackageTests != null)
|
||||
{
|
||||
Banner.Display($"Testing {PackageFileName}");
|
||||
RunPackageTests();
|
||||
}
|
||||
}
|
||||
|
||||
protected void FetchBundledExtensions(PackageReference[] extensions)
|
||||
{
|
||||
foreach (var extension in extensions)
|
||||
if (!extension.IsInstalled(BuildSettings.ExtensionsDirectory))
|
||||
extension.Install(BuildSettings.ExtensionsDirectory);
|
||||
}
|
||||
|
||||
public abstract void BuildPackage();
|
||||
|
||||
// Base implementation is used for installing both NuGet and
|
||||
// Chocolatey packages. Other package types should override.
|
||||
public virtual void InstallPackage()
|
||||
{
|
||||
var installSettings = new NuGetInstallSettings
|
||||
{
|
||||
Source = new [] {
|
||||
// Package will be found here
|
||||
BuildSettings.PackageDirectory,
|
||||
// Dependencies may be in any of these
|
||||
"https://www.myget.org/F/nunit/api/v3/index.json",
|
||||
"https://api.nuget.org/v3/index.json" },
|
||||
Version = PackageVersion,
|
||||
OutputDirectory = PackageInstallDirectory,
|
||||
//ExcludeVersion = true,
|
||||
Prerelease = true,
|
||||
NoCache = true
|
||||
};
|
||||
|
||||
_context.NuGetInstall(PackageId, installSettings);
|
||||
}
|
||||
|
||||
public void VerifyPackage()
|
||||
{
|
||||
bool allOK = true;
|
||||
|
||||
if (PackageChecks != null)
|
||||
foreach (var check in PackageChecks)
|
||||
allOK &= check.ApplyTo(PackageTestDirectory);
|
||||
|
||||
if (allOK)
|
||||
Console.WriteLine("All checks passed!");
|
||||
else
|
||||
throw new Exception("Verification failed!");
|
||||
}
|
||||
|
||||
public void RunPackageTests()
|
||||
{
|
||||
_context.Information($"Package tests will run at level {BuildSettings.PackageTestLevel}");
|
||||
|
||||
var reporter = new ResultReporter(PackageFileName);
|
||||
|
||||
_context.CleanDirectory(PackageResultDirectory);
|
||||
|
||||
// Ensure we start out each package with no extensions installed.
|
||||
// If any package test installs an extension, it remains available
|
||||
// for subsequent tests of the same package only.
|
||||
//foreach (DirectoryPath dirPath in _context.GetDirectories(ExtensionInstallDirectory + "*"))
|
||||
//{
|
||||
// _context.DeleteDirectory(dirPath, new DeleteDirectorySettings() { Recursive = true });
|
||||
// _context.Information("Deleted directory " + dirPath.GetDirectoryName());
|
||||
//}
|
||||
|
||||
// Package was defined with either a TestRunnerSource or a single TestRunner. In either
|
||||
// case, these will all be package test runners and may or may not require installation.
|
||||
var defaultRunners = TestRunnerSource ?? new TestRunnerSource((TestRunner)TestRunner);
|
||||
|
||||
// Preinstall all runners requiring installation
|
||||
InstallRunners(defaultRunners.PackageTestRunners);
|
||||
|
||||
foreach (var packageTest in PackageTests)
|
||||
{
|
||||
if (packageTest.Level > BuildSettings.PackageTestLevel)
|
||||
continue;
|
||||
|
||||
InstallExtensions(packageTest.ExtensionsNeeded);
|
||||
InstallRunners(packageTest.TestRunners);
|
||||
|
||||
// Use runners from the test if provided, otherwise the default runners
|
||||
var runners = packageTest.TestRunners.Length > 0 ? packageTest.TestRunners : defaultRunners.PackageTestRunners;
|
||||
|
||||
foreach (var runner in runners)
|
||||
{
|
||||
Console.WriteLine(runner.Version);
|
||||
var testResultDir = $"{PackageResultDirectory}/{packageTest.Name}/";
|
||||
var resultFile = testResultDir + "TestResult.xml";
|
||||
|
||||
Banner.Display(packageTest.Description);
|
||||
|
||||
_context.CreateDirectory(testResultDir);
|
||||
string arguments = $"{packageTest.Arguments} {ExtraTestArguments} --work={testResultDir}";
|
||||
if (CommandLineOptions.TraceLevel.Value != "Off")
|
||||
arguments += $" --trace:{CommandLineOptions.TraceLevel.Value}";
|
||||
|
||||
int rc = runner.RunPackageTest(arguments);
|
||||
|
||||
try
|
||||
{
|
||||
var result = new ActualResult(resultFile);
|
||||
var report = new PackageTestReport(packageTest, result, runner);
|
||||
reporter.AddReport(report);
|
||||
|
||||
Console.WriteLine(report.Errors.Count == 0
|
||||
? "\nSUCCESS: Test Result matches expected result!"
|
||||
: "\nERROR: Test Result not as expected!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
reporter.AddReport(new PackageTestReport(packageTest, ex));
|
||||
|
||||
Console.WriteLine("\nERROR: No result found!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create report as a string
|
||||
var sw = new StringWriter();
|
||||
bool hadErrors = reporter.ReportResults(sw);
|
||||
string reportText = sw.ToString();
|
||||
|
||||
//Display it on the console
|
||||
Console.WriteLine(reportText);
|
||||
|
||||
// Save it to the result directory as well
|
||||
using (var reportFile = new StreamWriter($"{PackageResultDirectory}/PackageTestSummary.txt"))
|
||||
reportFile.Write(reportText);
|
||||
|
||||
if (hadErrors)
|
||||
throw new Exception("One or more package tests had errors!");
|
||||
}
|
||||
|
||||
private void InstallExtensions(ExtensionSpecifier[] extensionsNeeded)
|
||||
{
|
||||
foreach (ExtensionSpecifier extension in extensionsNeeded)
|
||||
extension.InstallExtension(this);
|
||||
}
|
||||
|
||||
private void InstallRunners(IEnumerable<IPackageTestRunner> runners)
|
||||
{
|
||||
// Install any runners needing installation
|
||||
foreach (var runner in runners)
|
||||
if (runner is InstallableTestRunner)
|
||||
InstallRunner((InstallableTestRunner)runner);
|
||||
}
|
||||
|
||||
private void InstallRunner(InstallableTestRunner runner)
|
||||
{
|
||||
runner.Install(PackageInstallDirectory);
|
||||
|
||||
// We are using nuget packages for the runner, so it won't normally recognize
|
||||
// chocolatey extensions. We add an extra addins file for that purpose.
|
||||
if (PackageType == PackageType.Chocolatey)
|
||||
{
|
||||
var filePath = runner.ExecutablePath.GetDirectory().CombineWithFilePath("choco.engine.addins").ToString();
|
||||
Console.WriteLine($"Creating {filePath}");
|
||||
|
||||
using (var writer = new StreamWriter(filePath))
|
||||
{
|
||||
writer.WriteLine("../../nunit-extension-*/tools/");
|
||||
writer.WriteLine("../../nunit-extension-*/tools/*/");
|
||||
writer.WriteLine("../../../nunit-extension-*/tools/");
|
||||
writer.WriteLine("../../../nunit-extension-*/tools/*/");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void VerifySymbolPackage() { } // Does nothing. Overridden for NuGet packages.
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
// Representation of a package reference, containing everything needed to install it
|
||||
public class PackageReference
|
||||
{
|
||||
private ICakeContext _context;
|
||||
|
||||
public string Id { get; }
|
||||
public string Version { get; }
|
||||
|
||||
public PackageReference(string id, string version)
|
||||
{
|
||||
_context = BuildSettings.Context;
|
||||
|
||||
Id = id;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
public PackageReference LatestDevBuild => GetLatestDevBuild();
|
||||
public PackageReference LatestRelease => GetLatestRelease();
|
||||
|
||||
private PackageReference GetLatestDevBuild()
|
||||
{
|
||||
var packageList = _context.NuGetList(Id, new NuGetListSettings()
|
||||
{
|
||||
Prerelease = true,
|
||||
Source = new [] { "https://www.myget.org/F/nunit/api/v3/index.json" }
|
||||
} );
|
||||
|
||||
foreach (var package in packageList)
|
||||
return new PackageReference(package.Name, package.Version);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private PackageReference GetLatestRelease()
|
||||
{
|
||||
var packageList = _context.NuGetList(Id, new NuGetListSettings()
|
||||
{
|
||||
Prerelease = true,
|
||||
Source = new [] {
|
||||
"https://www.nuget.org/api/v2/",
|
||||
"https://community.chocolatey.org/api/v2/" }
|
||||
} );
|
||||
|
||||
// TODO: There seems to be an error in NuGet or in Cake, causing the list to
|
||||
// contain ALL NuGet packages, so we check the Id in this loop.
|
||||
foreach (var package in packageList)
|
||||
if (package.Name == Id)
|
||||
return new PackageReference(Id, package.Version);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public bool IsInstalled(string installDirectory)
|
||||
{
|
||||
return _context.GetDirectories($"{installDirectory}{Id}.*").Count > 0;
|
||||
}
|
||||
|
||||
public void InstallExtension(PackageDefinition targetPackage)
|
||||
{
|
||||
Install(targetPackage.ExtensionInstallDirectory);
|
||||
}
|
||||
|
||||
public void Install(string installDirectory)
|
||||
{
|
||||
if (!IsInstalled(installDirectory))
|
||||
{
|
||||
Banner.Display($"Installing {Id} version {Version}");
|
||||
|
||||
var packageSources = new []
|
||||
{
|
||||
"https://www.myget.org/F/nunit/api/v3/index.json",
|
||||
"https://api.nuget.org/v3/index.json",
|
||||
"https://community.chocolatey.org/api/v2/"
|
||||
};
|
||||
|
||||
Console.WriteLine("Package Sources:");
|
||||
foreach(var source in packageSources)
|
||||
Console.WriteLine($" {source}");
|
||||
Console.WriteLine();
|
||||
|
||||
_context.NuGetInstall(Id,
|
||||
new NuGetInstallSettings()
|
||||
{
|
||||
OutputDirectory = installDirectory,
|
||||
Version = Version,
|
||||
Source = packageSources
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
// Representation of a single test to be run against a pre-built package.
|
||||
// Each test has a Level, with the following values defined...
|
||||
// 0 Do not run - used for temporarily disabling a test
|
||||
// 1 Run for all CI tests - that is every time we test packages
|
||||
// 2 Run only on PRs, dev builds and when publishing
|
||||
// 3 Run only when publishing
|
||||
public struct PackageTest
|
||||
{
|
||||
public int Level;
|
||||
public string Name;
|
||||
public string Description;
|
||||
public string Arguments;
|
||||
public ExpectedResult ExpectedResult;
|
||||
public IPackageTestRunner[] TestRunners;
|
||||
public ExtensionSpecifier[] ExtensionsNeeded;
|
||||
|
||||
public PackageTest(int level, string name, string description, string arguments, ExpectedResult expectedResult )
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
if (description == null)
|
||||
throw new ArgumentNullException(nameof(description));
|
||||
if (arguments == null)
|
||||
throw new ArgumentNullException(nameof(arguments));
|
||||
if (expectedResult == null)
|
||||
throw new ArgumentNullException(nameof(expectedResult));
|
||||
|
||||
Level = level;
|
||||
Name = name;
|
||||
Description = description;
|
||||
Arguments = arguments;
|
||||
ExpectedResult = expectedResult;
|
||||
ExtensionsNeeded = new ExtensionSpecifier[0];
|
||||
TestRunners = new IPackageTestRunner[0];
|
||||
}
|
||||
|
||||
public PackageTest(int level, string name, string description, string arguments, ExpectedResult expectedResult, params ExtensionSpecifier[] extensionsNeeded )
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
if (description == null)
|
||||
throw new ArgumentNullException(nameof(description));
|
||||
if (arguments == null)
|
||||
throw new ArgumentNullException(nameof(arguments));
|
||||
if (expectedResult == null)
|
||||
throw new ArgumentNullException(nameof(expectedResult));
|
||||
|
||||
Level = level;
|
||||
Name = name;
|
||||
Description = description;
|
||||
Arguments = arguments;
|
||||
ExpectedResult = expectedResult;
|
||||
ExtensionsNeeded = extensionsNeeded;
|
||||
TestRunners = new IPackageTestRunner[0];
|
||||
}
|
||||
|
||||
public PackageTest(int level, string name, string description, string arguments, ExpectedResult expectedResult, params IPackageTestRunner[] testRunners )
|
||||
{
|
||||
if (name == null)
|
||||
throw new ArgumentNullException(nameof(name));
|
||||
if (description == null)
|
||||
throw new ArgumentNullException(nameof(description));
|
||||
if (arguments == null)
|
||||
throw new ArgumentNullException(nameof(arguments));
|
||||
if (expectedResult == null)
|
||||
throw new ArgumentNullException(nameof(expectedResult));
|
||||
|
||||
Level = level;
|
||||
Name = name;
|
||||
Description = description;
|
||||
Arguments = arguments;
|
||||
ExpectedResult = expectedResult;
|
||||
TestRunners = testRunners;
|
||||
ExtensionsNeeded = new ExtensionSpecifier[0];
|
||||
}
|
||||
}
|
|
@ -1,244 +0,0 @@
|
|||
public static class PackageReleaseManager
|
||||
{
|
||||
private static ICakeContext _context;
|
||||
|
||||
static PackageReleaseManager()
|
||||
{
|
||||
_context = BuildSettings.Context;
|
||||
}
|
||||
|
||||
private static bool _hadErrors = false;
|
||||
|
||||
public static void Publish()
|
||||
{
|
||||
_hadErrors = false;
|
||||
|
||||
PublishToMyGet();
|
||||
PublishToNuGet();
|
||||
PublishToChocolatey();
|
||||
|
||||
if (_hadErrors)
|
||||
throw new Exception("One of the publishing steps failed.");
|
||||
}
|
||||
|
||||
public static void PublishToMyGet()
|
||||
{
|
||||
if (!BuildSettings.ShouldPublishToMyGet)
|
||||
_context.Information("Nothing to publish to MyGet from this run.");
|
||||
else if (CommandLineOptions.NoPush)
|
||||
_context.Information("NoPush option suppressing publication to MyGet");
|
||||
else
|
||||
foreach (var package in BuildSettings.Packages)
|
||||
{
|
||||
var packageName = $"{package.PackageId}.{BuildSettings.PackageVersion}.nupkg";
|
||||
var packagePath = BuildSettings.PackageDirectory + packageName;
|
||||
try
|
||||
{
|
||||
if (package.PackageType == PackageType.NuGet)
|
||||
PushNuGetPackage(packagePath, BuildSettings.MyGetApiKey, BuildSettings.MyGetPushUrl);
|
||||
else if (package.PackageType == PackageType.Chocolatey)
|
||||
PushChocolateyPackage(packagePath, BuildSettings.MyGetApiKey, BuildSettings.MyGetPushUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_context.Error(ex.Message);
|
||||
_hadErrors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PublishToNuGet()
|
||||
{
|
||||
if (!BuildSettings.ShouldPublishToNuGet)
|
||||
_context.Information("Nothing to publish to NuGet from this run.");
|
||||
else if (CommandLineOptions.NoPush)
|
||||
_context.Information("NoPush option suppressing publication to NuGet");
|
||||
else
|
||||
foreach (var package in BuildSettings.Packages)
|
||||
{
|
||||
var packageName = $"{package.PackageId}.{BuildSettings.PackageVersion}.nupkg";
|
||||
var packagePath = BuildSettings.PackageDirectory + packageName;
|
||||
try
|
||||
{
|
||||
if (package.PackageType == PackageType.NuGet)
|
||||
PushNuGetPackage(packagePath, BuildSettings.NuGetApiKey, BuildSettings.NuGetPushUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_context.Error(ex.Message);
|
||||
_hadErrors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void PublishToChocolatey()
|
||||
{
|
||||
if (!BuildSettings.ShouldPublishToChocolatey)
|
||||
_context.Information("Nothing to publish to Chocolatey from this run.");
|
||||
else if (CommandLineOptions.NoPush)
|
||||
_context.Information("NoPush option suppressing publication to Chocolatey");
|
||||
else
|
||||
foreach (var package in BuildSettings.Packages)
|
||||
{
|
||||
var packageName = $"{package.PackageId}.{BuildSettings.PackageVersion}.nupkg";
|
||||
var packagePath = BuildSettings.PackageDirectory + packageName;
|
||||
try
|
||||
{
|
||||
if (package.PackageType == PackageType.Chocolatey)
|
||||
PushChocolateyPackage(packagePath, BuildSettings.ChocolateyApiKey, BuildSettings.ChocolateyPushUrl);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_context.Error(ex.Message);
|
||||
_hadErrors = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void PushNuGetPackage(FilePath package, string apiKey, string url)
|
||||
{
|
||||
CheckPackageExists(package);
|
||||
_context.NuGetPush(package, new NuGetPushSettings() { ApiKey = apiKey, Source = url });
|
||||
}
|
||||
|
||||
private static void PushChocolateyPackage(FilePath package, string apiKey, string url)
|
||||
{
|
||||
CheckPackageExists(package);
|
||||
_context.ChocolateyPush(package, new ChocolateyPushSettings() { ApiKey = apiKey, Source = url });
|
||||
}
|
||||
|
||||
private static void CheckPackageExists(FilePath package)
|
||||
{
|
||||
if (!_context.FileExists(package))
|
||||
throw new InvalidOperationException(
|
||||
$"Package not found: {package.GetFilename()}.\nCode may have changed since package was last built.");
|
||||
}
|
||||
|
||||
private const string DRAFT_RELEASE_ERROR =
|
||||
"A direct call to CreateDraftRelease is permitted only:\r\n" +
|
||||
" * On a release branch (release-x.x.x)\r\n" +
|
||||
" * On the main branch tagged for a production release\r\n" +
|
||||
" * Using option --packageVersion to specify a release version";
|
||||
|
||||
public static void CreateDraftRelease()
|
||||
{
|
||||
string releaseVersion =
|
||||
CommandLineOptions.PackageVersion.Exists ? CommandLineOptions.PackageVersion.Value :
|
||||
BuildSettings.IsReleaseBranch ? BuildSettings.BuildVersion.BranchName.Substring(8) :
|
||||
BuildSettings.IsProductionRelease ? BuildSettings.PackageVersion : null;
|
||||
|
||||
if (releaseVersion != null)
|
||||
{
|
||||
if (CommandLineOptions.NoPush)
|
||||
_context.Information($"NoPush option skipping creation of draft release for version {releaseVersion}");
|
||||
else
|
||||
{
|
||||
string releaseName = $"{BuildSettings.Title} {releaseVersion}";
|
||||
_context.Information($"Creating draft release for {releaseName}");
|
||||
|
||||
try
|
||||
{
|
||||
_context.GitReleaseManagerCreate(BuildSettings.GitHubAccessToken, BuildSettings.GitHubOwner, BuildSettings.GitHubRepository, new GitReleaseManagerCreateSettings()
|
||||
{
|
||||
Name = releaseName,
|
||||
Milestone = releaseVersion
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
_context.Error($"Unable to create draft release for {releaseName}.");
|
||||
_context.Error($"Check that there is a {releaseVersion} milestone with at least one closed issue.");
|
||||
_context.Error("");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bool calledDirectly = CommandLineOptions.Target.Value == "CreateDraftRelease";
|
||||
if (calledDirectly)
|
||||
throw new InvalidOperationException(DRAFT_RELEASE_ERROR);
|
||||
else
|
||||
_context.Information("Skipping creation of draft release because this is not a release branch");
|
||||
}
|
||||
}
|
||||
|
||||
private const string UPDATE_RELEASE_ERROR =
|
||||
"A direct call to UpdateReleaseNotes is permitted only:\r\n" +
|
||||
" * On the main branch tagged for a production release\r\n" +
|
||||
" * Using option --packageVersion to specify a release version";
|
||||
|
||||
public static void UpdateReleaseNotes()
|
||||
{
|
||||
string releaseVersion =
|
||||
CommandLineOptions.PackageVersion.Exists ? CommandLineOptions.PackageVersion.Value :
|
||||
BuildSettings.IsProductionRelease ? BuildSettings.PackageVersion : null;
|
||||
|
||||
if (releaseVersion == null)
|
||||
throw new InvalidOperationException(UPDATE_RELEASE_ERROR);
|
||||
|
||||
if (CommandLineOptions.NoPush)
|
||||
_context.Information($"NoPush option skipping update of release notes for version {releaseVersion}");
|
||||
else
|
||||
{
|
||||
string releaseName = $"{BuildSettings.Title} {releaseVersion}";
|
||||
_context.Information($"Updating release notes for {releaseName}");
|
||||
|
||||
try
|
||||
{
|
||||
_context.GitReleaseManagerCreate(BuildSettings.GitHubAccessToken, BuildSettings.GitHubOwner, BuildSettings.GitHubRepository, new GitReleaseManagerCreateSettings()
|
||||
{
|
||||
Name = releaseName,
|
||||
Milestone = releaseVersion
|
||||
});
|
||||
}
|
||||
catch
|
||||
{
|
||||
_context.Error($"Unable to update release notes for {releaseName}.");
|
||||
_context.Error($"Check that there is a {releaseVersion} milestone with a matching release.");
|
||||
_context.Error("");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static void DownloadDraftRelease()
|
||||
{
|
||||
if (!BuildSettings.IsReleaseBranch)
|
||||
throw new Exception("DownloadDraftRelease requires a release branch!");
|
||||
|
||||
string milestone = BuildSettings.BranchName.Substring(8);
|
||||
|
||||
_context.GitReleaseManagerExport(BuildSettings.GitHubAccessToken, BuildSettings.GitHubOwner, BuildSettings.GitHubRepository, "DraftRelease.md",
|
||||
new GitReleaseManagerExportSettings() { TagName = milestone });
|
||||
}
|
||||
|
||||
public static void CreateProductionRelease()
|
||||
{
|
||||
if (!BuildSettings.IsProductionRelease)
|
||||
{
|
||||
_context.Information("Skipping CreateProductionRelease because this is not a production release");
|
||||
}
|
||||
else if (CommandLineOptions.NoPush)
|
||||
_context.Information($"NoPush option skipping creation of production release for version {BuildSettings.PackageVersion}");
|
||||
else
|
||||
{
|
||||
string token = BuildSettings.GitHubAccessToken;
|
||||
string owner = BuildSettings.GitHubOwner;
|
||||
string repository = BuildSettings.GitHubRepository;
|
||||
string tagName = BuildSettings.PackageVersion;
|
||||
string assets = string.Join<string>(',', BuildSettings.Packages.Select(p => p.PackageFilePath));
|
||||
|
||||
//IsRunningOnWindows()
|
||||
// ? $"\"{BuildSettings.NuGetPackage},{BuildSettings.ChocolateyPackage}\""
|
||||
// : $"\"{BuildSettings.NuGetPackage}\"";
|
||||
|
||||
_context.Information($"Publishing release {tagName} to GitHub");
|
||||
_context.Information($" Assets: {assets}");
|
||||
|
||||
_context.GitReleaseManagerAddAssets(token, owner, repository, tagName, assets);
|
||||
_context.GitReleaseManagerClose(token, owner, repository, tagName);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,51 +0,0 @@
|
|||
Setup((context) =>
|
||||
{
|
||||
var target = context.TargetTask.Name;
|
||||
var tasksToExecute = context.TasksToExecute.Select(t => t.Name);
|
||||
|
||||
// Ensure that BuildSettings have been initialized
|
||||
if (BuildSettings.Context == null)
|
||||
throw new Exception("BuildSettings have not been initialized. Call BuildSettings.Initialize() from your build.cake script.");
|
||||
|
||||
// Ensure Api Keys and tokens are available if needed for tasks to be executed
|
||||
|
||||
// MyGet Api Key
|
||||
bool needMyGetApiKey = tasksToExecute.Contains("PublishToMyGet") && BuildSettings.ShouldPublishToMyGet && !CommandLineOptions.NoPush;
|
||||
if (needMyGetApiKey && string.IsNullOrEmpty(BuildSettings.MyGetApiKey))
|
||||
DisplayErrorAndThrow("MyGet ApiKey is required but was not set.");
|
||||
|
||||
// NuGet Api Key
|
||||
bool needNuGetApiKey = tasksToExecute.Contains("PublishToNuGet") && BuildSettings.ShouldPublishToNuGet && !CommandLineOptions.NoPush;
|
||||
if (needNuGetApiKey && string.IsNullOrEmpty(BuildSettings.NuGetApiKey))
|
||||
DisplayErrorAndThrow("NuGet ApiKey is required but was not set.");
|
||||
|
||||
// Chocolatey Api Key
|
||||
bool needChocolateyApiKey = tasksToExecute.Contains("PublishToChocolatey") && BuildSettings.ShouldPublishToChocolatey && !CommandLineOptions.NoPush;
|
||||
if (needChocolateyApiKey && string.IsNullOrEmpty(BuildSettings.ChocolateyApiKey))
|
||||
DisplayErrorAndThrow("Chocolatey ApiKey is required but was not set.");
|
||||
|
||||
// GitHub Access Token, Owner and Repository
|
||||
if (!CommandLineOptions.NoPush)
|
||||
if (tasksToExecute.Contains("CreateDraftRelease") && BuildSettings.IsReleaseBranch ||
|
||||
tasksToExecute.Contains("CreateProductionRelease") && BuildSettings.IsProductionRelease)
|
||||
{
|
||||
if (string.IsNullOrEmpty(BuildSettings.GitHubAccessToken))
|
||||
DisplayErrorAndThrow("GitHub Access Token is required but was not set.");
|
||||
if (string.IsNullOrEmpty(BuildSettings.GitHubOwner))
|
||||
DisplayErrorAndThrow("GitHub Owner is required but was not set.");
|
||||
if (string.IsNullOrEmpty(BuildSettings.GitHubRepository))
|
||||
DisplayErrorAndThrow("GitHub Repository is required but was not set.");
|
||||
}
|
||||
|
||||
// Add settings to BuildSettings
|
||||
BuildSettings.Target = target;
|
||||
BuildSettings.TasksToExecute = tasksToExecute;
|
||||
|
||||
void DisplayErrorAndThrow(string message)
|
||||
{
|
||||
message += $"\r\n Tasks: {string.Join(", ", tasksToExecute)}";
|
||||
|
||||
context.Error(message);
|
||||
throw new Exception(message);
|
||||
}
|
||||
});
|
|
@ -1,48 +0,0 @@
|
|||
// All tasks incorporated in the recipe are defined using CakeTaskBuilders.
|
||||
// The actual specification of criteria, dependencies and actions for each
|
||||
// task is done separately in task-definitions.cake.
|
||||
//
|
||||
// This approach provides a level of indirection, permitting the user to
|
||||
// modify or completely redefine what a task does in their build.cake file,
|
||||
// without changing the definitions in the recipe.
|
||||
|
||||
public static class BuildTasks
|
||||
{
|
||||
// General
|
||||
public static CakeTaskBuilder DumpSettingsTask { get; set; }
|
||||
public static CakeTaskBuilder DefaultTask {get; set; }
|
||||
|
||||
// Building
|
||||
public static CakeTaskBuilder BuildTask { get; set; }
|
||||
public static CakeTaskBuilder CheckHeadersTask { get; set; }
|
||||
public static CakeTaskBuilder CleanTask { get; set; }
|
||||
public static CakeTaskBuilder CleanAllTask { get; set; }
|
||||
public static CakeTaskBuilder RestoreTask { get; set; }
|
||||
|
||||
// Unit Testing
|
||||
public static CakeTaskBuilder UnitTestTask { get; set; }
|
||||
|
||||
// Packaging
|
||||
public static CakeTaskBuilder PackageTask { get; set; }
|
||||
public static CakeTaskBuilder BuildTestAndPackageTask { get; set; }
|
||||
//public static CakeTaskBuilder PackageBuildTask { get; set; }
|
||||
//public static CakeTaskBuilder PackageInstallTask { get; set; }
|
||||
//public static CakeTaskBuilder PackageVerifyTask { get; set; }
|
||||
//public static CakeTaskBuilder PackageTestTask { get; set; }
|
||||
|
||||
// Publishing
|
||||
public static CakeTaskBuilder PublishTask { get; set; }
|
||||
public static CakeTaskBuilder PublishToMyGetTask { get; set; }
|
||||
public static CakeTaskBuilder PublishToNuGetTask { get; set; }
|
||||
public static CakeTaskBuilder PublishToChocolateyTask { get; set; }
|
||||
|
||||
// Releasing
|
||||
public static CakeTaskBuilder CreateDraftReleaseTask { get; set; }
|
||||
//public static CakeTaskBuilder DownloadDraftReleaseTask { get; set; }
|
||||
//public static CakeTaskBuilder UpdateReleaseNotesTask { get; set; }
|
||||
public static CakeTaskBuilder CreateProductionReleaseTask { get; set; }
|
||||
|
||||
// Continuous Integration
|
||||
public static CakeTaskBuilder ContinuousIntegrationTask { get; set; }
|
||||
public static CakeTaskBuilder AppveyorTask { get; set; }
|
||||
}
|
|
@ -1,134 +0,0 @@
|
|||
// This file defines what each of the tasks in the recipe actually does.
|
||||
// You should not change these definitions unless you intend to change
|
||||
// the behavior of a task for all projects that use the recipe.
|
||||
//
|
||||
// To make a change for a single project, you should add code to your build.cake
|
||||
// or another project-specific cake file. See extending.cake for examples.
|
||||
|
||||
BuildTasks.DefaultTask = Task("Default")
|
||||
.Description("Default task if none specified by user")
|
||||
.IsDependentOn("Build");
|
||||
|
||||
BuildTasks.DumpSettingsTask = Task("DumpSettings")
|
||||
.Description("Display BuildSettings properties")
|
||||
.Does(() => BuildSettings.DumpSettings());
|
||||
|
||||
BuildTasks.CheckHeadersTask = Task("CheckHeaders")
|
||||
.Description("Check source files for valid copyright headers")
|
||||
.WithCriteria(() => !CommandLineOptions.NoBuild)
|
||||
.WithCriteria(() => !BuildSettings.SuppressHeaderCheck)
|
||||
.Does(() => Headers.Check());
|
||||
|
||||
BuildTasks.CleanTask = Task("Clean")
|
||||
.Description("Clean output and package directories")
|
||||
.WithCriteria(() => !CommandLineOptions.NoBuild)
|
||||
.Does(() =>
|
||||
{
|
||||
foreach (var binDir in GetDirectories($"**/bin/{BuildSettings.Configuration}/"))
|
||||
CleanDirectory(binDir);
|
||||
|
||||
CleanDirectory(BuildSettings.PackageDirectory);
|
||||
CleanDirectory(BuildSettings.ImageDirectory);
|
||||
CleanDirectory(BuildSettings.ExtensionsDirectory);
|
||||
|
||||
DeleteFiles(BuildSettings.ProjectDirectory + "*.log");
|
||||
});
|
||||
|
||||
BuildTasks.CleanAllTask = Task("CleanAll")
|
||||
.Description("Clean everything!")
|
||||
.Does(() =>
|
||||
{
|
||||
foreach (var binDir in GetDirectories("**/bin/"))
|
||||
CleanDirectory(binDir);
|
||||
|
||||
CleanDirectory(BuildSettings.PackageDirectory);
|
||||
CleanDirectory(BuildSettings.ImageDirectory);
|
||||
CleanDirectory(BuildSettings.ExtensionsDirectory);
|
||||
|
||||
DeleteFiles(BuildSettings.ProjectDirectory + "*.log");
|
||||
|
||||
foreach (var dir in GetDirectories("src/**/obj/"))
|
||||
DeleteDirectory(dir, new DeleteDirectorySettings() { Recursive = true });
|
||||
});
|
||||
|
||||
BuildTasks.RestoreTask = Task("Restore")
|
||||
.Description("Restore referenced packages")
|
||||
.WithCriteria(() => BuildSettings.SolutionFile != null)
|
||||
.WithCriteria(() => !CommandLineOptions.NoBuild)
|
||||
.Does(() => {
|
||||
NuGetRestore(BuildSettings.SolutionFile, new NuGetRestoreSettings() {
|
||||
Source = new string[] {
|
||||
"https://www.nuget.org/api/v2",
|
||||
"https://www.myget.org/F/nunit/api/v2" }
|
||||
});
|
||||
});
|
||||
|
||||
BuildTasks.BuildTask = Task("Build")
|
||||
.WithCriteria(() => BuildSettings.SolutionFile != null)
|
||||
.WithCriteria(() => !CommandLineOptions.NoBuild)
|
||||
.IsDependentOn("Clean")
|
||||
.IsDependentOn("Restore")
|
||||
.IsDependentOn("CheckHeaders")
|
||||
.Description("Build the solution")
|
||||
.Does(() => {
|
||||
MSBuild(BuildSettings.SolutionFile, BuildSettings.MSBuildSettings.WithProperty("Version", BuildSettings.PackageVersion));
|
||||
});
|
||||
|
||||
BuildTasks.UnitTestTask = Task("Test")
|
||||
.Description("Run unit tests")
|
||||
.IsDependentOn("Build")
|
||||
.Does(() => UnitTesting.RunAllTests());
|
||||
|
||||
BuildTasks.PackageTask = Task("Package")
|
||||
.IsDependentOn("Build")
|
||||
.Description("Build, Install, Verify and Test all packages")
|
||||
.Does(() => {
|
||||
var selector = CommandLineOptions.PackageSelector;
|
||||
foreach(var package in BuildSettings.Packages)
|
||||
if (!selector.Exists || package.IsSelectedBy(selector.Value))
|
||||
package.BuildVerifyAndTest();
|
||||
});
|
||||
|
||||
BuildTasks.BuildTestAndPackageTask = Task("BuildTestAndPackage")
|
||||
.Description("Do Build, Test and Package all in one run")
|
||||
.IsDependentOn("Build")
|
||||
.IsDependentOn("Test")
|
||||
.IsDependentOn("Package");
|
||||
|
||||
BuildTasks.PublishTask = Task("Publish")
|
||||
.Description("Publish all packages for current branch")
|
||||
.IsDependentOn("Package")
|
||||
.Does(() => PackageReleaseManager.Publish());
|
||||
|
||||
BuildTasks.PublishToMyGetTask = Task("PublishToMyGet")
|
||||
.Description("Publish packages to MyGet")
|
||||
.Does(() => PackageReleaseManager.PublishToMyGet() );
|
||||
|
||||
BuildTasks.PublishToNuGetTask = Task("PublishToNuGet")
|
||||
.Description("Publish packages to NuGet")
|
||||
.Does(() => PackageReleaseManager.PublishToNuGet() );
|
||||
|
||||
BuildTasks.PublishToChocolateyTask = Task("PublishToChocolatey")
|
||||
.Description("Publish packages to Chocolatey")
|
||||
.Does(() => PackageReleaseManager.PublishToChocolatey() );
|
||||
|
||||
BuildTasks.CreateDraftReleaseTask = Task("CreateDraftRelease")
|
||||
.Description("Create a draft release on GitHub")
|
||||
.Does(() => PackageReleaseManager.CreateDraftRelease() );
|
||||
|
||||
BuildTasks.CreateProductionReleaseTask = Task("CreateProductionRelease")
|
||||
.Description("Create a production GitHub Release")
|
||||
.Does(() => PackageReleaseManager.CreateProductionRelease() );
|
||||
|
||||
BuildTasks.ContinuousIntegrationTask = Task("ContinuousIntegration")
|
||||
.Description("Perform continuous integration run")
|
||||
.IsDependentOn("Build")
|
||||
.IsDependentOn("Test")
|
||||
.IsDependentOn("Package")
|
||||
.IsDependentOn("Publish")
|
||||
.IsDependentOn("CreateDraftRelease")
|
||||
.IsDependentOn("CreateProductionRelease");
|
||||
|
||||
BuildTasks.AppveyorTask = Task("Appveyor")
|
||||
.Description("Target for running on AppVeyor")
|
||||
.IsDependentOn("ContinuousIntegration");
|
|
@ -1,171 +0,0 @@
|
|||
public class PackageTestReport
|
||||
{
|
||||
public PackageTest Test;
|
||||
public ActualResult Result;
|
||||
public ITestRunner Runner;
|
||||
public List<string> Errors;
|
||||
public List<string> Warnings;
|
||||
|
||||
public PackageTestReport(PackageTest test, ActualResult actualResult, ITestRunner runner = null)
|
||||
{
|
||||
Test = test;
|
||||
Result = actualResult;
|
||||
Runner = runner;
|
||||
Errors = new List<string>();
|
||||
Warnings = new List<string>();
|
||||
|
||||
var expectedResult = test.ExpectedResult;
|
||||
|
||||
ReportMissingFiles();
|
||||
|
||||
if (actualResult.OverallResult == null)
|
||||
Errors.Add(" The test-run element has no result attribute.");
|
||||
else if (expectedResult.OverallResult != actualResult.OverallResult)
|
||||
Errors.Add($" Expected: Overall Result = {expectedResult.OverallResult} But was: {actualResult.OverallResult}");
|
||||
CheckCounter("Test Count", expectedResult.Total, actualResult.Total);
|
||||
CheckCounter("Passed", expectedResult.Passed, actualResult.Passed);
|
||||
CheckCounter("Failed", expectedResult.Failed, actualResult.Failed);
|
||||
CheckCounter("Warnings", expectedResult.Warnings, actualResult.Warnings);
|
||||
CheckCounter("Inconclusive", expectedResult.Inconclusive, actualResult.Inconclusive);
|
||||
CheckCounter("Skipped", expectedResult.Skipped, actualResult.Skipped);
|
||||
|
||||
var expectedAssemblies = expectedResult.Assemblies;
|
||||
var actualAssemblies = actualResult.Assemblies;
|
||||
|
||||
for (int i = 0; i < expectedAssemblies.Length && i < actualAssemblies.Length; i++)
|
||||
{
|
||||
var expected = expectedAssemblies[i];
|
||||
var actual = actualAssemblies[i];
|
||||
|
||||
if (expected.AssemblyName != actual.AssemblyName)
|
||||
Errors.Add($" Expected: {expected.AssemblyName} But was: { actual.AssemblyName}");
|
||||
else if (runner == null || runner.PackageId == "NUnit.ConsoleRunner.NetCore")
|
||||
{
|
||||
if (actual.Runtime == null)
|
||||
Warnings.Add($"Unable to determine actual runtime used for {expected.AssemblyName}");
|
||||
else if (expected.Runtime != actual.Runtime)
|
||||
Errors.Add($" Assembly {actual.AssemblyName} Expected: {expected.Runtime} But was: {actual.Runtime}");
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = actualAssemblies.Length; i < expectedAssemblies.Length; i++)
|
||||
Errors.Add($" Assembly {expectedAssemblies[i].AssemblyName} was not found");
|
||||
|
||||
for (int i = expectedAssemblies.Length; i < actualAssemblies.Length; i++)
|
||||
Errors.Add($" Found unexpected assembly {actualAssemblies[i].AssemblyName}");
|
||||
}
|
||||
|
||||
public PackageTestReport(PackageTest test, Exception ex, ITestRunner runner = null)
|
||||
{
|
||||
Test = test;
|
||||
Result = null;
|
||||
Errors = new List<string>();
|
||||
Errors.Add($" {ex.Message}");
|
||||
Runner = runner;
|
||||
}
|
||||
|
||||
public void Display(int index, TextWriter writer)
|
||||
{
|
||||
writer.WriteLine();
|
||||
writer.WriteLine($"{index}. {Test.Description}");
|
||||
if (Runner != null)
|
||||
writer.WriteLine($" Runner: {Runner.PackageId} {Runner.Version}");
|
||||
writer.WriteLine($" Args: {Test.Arguments}");
|
||||
writer.WriteLine();
|
||||
|
||||
foreach (var error in Errors)
|
||||
writer.WriteLine(error);
|
||||
|
||||
if (Errors.Count == 0)
|
||||
{
|
||||
writer.WriteLine(" SUCCESS: Test Result matches expected result!");
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteLine();
|
||||
writer.WriteLine(" ERROR: Test Result not as expected!");
|
||||
}
|
||||
|
||||
foreach (var warning in Warnings)
|
||||
writer.WriteLine(" WARNING: " + warning);
|
||||
}
|
||||
|
||||
// File level errors, like missing or mal-formatted files, need to be highlighted
|
||||
// because otherwise it's hard to detect the cause of the problem without debugging.
|
||||
// This method finds and reports that type of error.
|
||||
private void ReportMissingFiles()
|
||||
{
|
||||
// Start with all the top-level test suites. Note that files that
|
||||
// cannot be found show up as Unknown as do unsupported file types.
|
||||
var suites = Result.Xml.SelectNodes(
|
||||
"//test-suite[@type='Unknown'] | //test-suite[@type='Project'] | //test-suite[@type='Assembly']");
|
||||
|
||||
// If there is no top-level suite, it generally means the file format could not be interpreted
|
||||
if (suites.Count == 0)
|
||||
Errors.Add(" No top-level suites! Possible empty command-line or misformed project.");
|
||||
|
||||
foreach (XmlNode suite in suites)
|
||||
{
|
||||
// Narrow down to the specific failures we want
|
||||
string runState = GetAttribute(suite, "runstate");
|
||||
string suiteResult = GetAttribute(suite, "result");
|
||||
string label = GetAttribute(suite, "label");
|
||||
string site = suite.Attributes["site"]?.Value ?? "Test";
|
||||
if (runState == "NotRunnable" || suiteResult == "Failed" && site == "Test" && (label == "Invalid" || label == "Error"))
|
||||
{
|
||||
string message = suite.SelectSingleNode("reason/message")?.InnerText;
|
||||
Errors.Add($" {message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void CheckCounter(string label, int expected, int actual)
|
||||
{
|
||||
// If expected value of counter is negative, it means no check is needed
|
||||
if (expected >= 0 && expected != actual)
|
||||
Errors.Add($" Expected: {label} = {expected} But was: {actual}");
|
||||
}
|
||||
|
||||
private string GetAttribute(XmlNode node, string name)
|
||||
{
|
||||
return node.Attributes[name]?.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public class ResultReporter
|
||||
{
|
||||
private string _packageName;
|
||||
private List<PackageTestReport> _reports = new List<PackageTestReport>();
|
||||
|
||||
public ResultReporter(string packageName)
|
||||
{
|
||||
_packageName = packageName;
|
||||
}
|
||||
|
||||
public void AddReport(PackageTestReport report)
|
||||
{
|
||||
_reports.Add(report);
|
||||
}
|
||||
|
||||
public bool ReportResults(TextWriter writer)
|
||||
{
|
||||
writer.WriteLine("\n=================================================="); ;
|
||||
writer.WriteLine($"Test Results for {_packageName}");
|
||||
writer.WriteLine("=================================================="); ;
|
||||
|
||||
writer.WriteLine("\nTest Environment");
|
||||
writer.WriteLine($" OS Version: {Environment.OSVersion.VersionString}");
|
||||
writer.WriteLine($" CLR Version: {Environment.Version}\n");
|
||||
|
||||
int index = 0;
|
||||
bool hasErrors = false;
|
||||
|
||||
foreach (var report in _reports)
|
||||
{
|
||||
hasErrors |= report.Errors.Count > 0;
|
||||
report.Display(++index, writer);
|
||||
}
|
||||
|
||||
return hasErrors;
|
||||
}
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
// This file contains classes used to interpret the result XML that is
|
||||
// produced by test runs of the GUI.
|
||||
|
||||
using System.Xml;
|
||||
|
||||
public abstract class ResultSummary
|
||||
{
|
||||
public string OverallResult { get; set; }
|
||||
public int Total { get; set; }
|
||||
public int Passed { get; set; }
|
||||
public int Failed { get; set; }
|
||||
public int Warnings { get; set; }
|
||||
public int Inconclusive { get; set; }
|
||||
public int Skipped { get; set; }
|
||||
}
|
||||
|
||||
public class ExpectedResult : ResultSummary
|
||||
{
|
||||
public ExpectedResult(string overallResult)
|
||||
{
|
||||
if (string.IsNullOrEmpty(overallResult))
|
||||
throw new ArgumentNullException(nameof(overallResult));
|
||||
|
||||
OverallResult = overallResult;
|
||||
|
||||
// Initialize counters to -1, indicating no expected value.
|
||||
// Set properties of those items to be checked.
|
||||
Total = Passed = Failed = Warnings = Inconclusive = Skipped = -1;
|
||||
}
|
||||
|
||||
public ExpectedAssemblyResult[] Assemblies { get; set; } = new ExpectedAssemblyResult[0];
|
||||
}
|
||||
|
||||
public class ExpectedAssemblyResult
|
||||
{
|
||||
public ExpectedAssemblyResult(string name, string expectedRuntime = null)
|
||||
{
|
||||
AssemblyName = name;
|
||||
Runtime = expectedRuntime;
|
||||
}
|
||||
|
||||
public string AssemblyName { get; }
|
||||
public string Runtime { get; }
|
||||
}
|
||||
|
||||
public class ActualResult : ResultSummary
|
||||
{
|
||||
public ActualResult(string resultFile)
|
||||
{
|
||||
var doc = new XmlDocument();
|
||||
doc.Load(resultFile);
|
||||
|
||||
Xml = doc.DocumentElement;
|
||||
if (Xml.Name != "test-run")
|
||||
throw new Exception("The test-run element was not found.");
|
||||
|
||||
OverallResult = GetAttribute(Xml, "result");
|
||||
Total = IntAttribute(Xml, "total");
|
||||
Passed = IntAttribute(Xml, "passed");
|
||||
Failed = IntAttribute(Xml, "failed");
|
||||
Warnings = IntAttribute(Xml, "warnings");
|
||||
Inconclusive = IntAttribute(Xml, "inconclusive");
|
||||
Skipped = IntAttribute(Xml, "skipped");
|
||||
|
||||
var assemblies = new List<ActualAssemblyResult>();
|
||||
//var engineVersion = new Version(GetAttribute(Xml, "engine-version"));
|
||||
|
||||
foreach (XmlNode node in Xml.SelectNodes("//test-suite[@type='Assembly']"))
|
||||
assemblies.Add(new ActualAssemblyResult(node));
|
||||
|
||||
//foreach (XmlNode node in Xml.SelectNodes("//test-suite[@type='Assembly']"))
|
||||
// assemblies.Add(new ActualAssemblyResult(node, engineVersion));
|
||||
|
||||
Assemblies = assemblies.ToArray();
|
||||
}
|
||||
|
||||
public XmlNode Xml { get; }
|
||||
|
||||
public ActualAssemblyResult[] Assemblies { get; }
|
||||
|
||||
private string GetAttribute(XmlNode node, string name)
|
||||
{
|
||||
return node.Attributes[name]?.Value;
|
||||
}
|
||||
|
||||
private int IntAttribute(XmlNode node, string name)
|
||||
{
|
||||
string s = GetAttribute(node, name);
|
||||
// TODO: We should replace 0 with -1, representing a missing counter
|
||||
// attribute, after issue #707 is fixed.
|
||||
return s == null ? 0 : int.Parse(s);
|
||||
}
|
||||
}
|
||||
|
||||
public class ActualAssemblyResult
|
||||
{
|
||||
public ActualAssemblyResult(XmlNode xml)
|
||||
{
|
||||
AssemblyName = xml.Attributes["name"]?.Value;
|
||||
|
||||
//var env = xml.SelectSingleNode("environment");
|
||||
var settings = xml.SelectSingleNode("settings");
|
||||
|
||||
// If TargetRuntimeFramework setting is not present, the Runner will probably crash
|
||||
var runtimeSetting = settings?.SelectSingleNode("setting[@name='TargetRuntimeFramework']");
|
||||
Runtime = runtimeSetting?.Attributes["value"]?.Value;
|
||||
|
||||
var agentSetting = settings?.SelectSingleNode("setting[@name='SelectedAgentName']");
|
||||
AgentName = agentSetting?.Attributes["value"]?.Value;
|
||||
}
|
||||
|
||||
public string AssemblyName { get; }
|
||||
public string AgentName { get; }
|
||||
|
||||
public string Runtime { get; }
|
||||
}
|
||||
|
||||
#if false
|
||||
public class ActualAssemblyResult
|
||||
{
|
||||
public ActualAssemblyResult(XmlNode xml, Version engineVersion)
|
||||
{
|
||||
Name = xml.Attributes["name"]?.Value;
|
||||
|
||||
var env = xml.SelectSingleNode("environment");
|
||||
var settings = xml.SelectSingleNode("settings");
|
||||
|
||||
// If TargetRuntimeFramework setting is not present, the GUI will have crashed anyway
|
||||
var runtimeSetting = settings.SelectSingleNode("setting[@name='ImageTargetFrameworkName']");
|
||||
TargetRuntime = runtimeSetting?.Attributes["value"]?.Value;
|
||||
|
||||
// Engine 3.10 and earlier doesn't provide enough info
|
||||
if (engineVersion >= new Version(3,11,0,0))
|
||||
Runtime = DeduceActualRuntime(xml);
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
public string Runtime { get; }
|
||||
|
||||
public string TargetRuntime { get; }
|
||||
|
||||
// Code to determine the runtime actually used is adhoc
|
||||
// and doesn't work for all assemblies because the needed
|
||||
// information may not be present in the result file.
|
||||
// TODO: Modify result file schema so this can be cleaner
|
||||
private static string DeduceActualRuntime(XmlNode assembly)
|
||||
{
|
||||
var env = assembly.SelectSingleNode("environment");
|
||||
// The TargetRuntimeFramework setting is only present
|
||||
// under the 3.12 and later versions of the engine.
|
||||
var runtimeSetting = assembly.SelectSingleNode("settings/setting[@name='TargetRuntimeFramework']");
|
||||
var targetRuntime = runtimeSetting?.Attributes["value"]?.Value;
|
||||
if (targetRuntime != null)
|
||||
return targetRuntime;
|
||||
|
||||
var clrVersion = env.Attributes["clr-version"]?.Value;
|
||||
if (clrVersion == null)
|
||||
return null;
|
||||
|
||||
if (clrVersion.StartsWith("2.0"))
|
||||
return "net-2.0";
|
||||
if (clrVersion.StartsWith("4.0"))
|
||||
return "net-4";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
#endif
|
|
@ -1,224 +0,0 @@
|
|||
/////////////////////////////////////////////////////////////////////////////
|
||||
// TEST RUNNER INTERFACES
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <Summary>
|
||||
/// Common interface for all test runners
|
||||
/// </Summary>
|
||||
public interface ITestRunner
|
||||
{
|
||||
string PackageId { get; }
|
||||
string Version { get; }
|
||||
}
|
||||
|
||||
/// <Summary>
|
||||
/// A runner capable of running unit tests
|
||||
/// </Summary>
|
||||
public interface IUnitTestRunner : ITestRunner
|
||||
{
|
||||
int RunUnitTest(FilePath testPath);
|
||||
}
|
||||
|
||||
/// <Summary>
|
||||
/// A runner capable of running package tests
|
||||
/// </Summary>
|
||||
public interface IPackageTestRunner : ITestRunner
|
||||
{
|
||||
int RunPackageTest(string arguments);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// ABSTRACT TEST RUNNER
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// The TestRunner class is the abstract base for all TestRunners used to run unit-
|
||||
/// or package-tests. A TestRunner knows how to run a test assembly and provide a result.
|
||||
/// All base functionality is implemented in this class. Derived classes make that
|
||||
/// functionality available selectively by implementing specific interfaces.
|
||||
/// </summary>
|
||||
public abstract class TestRunner : ITestRunner
|
||||
{
|
||||
protected ICakeContext Context => BuildSettings.Context;
|
||||
|
||||
public string PackageId { get; protected set; }
|
||||
public string Version { get; protected set; }
|
||||
|
||||
protected int RunTest(FilePath executablePath, string arguments = null)
|
||||
{
|
||||
return RunTest(executablePath, new ProcessSettings { Arguments = arguments });
|
||||
}
|
||||
|
||||
protected int RunTest(FilePath executablePath, ProcessSettings processSettings=null)
|
||||
{
|
||||
if (executablePath == null)
|
||||
throw new ArgumentNullException(nameof(executablePath));
|
||||
|
||||
if (processSettings == null)
|
||||
processSettings = new ProcessSettings();
|
||||
|
||||
// Add default values to settings if not present
|
||||
if (processSettings.WorkingDirectory == null)
|
||||
processSettings.WorkingDirectory = BuildSettings.OutputDirectory;
|
||||
|
||||
if (executablePath.GetExtension() == ".dll")
|
||||
return Context.StartProcess("dotnet", processSettings);
|
||||
else
|
||||
return Context.StartProcess(executablePath, processSettings);
|
||||
}
|
||||
}
|
||||
|
||||
/// <Summary>
|
||||
/// A TestRunner requiring some sort of installation before use.
|
||||
/// </Summary>
|
||||
public abstract class InstallableTestRunner : TestRunner
|
||||
{
|
||||
protected InstallableTestRunner(string packageId, string version)
|
||||
{
|
||||
PackageId = packageId;
|
||||
Version = version;
|
||||
}
|
||||
|
||||
protected abstract FilePath ExecutableRelativePath { get; }
|
||||
|
||||
// Path under tools directory where package would be installed by Cake #tool directive.
|
||||
// NOTE: When used to run unit tests, a #tool directive is required. If derived package
|
||||
// is only used for package tests, it is optional.
|
||||
protected DirectoryPath ToolInstallDirectory => BuildSettings.ToolsDirectory + $"{PackageId}.{Version}";
|
||||
protected bool IsInstalledAsTool =>
|
||||
ToolInstallDirectory != null && Context.DirectoryExists(ToolInstallDirectory);
|
||||
|
||||
protected DirectoryPath InstallDirectory;
|
||||
|
||||
public FilePath ExecutablePath => InstallDirectory.CombineWithFilePath(ExecutableRelativePath);
|
||||
|
||||
public void Install(DirectoryPath installDirectory)
|
||||
{
|
||||
InstallDirectory = installDirectory.Combine($"{PackageId}.{Version}");
|
||||
|
||||
// If the runner package is already installed as a cake tool, we just copy it
|
||||
if (IsInstalledAsTool)
|
||||
Context.CopyDirectory(ToolInstallDirectory, InstallDirectory);
|
||||
// Otherwise, we install it to the requested location
|
||||
else
|
||||
Context.NuGetInstall(
|
||||
PackageId,
|
||||
new NuGetInstallSettings() { OutputDirectory = installDirectory, Version = Version });
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// TEST RUNNER SOURCE
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <Summary>
|
||||
/// TestRunnerSource is a provider of TestRunners. It is used when the tests
|
||||
/// are to be run under multiple TestRunners rather than just one.
|
||||
/// </Summary>
|
||||
public class TestRunnerSource
|
||||
{
|
||||
public TestRunnerSource(TestRunner runner1, params TestRunner[] moreRunners)
|
||||
{
|
||||
AllRunners.Add(runner1);
|
||||
AllRunners.AddRange(moreRunners);
|
||||
}
|
||||
|
||||
public List<TestRunner> AllRunners { get; } = new List<TestRunner>();
|
||||
|
||||
public IEnumerable<IUnitTestRunner> UnitTestRunners
|
||||
{
|
||||
get { foreach(var runner in AllRunners.Where(r => r is IUnitTestRunner)) yield return (IUnitTestRunner)runner; }
|
||||
}
|
||||
|
||||
public IEnumerable<IPackageTestRunner> PackageTestRunners
|
||||
{
|
||||
get { foreach(var runner in AllRunners.Where(r => r is IPackageTestRunner)) yield return (IPackageTestRunner)runner; }
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// NUNITLITE RUNNER
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// For NUnitLite tests, the test is run directly
|
||||
public class NUnitLiteRunner : TestRunner, IUnitTestRunner
|
||||
{
|
||||
public int RunUnitTest(FilePath testPath) =>
|
||||
RunTest(testPath, BuildSettings.UnitTestArguments);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// NUNIT CONSOLE RUNNERS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// NUnitConsoleRunner is used for both unit and package tests. It must be pre-installed
|
||||
// in the tools directory by use of a #tools directive.
|
||||
public class NUnitConsoleRunner : InstallableTestRunner, IUnitTestRunner, IPackageTestRunner
|
||||
{
|
||||
protected override FilePath ExecutableRelativePath => "tools/nunit3-console.exe";
|
||||
|
||||
public NUnitConsoleRunner(string version) : base("NUnit.ConsoleRunner", version) { }
|
||||
|
||||
// Run a unit test
|
||||
public int RunUnitTest(FilePath testPath) => RunTest(ToolInstallDirectory.CombineWithFilePath(ExecutableRelativePath), $"\"{testPath}\" {BuildSettings.UnitTestArguments}");
|
||||
|
||||
// Run a package test
|
||||
public int RunPackageTest(string arguments) => RunTest(ExecutablePath, arguments);
|
||||
}
|
||||
|
||||
public class NUnitNetCoreConsoleRunner : InstallableTestRunner, IUnitTestRunner, IPackageTestRunner
|
||||
{
|
||||
protected override FilePath ExecutableRelativePath => "tools/net6.0/nunit3-console.exe";
|
||||
|
||||
public NUnitNetCoreConsoleRunner(string version) : base("NUnit.ConsoleRunner.NetCore", version) { }
|
||||
|
||||
// Run a unit test
|
||||
public int RunUnitTest(FilePath testPath) => RunTest(ExecutablePath, $"\"{testPath}\" {BuildSettings.UnitTestArguments}");
|
||||
|
||||
// Run a package test
|
||||
public int RunPackageTest(string arguments) => RunTest(ExecutablePath, arguments);
|
||||
}
|
||||
|
||||
public class EngineExtensionTestRunner : TestRunner, IPackageTestRunner
|
||||
{
|
||||
private IPackageTestRunner[] _runners = new IPackageTestRunner[] {
|
||||
new NUnitConsoleRunner("3.17.0"),
|
||||
new NUnitConsoleRunner("3.15.5")
|
||||
};
|
||||
|
||||
public int RunPackageTest(string arguments)
|
||||
{
|
||||
|
||||
return _runners[0].RunPackageTest(arguments);
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// AGENT RUNNER
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// <summary>
|
||||
/// Class that knows how to run an agent directly. (For future use)
|
||||
/// </summary>
|
||||
public class AgentRunner : TestRunner, IPackageTestRunner
|
||||
{
|
||||
private string _stdExecutable;
|
||||
private string _x86Executable;
|
||||
|
||||
private FilePath _executablePath;
|
||||
|
||||
public AgentRunner(string stdExecutable, string x86Executable = null)
|
||||
{
|
||||
_stdExecutable = stdExecutable;
|
||||
_x86Executable = x86Executable;
|
||||
}
|
||||
|
||||
public int RunPackageTest(string arguments)
|
||||
{
|
||||
_executablePath = arguments.Contains("--x86")
|
||||
? _x86Executable
|
||||
: _stdExecutable;
|
||||
|
||||
return base.RunTest(_executablePath, arguments.Replace("--x86", string.Empty));
|
||||
}
|
||||
}
|
|
@ -1,27 +0,0 @@
|
|||
// Load all tools used by the recipe
|
||||
#tool NuGet.CommandLine&version=6.9.1
|
||||
#tool dotnet:?package=GitVersion.Tool&version=5.12.0
|
||||
#tool dotnet:?package=GitReleaseManager.Tool&version=0.17.0
|
||||
|
||||
public static class Tools
|
||||
{
|
||||
public static DirectoryPath FindInstalledTool(string packageId)
|
||||
{
|
||||
if (SIO.Directory.Exists(BuildSettings.ToolsDirectory + packageId))
|
||||
return BuildSettings.ToolsDirectory + packageId;
|
||||
|
||||
foreach(var dir in BuildSettings.Context.GetDirectories(BuildSettings.ToolsDirectory + $"{packageId}.*"))
|
||||
return dir; // Use first one found
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static DirectoryPath FindInstalledTool(string packageId, string version)
|
||||
{
|
||||
if (version == null)
|
||||
throw new ArgumentNullException(nameof(version));
|
||||
|
||||
var toolPath = BuildSettings.ToolsDirectory + $"{packageId}.{version}";
|
||||
return BuildSettings.ToolsDirectory + $"{packageId}.{version}";
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// UNIT TEST RUNNER
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static class UnitTesting
|
||||
{
|
||||
static ICakeContext _context;
|
||||
|
||||
static UnitTesting()
|
||||
{
|
||||
_context = BuildSettings.Context;
|
||||
}
|
||||
|
||||
public static void RunAllTests()
|
||||
{
|
||||
var unitTests = FindUnitTestFiles(BuildSettings.UnitTests);
|
||||
|
||||
_context.Information($"Located {unitTests.Count} unit test assemblies.");
|
||||
var errors = new List<string>();
|
||||
|
||||
var runner = BuildSettings.UnitTestRunner ?? new NUnitLiteRunner();
|
||||
|
||||
foreach (var testPath in unitTests)
|
||||
{
|
||||
var testFile = testPath.GetFilename();
|
||||
var containingDir = testPath.GetDirectory().GetDirectoryName();
|
||||
var runtime = IsValidRuntime(containingDir) ? containingDir : null;
|
||||
|
||||
Banner.Display(runtime != null
|
||||
? $"Running {testFile} under {runtime}"
|
||||
: $"Running {testFile}");
|
||||
|
||||
int rc = runner.RunUnitTest(testPath);
|
||||
|
||||
var name = runtime != null
|
||||
? $"{testFile}({runtime})"
|
||||
: testFile;
|
||||
if (rc > 0)
|
||||
errors.Add($"{name}: {rc} tests failed");
|
||||
else if (rc < 0)
|
||||
errors.Add($"{name} returned rc = {rc}");
|
||||
}
|
||||
|
||||
if (unitTests.Count == 0)
|
||||
_context.Warning("No unit tests were found");
|
||||
else if (errors.Count > 0)
|
||||
throw new Exception(
|
||||
"One or more unit tests failed, breaking the build.\r\n"
|
||||
+ errors.Aggregate((x, y) => x + "\r\n" + y) );
|
||||
|
||||
static bool IsValidRuntime(string text)
|
||||
{
|
||||
string[] VALID_RUNTIMES = {
|
||||
"net20", "net30", "net35", "net40", "net45", "net451", "net451",
|
||||
"net46", "net461", "net462", "net47", "net471", "net472", "net48", "net481",
|
||||
"netcoreapp1.1", "netcoreapp2.1", "netcoreapp3.1",
|
||||
"net5.0", "net6.0", "net7.0", "net8.0"
|
||||
};
|
||||
|
||||
return VALID_RUNTIMES.Contains(text);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FilePath> FindUnitTestFiles(string patternSet)
|
||||
{
|
||||
var result = new List<FilePath>();
|
||||
|
||||
if (!string.IsNullOrEmpty(patternSet))
|
||||
{
|
||||
// User supplied a set of patterns for the unit tests
|
||||
foreach (string filePattern in patternSet.Split('|'))
|
||||
foreach (var testPath in _context.GetFiles(BuildSettings.OutputDirectory + filePattern))
|
||||
result.Add(testPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use default patterns to find unit tests - case insensitive because
|
||||
// we don't know how the user may have named test assemblies.
|
||||
var defaultPatterns = new [] { "**/*.tests.dll", "**/*.tests.exe" };
|
||||
var globberSettings = new GlobberSettings { IsCaseSensitive = false };
|
||||
foreach (string filePattern in defaultPatterns)
|
||||
foreach (var testPath in _context.GetFiles(BuildSettings.OutputDirectory + filePattern, globberSettings))
|
||||
result.Add(testPath);
|
||||
}
|
||||
|
||||
result.Sort(ComparePathsByFileName);
|
||||
|
||||
return result;
|
||||
|
||||
static int ComparePathsByFileName(FilePath x, FilePath y)
|
||||
{
|
||||
return x.GetFilename().ToString().CompareTo(y.GetFilename().ToString());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// HELPER METHODS - PACKAGING
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void CopyPackageContents(DirectoryPath packageDir, DirectoryPath outDir)
|
||||
{
|
||||
var files = GetFiles(packageDir + "/tools/*").Concat(GetFiles(packageDir + "/tools/net462/*"));
|
||||
CopyFiles(files.Where(f => f.GetExtension() != ".addins"), outDir);
|
||||
}
|
||||
|
|
@ -1,115 +0,0 @@
|
|||
using System.Text.RegularExpressions;
|
||||
|
||||
public class BuildVersion
|
||||
{
|
||||
private ICakeContext _context;
|
||||
private GitVersion _gitVersion;
|
||||
|
||||
// NOTE: This is complicated because (1) the user may have specified
|
||||
// the package version on the command-line and (2) GitVersion may
|
||||
// or may not be available. We'll work on solving (2) by getting
|
||||
// GitVersion to run for us on Linux, but (1) will alwas remain.
|
||||
//
|
||||
// We simplify things a by figuring out the full package version and
|
||||
// then parsing it to provide information that is used in the build.
|
||||
public BuildVersion(ICakeContext context)
|
||||
{
|
||||
if (context==null)
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
|
||||
_context = context;
|
||||
_gitVersion = context.GitVersion();
|
||||
|
||||
BranchName = _gitVersion.BranchName;
|
||||
IsReleaseBranch = BranchName.StartsWith("release-");
|
||||
|
||||
string packageVersion = CommandLineOptions.PackageVersion.Value ?? CalculatePackageVersion();
|
||||
|
||||
int dash = packageVersion.IndexOf('-');
|
||||
IsPreRelease = dash > 0;
|
||||
|
||||
string versionPart = packageVersion;
|
||||
string suffix = "";
|
||||
string label = "";
|
||||
|
||||
if (IsPreRelease)
|
||||
{
|
||||
versionPart = packageVersion.Substring(0, dash);
|
||||
suffix = packageVersion.Substring(dash + 1);
|
||||
foreach (char c in suffix)
|
||||
{
|
||||
if (!char.IsLetter(c))
|
||||
break;
|
||||
label += c;
|
||||
}
|
||||
}
|
||||
|
||||
Version version = new Version(versionPart);
|
||||
SemVer = version.ToString(3);
|
||||
PreReleaseLabel = label;
|
||||
PreReleaseSuffix = suffix;
|
||||
|
||||
PackageVersion = packageVersion;
|
||||
AssemblyVersion = SemVer + ".0";
|
||||
AssemblyFileVersion = SemVer;
|
||||
AssemblyInformationalVersion = packageVersion;
|
||||
}
|
||||
|
||||
public string BranchName { get; }
|
||||
public bool IsReleaseBranch { get; }
|
||||
|
||||
public string PackageVersion { get; }
|
||||
public string AssemblyVersion { get; }
|
||||
public string AssemblyFileVersion { get; }
|
||||
public string AssemblyInformationalVersion { get; }
|
||||
|
||||
public string SemVer { get; }
|
||||
public bool IsPreRelease { get; }
|
||||
public string PreReleaseLabel { get; }
|
||||
public string PreReleaseSuffix { get; }
|
||||
|
||||
private string CalculatePackageVersion()
|
||||
{
|
||||
string label = _gitVersion.PreReleaseLabel;
|
||||
|
||||
// Non pre-release is easy
|
||||
if (string.IsNullOrEmpty(label))
|
||||
return _gitVersion.MajorMinorPatch;
|
||||
|
||||
string branchName = _gitVersion.BranchName;
|
||||
|
||||
// We don't currently use this pattern, but check in case we do later.
|
||||
if (branchName.StartsWith("feature/"))
|
||||
branchName = branchName.Substring(8);
|
||||
|
||||
// Arbitrary branch names are ci builds
|
||||
if (label == branchName)
|
||||
label = "ci";
|
||||
|
||||
string suffix = "-" + label + _gitVersion.CommitsSinceVersionSourcePadded;
|
||||
|
||||
switch (label)
|
||||
{
|
||||
case "ci":
|
||||
branchName = Regex.Replace(branchName, "[^0-9A-Za-z-]+", "-");
|
||||
suffix += "-" + branchName;
|
||||
// Nuget limits "special version part" to 20 chars. Add one for the hyphen.
|
||||
if (suffix.Length > 21)
|
||||
suffix = suffix.Substring(0, 21);
|
||||
return _gitVersion.MajorMinorPatch + suffix;
|
||||
|
||||
case "dev":
|
||||
case "pre":
|
||||
return _gitVersion.MajorMinorPatch + suffix;
|
||||
|
||||
case "pr":
|
||||
return _gitVersion.LegacySemVerPadded;
|
||||
|
||||
case "rc":
|
||||
case "alpha":
|
||||
case "beta":
|
||||
default:
|
||||
return _gitVersion.LegacySemVer;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
public class ZipPackage : PackageDefinition
|
||||
{
|
||||
public ZipPackage(
|
||||
string id,
|
||||
string source,
|
||||
IPackageTestRunner testRunner = null,
|
||||
TestRunnerSource testRunnerSource = null,
|
||||
PackageCheck[] checks = null,
|
||||
IEnumerable<PackageTest> tests = null,
|
||||
PackageReference[] bundledExtensions = null )
|
||||
: base(
|
||||
PackageType.Zip,
|
||||
id,
|
||||
source,
|
||||
testRunner: testRunner,
|
||||
testRunnerSource: testRunnerSource,
|
||||
checks: checks,
|
||||
tests: tests)
|
||||
{
|
||||
BundledExtensions = bundledExtensions;
|
||||
}
|
||||
|
||||
// ZIP package supports bundling of extensions
|
||||
public PackageReference[] BundledExtensions { get; }
|
||||
|
||||
// The file name of this package, including extension
|
||||
public override string PackageFileName => $"{PackageId}-{PackageVersion}.zip";
|
||||
// The directory into which this package is installed
|
||||
public override string PackageInstallDirectory => BuildSettings.ZipTestDirectory;
|
||||
// The directory used to contain results of package tests for this package
|
||||
public override string PackageResultDirectory => $"{BuildSettings.ZipResultDirectory}{PackageId}/";
|
||||
// The directory into which extensions to the test runner are installed
|
||||
public override string ExtensionInstallDirectory => $"{BuildSettings.ZipTestDirectory}{PackageId}.{PackageVersion}/bin/addins/";
|
||||
|
||||
public override void BuildPackage()
|
||||
{
|
||||
FetchBundledExtensions(BundledExtensions);
|
||||
|
||||
CreateZipImage();
|
||||
|
||||
_context.Zip(BuildSettings.ZipImageDirectory, $"{BuildSettings.PackageDirectory}{PackageFileName}");
|
||||
}
|
||||
|
||||
public override void InstallPackage()
|
||||
{
|
||||
_context.Unzip($"{BuildSettings.PackageDirectory}{PackageFileName}", $"{PackageInstallDirectory}{PackageId}.{PackageVersion}");
|
||||
}
|
||||
|
||||
private void CreateZipImage()
|
||||
{
|
||||
_context.CleanDirectory(BuildSettings.ZipImageDirectory);
|
||||
|
||||
_context.CopyFiles(
|
||||
new FilePath[] { "LICENSE.txt", "NOTICES.txt", "CHANGES.txt", "nunit.ico" },
|
||||
BuildSettings.ZipImageDirectory);
|
||||
|
||||
_context.CopyDirectory(
|
||||
BuildSettings.OutputDirectory,
|
||||
BuildSettings.ZipImageDirectory + "bin/" );
|
||||
|
||||
_context.CopyFileToDirectory(
|
||||
BuildSettings.ZipDirectory + "nunit.bundle.addins",
|
||||
BuildSettings.ZipImageDirectory);
|
||||
|
||||
var addinsDir = BuildSettings.ZipImageDirectory + "bin/net462/addins/";
|
||||
_context.CreateDirectory(addinsDir);
|
||||
|
||||
foreach (var packageDir in SIO.Directory.GetDirectories(BuildSettings.ExtensionsDirectory))
|
||||
{
|
||||
var files = _context.GetFiles(packageDir + "/tools/*").Concat(_context.GetFiles(packageDir + "/tools/net462/*"));
|
||||
_context.CopyFiles(files.Where(f => f.GetExtension() != ".addins"), addinsDir);
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче