Use dev00001 build of common NUnit cake recipe
This commit is contained in:
Родитель
43310d4216
Коммит
3a021451be
|
@ -19,3 +19,4 @@ environment:
|
||||||
secure: aDsu1U+umVYFVybjkBVtVQsatSj3QKbD7VkGQci9mNF3493g9Giao/GABISIaHjT
|
secure: aDsu1U+umVYFVybjkBVtVQsatSj3QKbD7VkGQci9mNF3493g9Giao/GABISIaHjT
|
||||||
GITHUB_ACCESS_TOKEN:
|
GITHUB_ACCESS_TOKEN:
|
||||||
secure: xmGXWrw5Nj3CI3fPxhw/DWIU5YL/1mM06pSmjpkd9LpKs3t3EYXbECbEQs62lU/O
|
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.15.5
|
||||||
#tool nuget:?package=NUnit.ConsoleRUnner&version=3.17.0
|
#tool nuget:?package=NUnit.ConsoleRUnner&version=3.17.0
|
||||||
#tool nuget:?package=NUnit.ConsoleRunner&version=3.18.0-dev00037
|
#tool nuget:?package=NUnit.ConsoleRunner&version=3.18.0-dev00037
|
||||||
#tool nuget:?package=NUnit.ConsoleRunner.NetCore&version=3.18.0-dev00037
|
#tool nuget:?package=NUnit.ConsoleRunner.NetCore&version=3.18.0-dev00037
|
||||||
|
|
||||||
// Load scripts
|
// Load scripts
|
||||||
#load recipe/*.cake
|
#load nuget:?package=NUnit.Cake.Recipe&version=1.0.0-dev00001
|
||||||
|
//#load ../NUnit.Cake.Recipe/recipe/*.cake
|
||||||
|
|
||||||
// Initialize BuildSettings
|
// Initialize BuildSettings
|
||||||
BuildSettings.Initialize(
|
BuildSettings.Initialize(
|
||||||
|
@ -16,12 +13,8 @@ BuildSettings.Initialize(
|
||||||
"NUnit Project Loader",
|
"NUnit Project Loader",
|
||||||
"nunit-project-loader",
|
"nunit-project-loader",
|
||||||
solutionFile: "nunit-project-loader.sln",
|
solutionFile: "nunit-project-loader.sln",
|
||||||
//unitTestRunner: new NUnitLiteRunner(),
|
unitTestRunner: new NUnitLiteRunner(),
|
||||||
//unitTests: "**/*.Tests.exe");
|
unitTests: "**/*.Tests.exe");
|
||||||
unitTestRunner: new NUnitConsoleRunner("3.17.0"),
|
|
||||||
unitTests: "**/*.Tests.dll");
|
|
||||||
//unitTestRunner: new NUnitNetCoreConsoleRunner("3.18.0-dev00037"),
|
|
||||||
//unitTests: "**/*.Tests.dll");
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// PACKAGE TESTS
|
// PACKAGE TESTS
|
||||||
|
@ -100,11 +93,6 @@ BuildSettings.Packages.Add(
|
||||||
HasDirectory("tools/net6.0").WithFiles("nunit-project-loader.dll", "nunit.engine.api.dll") },
|
HasDirectory("tools/net6.0").WithFiles("nunit-project-loader.dll", "nunit.engine.api.dll") },
|
||||||
tests: PackageTests,
|
tests: PackageTests,
|
||||||
testRunnerSource: new TestRunnerSource(new NUnitConsoleRunner("3.17.0"), new NUnitConsoleRunner("3.15.5"), new NUnitConsoleRunner("3.18.0-dev00037"))
|
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") },
|
HasDirectory("tools/net6.0").WithFiles("nunit-project-loader.dll", "nunit.engine.api.dll") },
|
||||||
tests: PackageTests,
|
tests: PackageTests,
|
||||||
testRunnerSource: new TestRunnerSource(new NUnitConsoleRunner("3.17.0"), new NUnitConsoleRunner("3.15.5"), new NUnitConsoleRunner("3.18.0-dev00037"))
|
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
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "test-lib-2", "src\test-lib-2\test-lib-2.csproj", "{7808DEA9-FB13-47FC-823F-DC78C1057061}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "test-lib-2", "src\test-lib-2\test-lib-2.csproj", "{7808DEA9-FB13-47FC-823F-DC78C1057061}"
|
||||||
EndProject
|
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}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nuget", "nuget", "{6C381491-0062-4276-B884-86A6A175FFF5}"
|
||||||
ProjectSection(SolutionItems) = preProject
|
ProjectSection(SolutionItems) = preProject
|
||||||
nuget\nunit-project-loader.legacy.addins = nuget\nunit-project-loader.legacy.addins
|
nuget\nunit-project-loader.legacy.addins = nuget\nunit-project-loader.legacy.addins
|
||||||
|
@ -101,7 +69,6 @@ Global
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(NestedProjects) = preSolution
|
GlobalSection(NestedProjects) = preSolution
|
||||||
{7EE5FBD2-CD4B-4FB0-9F36-29665955E8BE} = {3B28CF0C-D613-4971-9D8F-00C960C656E2}
|
|
||||||
{6C381491-0062-4276-B884-86A6A175FFF5} = {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}
|
{2DA8DF86-18D3-4832-970C-A0B26498B93D} = {3B28CF0C-D613-4971-9D8F-00C960C656E2}
|
||||||
EndGlobalSection
|
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Загрузка…
Ссылка в новой задаче