From 99c18bade0bf2018f9409d47677ec623f89ce81d Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Fri, 2 Jan 2026 17:28:01 +0100
Subject: [PATCH 01/73] Add Cake.Frosting-based build utilities for streamlined
task management
- Introduced `BuildContext` for managing solution, Git root, and executed tasks.
- Added foundational task templates (`BuildTask`, `CleanTask`, `RestoreTask`, etc.) and default implementations.
- Included CakeHost extensions for task registration and setup.
- Created sample project demonstrating the usage of custom tasks.
- Updated solution file to include new `CakeBuild` projects and samples.
---
Core.sln | 17 +++++
.../CakeBuildSample/CakeBuildSample.csproj | 14 ++++
samples/CakeBuildSample/Program.cs | 13 ++++
.../CreativeCoders.CakeBuild/BuildContext.cs | 50 +++++++++++++
.../CakeContextExtensions.cs | 28 ++++++++
.../CakeHostExtensions.cs | 70 +++++++++++++++++++
.../CreativeCoders.CakeBuild.csproj | 13 ++++
.../StaticGitVersion.cs | 40 +++++++++++
.../Tasks/Defaults/BuildTask.cs | 8 +++
.../Tasks/Defaults/CleanTask.cs | 7 ++
.../Tasks/Defaults/CodeCoverageTask.cs | 8 +++
.../Tasks/Defaults/NuGetPublishTask.cs | 8 +++
.../Tasks/Defaults/PackTask.cs | 8 +++
.../Tasks/Defaults/RestoreTask.cs | 8 +++
.../Tasks/Defaults/TestTask.cs | 8 +++
.../Tasks/FrostingTaskBase.cs | 14 ++++
.../Tasks/Templates/BuildTask.cs | 40 +++++++++++
.../Tasks/Templates/CleanTask.cs | 3 +
.../Tasks/Templates/CodeCoverageTask.cs | 4 ++
.../Tasks/Templates/NuGetPublishTask.cs | 3 +
.../Tasks/Templates/PackTask.cs | 4 ++
.../Tasks/Templates/RestoreTask.cs | 14 ++++
.../Tasks/Templates/TestTask.cs | 3 +
23 files changed, 385 insertions(+)
create mode 100644 samples/CakeBuildSample/CakeBuildSample.csproj
create mode 100644 samples/CakeBuildSample/Program.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CodeCoverageTask.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/PackTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/RestoreTask.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/TestTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
diff --git a/Core.sln b/Core.sln
index dce7aa22..f017c0df 100644
--- a/Core.sln
+++ b/Core.sln
@@ -247,6 +247,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CliHostSampleApp", "samples
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.Cli.Tests", "tests\CreativeCoders.Cli.Tests\CreativeCoders.Cli.Tests.csproj", "{FF482B6D-D459-413E-82E0-9175C44DA8BA}"
EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "CakeBuild", "CakeBuild", "{E8EF00ED-01FA-4F51-A668-5AF8B6C0F09E}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CreativeCoders.CakeBuild", "source\CakeBuild\CreativeCoders.CakeBuild\CreativeCoders.CakeBuild.csproj", "{EB88412B-8523-4DA4-8FF9-CACECA0969E6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CakeBuildSample", "samples\CakeBuildSample\CakeBuildSample.csproj", "{58C01CB8-B65A-44FE-9BE0-22929CD474A2}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -571,6 +577,14 @@ Global
{FF482B6D-D459-413E-82E0-9175C44DA8BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FF482B6D-D459-413E-82E0-9175C44DA8BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FF482B6D-D459-413E-82E0-9175C44DA8BA}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Release|Any CPU.Build.0 = Release|Any CPU
+ {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -679,6 +693,9 @@ Global
{ED92EBC6-C297-46AE-998B-155A26442AA5} = {CDCF2469-1668-4EB0-A73F-692115CF6776}
{CA248700-A9E0-433E-98FE-4E1C6844811F} = {72E179CA-7AE6-412A-856D-7BD13838E8E3}
{FF482B6D-D459-413E-82E0-9175C44DA8BA} = {5A3FFD14-2258-4007-AC77-BAFB3B3EB26F}
+ {E8EF00ED-01FA-4F51-A668-5AF8B6C0F09E} = {2A7105AA-05B6-469A-93F5-719723A4D90D}
+ {EB88412B-8523-4DA4-8FF9-CACECA0969E6} = {E8EF00ED-01FA-4F51-A668-5AF8B6C0F09E}
+ {58C01CB8-B65A-44FE-9BE0-22929CD474A2} = {72E179CA-7AE6-412A-856D-7BD13838E8E3}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {EE24476B-9A4C-4146-B982-3461FAF8B3B0}
diff --git a/samples/CakeBuildSample/CakeBuildSample.csproj b/samples/CakeBuildSample/CakeBuildSample.csproj
new file mode 100644
index 00000000..793be092
--- /dev/null
+++ b/samples/CakeBuildSample/CakeBuildSample.csproj
@@ -0,0 +1,14 @@
+
+
+
+ Exe
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
new file mode 100644
index 00000000..49fb91df
--- /dev/null
+++ b/samples/CakeBuildSample/Program.cs
@@ -0,0 +1,13 @@
+using Cake.Frosting;
+
+namespace CakeBuildSample;
+
+internal static class Program
+{
+ static int Main(string[] args)
+ {
+ return new CakeHost()
+ .UseTaskSetup<>()
+ .Run(args);
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
new file mode 100755
index 00000000..42a2741a
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -0,0 +1,50 @@
+using Cake.Common.Tools.GitVersion;
+using Cake.Core;
+using Cake.Core.IO;
+using Cake.Frosting;
+
+namespace CreativeCoders.CakeBuild;
+
+public class BuildContext : FrostingContext
+{
+ private readonly List _executedTasks = [];
+
+ public FilePath SolutionFile { get; set; }
+
+ public GitVersion Version { get; set; }
+
+ public DirectoryPath RootDir { get; set; }
+
+ public IEnumerable ExecutedTasks => _executedTasks;
+
+ public BuildContext(ICakeContext context)
+ : base(context)
+ {
+ RootDir = FindGitRootPath(context.Environment.WorkingDirectory) ??
+ context.Environment.WorkingDirectory.GetParent();
+ SolutionFile = context.Arguments.GetArgument("solution");
+ }
+
+ public void AddExecutedTask(IFrostingTask task)
+ {
+ _executedTasks.Add(task);
+ }
+
+ private DirectoryPath? FindGitRootPath(DirectoryPath? startPath)
+ {
+ while (true)
+ {
+ if (startPath == null)
+ {
+ return null;
+ }
+
+ if (FileSystem.Exist(startPath.Combine(".git")))
+ {
+ return startPath;
+ }
+
+ startPath = startPath.GetParent();
+ }
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
new file mode 100755
index 00000000..ab8ef18c
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
@@ -0,0 +1,28 @@
+using Cake.Common.Tools.GitVersion;
+using Cake.Core;
+using Cake.Frosting;
+
+namespace CreativeCoders.CakeBuild;
+
+public static class CakeContextExtensions
+{
+ public static bool TaskHasRun(this BuildContext context)
+ where TTask : IFrostingTask
+ {
+ return context.ExecutedTasks.Any(x => x.GetType() == typeof(TTask));
+ }
+
+ public static GitVersion GetGitVersionSafe(this ICakeContext context,
+ string? major = null, string? minor = null, string? patch = null, string? build = null,
+ GitVersionSettings? gitVersionSettings = null)
+ {
+ try
+ {
+ return context.GitVersion();
+ }
+ catch (Exception)
+ {
+ return StaticGitVersion.Create(major ?? "0", minor ?? "0", patch ?? "0", build ?? "0", "");
+ }
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
new file mode 100755
index 00000000..91656e1e
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -0,0 +1,70 @@
+using System.Reflection;
+using Cake.Frosting;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.DependencyInjection.Extensions;
+
+namespace CreativeCoders.CakeBuild;
+
+public static class CakeHostExtensions
+{
+ public static CakeHost AddTask(this CakeHost host)
+ where TTask : class, IFrostingTask
+ {
+ return host.ConfigureServices(x => x.AddSingleton());
+ }
+
+ public static CakeHost AddTask(this CakeHost host, TTaskSettings taskSettings)
+ where TTask : class, IFrostingTask
+ where TTaskSettings : class
+ {
+ ArgumentNullException.ThrowIfNull(host);
+
+ return host.ConfigureServices(x =>
+ {
+ x.AddSingleton();
+
+ x.TryAddSingleton(taskSettings);
+ }
+ );
+ }
+
+ public static CakeHost AddTasks(this CakeHost host, params Type[] taskTypes)
+ {
+ ArgumentNullException.ThrowIfNull(host);
+ ArgumentNullException.ThrowIfNull(taskTypes);
+
+ return host.ConfigureServices(x =>
+ {
+ foreach (var taskType in taskTypes)
+ {
+ if (!typeof(IFrostingTask).IsAssignableFrom(taskType))
+ {
+ throw new InvalidOperationException(
+ $"Type '{taskType.FullName}' does not implement '{nameof(IFrostingTask)}'.");
+ }
+
+ x.AddSingleton(typeof(IFrostingTask), taskType);
+ }
+ });
+ }
+
+ public static CakeHost UseBuildSetup(this CakeHost host)
+ where TBuildSetup : class
+ {
+ host.ConfigureServices(services => services.AddSingleton());
+
+ foreach (var propertyInfo in typeof(TBuildSetup).GetProperties(BindingFlags.Public |
+ BindingFlags.Instance))
+ {
+ host.ConfigureServices(services => services.AddSingleton(propertyInfo.PropertyType, sp =>
+ {
+ var buildSetup = sp.GetRequiredService();
+
+ return propertyInfo.GetValue(buildSetup) ?? throw new InvalidOperationException(
+ $"Property '{propertyInfo.Name}' of BuildSetup '{typeof(TBuildSetup).FullName}' is null.");
+ }));
+ }
+
+ return host;
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj b/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj
new file mode 100644
index 00000000..bc7d4b3d
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs b/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs
new file mode 100755
index 00000000..4af8d11f
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs
@@ -0,0 +1,40 @@
+using Cake.Common.Tools.GitVersion;
+
+namespace CreativeCoders.CakeBuild;
+
+public static class StaticGitVersion
+{
+ public static GitVersion Create(string major, string minor, string patch, string build,
+ string preReleaseTag)
+ {
+ var version = $"{major}.{minor}.{patch}.{build}";
+ var versionWithPreRelease = string.IsNullOrWhiteSpace(preReleaseTag)
+ ? version
+ : $"{version}-{preReleaseTag}";
+
+ return new GitVersion
+ {
+ Major = int.Parse(major),
+ Minor = int.Parse(minor),
+ Patch = int.Parse(patch),
+ PreReleaseTag = preReleaseTag,
+ BuildMetaData = build,
+ AssemblySemVer = versionWithPreRelease,
+ FullSemVer = versionWithPreRelease,
+ AssemblySemFileVer = version,
+ BranchName = "unknown",
+ InformationalVersion = versionWithPreRelease,
+ MajorMinorPatch = $"{major}.{minor}.{patch}",
+ LegacySemVer = versionWithPreRelease,
+ NuGetVersion = versionWithPreRelease,
+ NuGetVersionV2 = versionWithPreRelease,
+ PreReleaseLabel = preReleaseTag,
+ SemVer = versionWithPreRelease,
+ NuGetPreReleaseTag = preReleaseTag,
+ NuGetPreReleaseTagV2 = preReleaseTag,
+ CommitDate = DateTimeOffset.Now.ToString(),
+ PreReleaseTagWithDash = $"-{preReleaseTag}",
+ PreReleaseLabelWithDash = $"-{preReleaseTag}",
+ };
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs
new file mode 100755
index 00000000..aa756e91
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs
@@ -0,0 +1,8 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("Build")]
+[IsDependentOn(typeof(RestoreTask))]
+public class BuildTask(BuildTaskSettings settings) : BuildTask(settings);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs
new file mode 100644
index 00000000..0fcad8f2
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs
@@ -0,0 +1,7 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("Build")]
+public class CleanTask : CleanTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CodeCoverageTask.cs
new file mode 100644
index 00000000..7f979ecc
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CodeCoverageTask.cs
@@ -0,0 +1,8 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("CodeCoverage")]
+[IsDependentOn(typeof(TestTask))]
+public class CodeCoverageTask : CodeCoverageTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs
new file mode 100644
index 00000000..e401e7b8
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs
@@ -0,0 +1,8 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("NuGetPublish")]
+[IsDependentOn(typeof(PackTask))]
+public class NuGetPublishTask : NuGetPublishTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/PackTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/PackTask.cs
new file mode 100644
index 00000000..7ccadcbf
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/PackTask.cs
@@ -0,0 +1,8 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("Pack")]
+[IsDependentOn(typeof(CodeCoverageTask))]
+public class PackTask : PackTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/RestoreTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/RestoreTask.cs
new file mode 100755
index 00000000..62a60423
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/RestoreTask.cs
@@ -0,0 +1,8 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("Restore")]
+[IsDependentOn(typeof(CleanTask))]
+public class RestoreTask : RestoreTask;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/TestTask.cs
new file mode 100644
index 00000000..288f4098
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/TestTask.cs
@@ -0,0 +1,8 @@
+using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+[TaskName("Test")]
+[IsDependentOn(typeof(BuildTask))]
+public class TestTask : TestTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
new file mode 100755
index 00000000..4ced8fdc
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
@@ -0,0 +1,14 @@
+using Cake.Frosting;
+
+namespace CreativeCoders.CakeBuild.Tasks;
+
+public class FrostingTaskBase : AsyncFrostingTask
+ where T : BuildContext
+{
+ public override void Finally(T context)
+ {
+ base.Finally(context);
+
+ context.AddExecutedTask(this);
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
new file mode 100755
index 00000000..df3b396b
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -0,0 +1,40 @@
+using Cake.Common.Tools.DotNet;
+using Cake.Common.Tools.DotNet.Build;
+using Cake.Core.Diagnostics;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class BuildTask(BuildTaskSettings settings) : FrostingTaskBase
+ where T : BuildContext
+{
+ protected virtual void ApplyDotNetBuildSettings(DotNetBuildSettings dotNetBuildSettings) { }
+
+ private DotNetBuildSettings CreateDotNetBuildSettings()
+ {
+ var dotNetBuildSettings = new DotNetBuildSettings
+ {
+ Configuration = settings.Configuration
+ };
+
+ ApplyDotNetBuildSettings(dotNetBuildSettings);
+
+ return dotNetBuildSettings;
+ }
+
+ public override Task RunAsync(T context)
+ {
+ var dotnetSettings = CreateDotNetBuildSettings();
+
+ context.Log.Information("Building solution {0} with configuration {1}",
+ context.SolutionFile.FullPath, dotnetSettings.Configuration);
+
+ context.DotNetBuild(context.SolutionFile.FullPath, dotnetSettings);
+
+ return Task.CompletedTask;
+ }
+}
+
+public class BuildTaskSettings
+{
+ public string? Configuration { get; set; }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
new file mode 100755
index 00000000..bf4b0f9d
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class CleanTask : FrostingTaskBase where T : BuildContext { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
new file mode 100755
index 00000000..526c0750
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
@@ -0,0 +1,4 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class CodeCoverageTask : FrostingTaskBase
+ where T : BuildContext { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
new file mode 100755
index 00000000..504b9af0
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class NuGetPublishTask : FrostingTaskBase where T : BuildContext { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
new file mode 100755
index 00000000..7a24f6ab
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
@@ -0,0 +1,4 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class PackTask : FrostingTaskBase
+ where T : BuildContext { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
new file mode 100755
index 00000000..c4ece690
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
@@ -0,0 +1,14 @@
+using Cake.Common.Tools.DotNet;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class RestoreTask : FrostingTaskBase
+ where T : BuildContext
+{
+ public override Task RunAsync(T context)
+ {
+ context.DotNetRestore(context.RootDir.FullPath);
+
+ return Task.CompletedTask;
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
new file mode 100755
index 00000000..377389f6
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class TestTask : FrostingTaskBase where T : BuildContext { }
From 0dccfa21aa26685bbf05b4ba02e20f4b8fa80193 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Fri, 2 Jan 2026 18:26:23 +0100
Subject: [PATCH 02/73] Add support for solution file auto-detection, build
configuration, and context initialization improvements
- Renamed `CleanTask` to properly align task names with functionality.
- Enhanced `BuildContext` to include solution file auto-detection, default build configuration, and Git version integration.
- Simplified `BuildTask` templates and adjusted configuration handling.
- Updated `CakeHost` sample with task registration and streamlined workflow.
- Refactored project files for consistent dependencies and task integration.
---
Core.sln | 3 +-
.../CakeBuildSample/CakeBuildSample.csproj | 4 ++
samples/CakeBuildSample/Program.cs | 7 +++-
.../CreativeCoders.CakeBuild/BuildContext.cs | 41 ++++++++++++++++++-
.../CakeContextExtensions.cs | 2 +-
.../CreativeCoders.CakeBuild.csproj | 4 ++
.../Tasks/Defaults/BuildTask.cs | 2 +-
.../Tasks/Defaults/CleanTask.cs | 2 +-
.../Tasks/Templates/BuildTask.cs | 22 +++++++---
9 files changed, 73 insertions(+), 14 deletions(-)
diff --git a/Core.sln b/Core.sln
index f017c0df..da034e61 100644
--- a/Core.sln
+++ b/Core.sln
@@ -582,9 +582,8 @@ Global
{EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Release|Any CPU.Build.0 = Release|Any CPU
{58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/samples/CakeBuildSample/CakeBuildSample.csproj b/samples/CakeBuildSample/CakeBuildSample.csproj
index 793be092..ec82a3ec 100644
--- a/samples/CakeBuildSample/CakeBuildSample.csproj
+++ b/samples/CakeBuildSample/CakeBuildSample.csproj
@@ -11,4 +11,8 @@
+
+
+
+
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 49fb91df..557737fc 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,4 +1,6 @@
using Cake.Frosting;
+using CreativeCoders.CakeBuild;
+using CreativeCoders.CakeBuild.Tasks.Defaults;
namespace CakeBuildSample;
@@ -7,7 +9,10 @@ internal static class Program
static int Main(string[] args)
{
return new CakeHost()
- .UseTaskSetup<>()
+ .UseContext()
+ .AddTask()
+ .AddTask()
+ .AddTask()
.Run(args);
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index 42a2741a..f0c0bb6b 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -1,7 +1,9 @@
-using Cake.Common.Tools.GitVersion;
+using Cake.Common.Diagnostics;
+using Cake.Common.Tools.GitVersion;
using Cake.Core;
using Cake.Core.IO;
using Cake.Frosting;
+using CreativeCoders.Core.IO;
namespace CreativeCoders.CakeBuild;
@@ -15,6 +17,8 @@ public class BuildContext : FrostingContext
public DirectoryPath RootDir { get; set; }
+ public string BuildConfiguration { get; set; } = "Release";
+
public IEnumerable ExecutedTasks => _executedTasks;
public BuildContext(ICakeContext context)
@@ -22,7 +26,40 @@ public BuildContext(ICakeContext context)
{
RootDir = FindGitRootPath(context.Environment.WorkingDirectory) ??
context.Environment.WorkingDirectory.GetParent();
- SolutionFile = context.Arguments.GetArgument("solution");
+
+ var solutionsFilePath = context.Arguments.GetArgument("solution");
+ SolutionFile = string.IsNullOrWhiteSpace(solutionsFilePath)
+ ? FindRootSolution(context)
+ : new FilePath(solutionsFilePath);
+
+ Version = context.GetGitVersionSafe();
+ }
+
+ private FilePath FindRootSolution(ICakeContext context)
+ {
+ var solutionsFiles =
+ FileSys.Directory.EnumerateFiles(RootDir.FullPath, "*.sln", SearchOption.AllDirectories);
+
+ var solutionsSlnxFiles =
+ FileSys.Directory.EnumerateFiles(RootDir.FullPath, "*.slnx", SearchOption.AllDirectories);
+
+ var solutions = solutionsFiles.Concat(solutionsSlnxFiles).ToArray();
+
+ if (solutions.Length > 1)
+ {
+ context.Error("Multiple solution files found.");
+ }
+
+ var solution = solutions.FirstOrDefault();
+
+ if (solution == null)
+ {
+ context.Error("No solution file found.");
+
+ throw new InvalidOperationException("No solution file found");
+ }
+
+ return solution;
}
public void AddExecutedTask(IFrostingTask task)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
index ab8ef18c..90ed095e 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
@@ -22,7 +22,7 @@ public static GitVersion GetGitVersionSafe(this ICakeContext context,
}
catch (Exception)
{
- return StaticGitVersion.Create(major ?? "0", minor ?? "0", patch ?? "0", build ?? "0", "");
+ return StaticGitVersion.Create(major ?? "0", minor ?? "0", patch ?? "0", build ?? "1", "");
}
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj b/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj
index bc7d4b3d..69c651f0 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CreativeCoders.CakeBuild.csproj
@@ -10,4 +10,8 @@
+
+
+
+
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs
index aa756e91..814d08c1 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/BuildTask.cs
@@ -5,4 +5,4 @@ namespace CreativeCoders.CakeBuild.Tasks.Defaults;
[TaskName("Build")]
[IsDependentOn(typeof(RestoreTask))]
-public class BuildTask(BuildTaskSettings settings) : BuildTask(settings);
+public class BuildTask() : BuildTask();
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs
index 0fcad8f2..43fcf543 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/CleanTask.cs
@@ -3,5 +3,5 @@
namespace CreativeCoders.CakeBuild.Tasks.Defaults;
-[TaskName("Build")]
+[TaskName("Clean")]
public class CleanTask : CleanTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index df3b396b..5c5f568a 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -1,29 +1,39 @@
using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Build;
+using Cake.Common.Tools.DotNet.MSBuild;
using Cake.Core.Diagnostics;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
-public class BuildTask(BuildTaskSettings settings) : FrostingTaskBase
+[PublicAPI]
+public class BuildTask() : FrostingTaskBase
where T : BuildContext
{
- protected virtual void ApplyDotNetBuildSettings(DotNetBuildSettings dotNetBuildSettings) { }
+ protected virtual void ApplyDotNetBuildSettings(T context, DotNetBuildSettings dotNetBuildSettings) { }
- private DotNetBuildSettings CreateDotNetBuildSettings()
+ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
{
var dotNetBuildSettings = new DotNetBuildSettings
{
- Configuration = settings.Configuration
+ Configuration = context.BuildConfiguration,
+ NoRestore = true,
+ MSBuildSettings = new DotNetMSBuildSettings
+ {
+ InformationalVersion = context.Version.InformationalVersion,
+ AssemblyVersion = context.Version.AssemblySemVer,
+ FileVersion = context.Version.AssemblySemFileVer
+ }
};
- ApplyDotNetBuildSettings(dotNetBuildSettings);
+ ApplyDotNetBuildSettings(context, dotNetBuildSettings);
return dotNetBuildSettings;
}
public override Task RunAsync(T context)
{
- var dotnetSettings = CreateDotNetBuildSettings();
+ var dotnetSettings = CreateDotNetBuildSettings(context);
context.Log.Information("Building solution {0} with configuration {1}",
context.SolutionFile.FullPath, dotnetSettings.Configuration);
From 8ca81bd7ee4cea45de5740c2eea59ddb847e99cd Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Fri, 2 Jan 2026 18:46:43 +0100
Subject: [PATCH 03/73] Update `CakeContextExtensions` to include exception
variable in catch block for improved diagnostics, and refine `GitVersion.yml`
configuration
- Replace `tag` with `label` for branch definitions.
- Adjust formatting for improved YAML readability.
---
GitVersion.yml | 79 ++++++++-----------
.../CakeContextExtensions.cs | 2 +-
2 files changed, 33 insertions(+), 48 deletions(-)
diff --git a/GitVersion.yml b/GitVersion.yml
index 7d2adb2e..496a653f 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -8,111 +8,96 @@ mode: ContinuousDeployment
branches:
feature:
mode: ContinuousDeployment
- tag: feature.{BranchName}
+ label: feature.{BranchName}
increment: Minor
- prevent-increment-of-merged-branch-version: false
track-merge-target: false
regex: ^features?[/-]
source-branches:
- - develop
- - main
- - release
- - feature
- - support
- - hotfix
+ - develop
+ - main
+ - release
+ - feature
+ - support
+ - hotfix
tracks-release-branches: false
is-release-branch: false
- is-mainline: false
pre-release-weight: 30000
main:
mode: ContinuousDeployment
- tag: ''
+ label: ''
increment: Patch
- prevent-increment-of-merged-branch-version: true
track-merge-target: false
regex: ^master$|^main$
source-branches:
- - develop
- - release
+ - develop
+ - release
tracks-release-branches: false
is-release-branch: false
- is-mainline: true
pre-release-weight: 55000
develop:
mode: ContinuousDeployment
- tag: alpha
+ label: alpha
increment: Minor
- prevent-increment-of-merged-branch-version: false
track-merge-target: true
regex: ^dev(elop)?(ment)?$
- source-branches: []
+ source-branches: [ ]
tracks-release-branches: true
is-release-branch: false
- is-mainline: false
pre-release-weight: 0
release:
mode: ContinuousDeployment
- tag: beta
+ label: beta
increment: None
- prevent-increment-of-merged-branch-version: true
track-merge-target: false
regex: ^releases?[/-]
source-branches:
- - develop
- - main
- - support
- - release
+ - develop
+ - main
+ - support
+ - release
tracks-release-branches: false
is-release-branch: true
- is-mainline: false
pre-release-weight: 30000
pull-request:
mode: ContinuousDeployment
- tag: PullRequest
+ label: PullRequest
increment: Inherit
- prevent-increment-of-merged-branch-version: false
- tag-number-pattern: '[/-](?\d+)'
track-merge-target: false
regex: ^(pull|pull\-requests|pr)[/-]
source-branches:
- - develop
- - main
- - release
- - feature
- - support
- - hotfix
+ - develop
+ - main
+ - release
+ - feature
+ - support
+ - hotfix
tracks-release-branches: false
is-release-branch: false
- is-mainline: false
pre-release-weight: 30000
hotfix:
mode: ContinuousDeployment
- tag: beta
+ label: beta
increment: Patch
- prevent-increment-of-merged-branch-version: false
track-merge-target: false
regex: ^hotfix(es)?[/-]
source-branches:
- - develop
- - main
- - support
+ - develop
+ - main
+ - support
tracks-release-branches: false
is-release-branch: false
- is-mainline: false
pre-release-weight: 30000
support:
mode: ContinuousDeployment
- tag: ''
+ label: ''
increment: Patch
- prevent-increment-of-merged-branch-version: true
track-merge-target: false
regex: ^support[/-]
source-branches:
- - main
+ - main
tracks-release-branches: false
is-release-branch: false
- is-mainline: true
pre-release-weight: 55000
ignore:
- sha: []
-merge-message-formats: {}
+ sha: [ ]
+merge-message-formats: { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
index 90ed095e..af61d656 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
@@ -20,7 +20,7 @@ public static GitVersion GetGitVersionSafe(this ICakeContext context,
{
return context.GitVersion();
}
- catch (Exception)
+ catch (Exception e)
{
return StaticGitVersion.Create(major ?? "0", minor ?? "0", patch ?? "0", build ?? "1", "");
}
From 9f0dd9fa9b15f728f2c88527860faf48f18137da Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 11:58:26 +0100
Subject: [PATCH 04/73] Simplify `GitVersion.yml` by removing unused branch
configurations and redundant properties.
---
GitVersion.yml | 39 ---------------------------------------
1 file changed, 39 deletions(-)
diff --git a/GitVersion.yml b/GitVersion.yml
index 496a653f..6460f715 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -13,12 +13,7 @@ branches:
track-merge-target: false
regex: ^features?[/-]
source-branches:
- - develop
- main
- - release
- - feature
- - support
- - hotfix
tracks-release-branches: false
is-release-branch: false
pre-release-weight: 30000
@@ -34,16 +29,6 @@ branches:
tracks-release-branches: false
is-release-branch: false
pre-release-weight: 55000
- develop:
- mode: ContinuousDeployment
- label: alpha
- increment: Minor
- track-merge-target: true
- regex: ^dev(elop)?(ment)?$
- source-branches: [ ]
- tracks-release-branches: true
- is-release-branch: false
- pre-release-weight: 0
release:
mode: ContinuousDeployment
label: beta
@@ -74,30 +59,6 @@ branches:
tracks-release-branches: false
is-release-branch: false
pre-release-weight: 30000
- hotfix:
- mode: ContinuousDeployment
- label: beta
- increment: Patch
- track-merge-target: false
- regex: ^hotfix(es)?[/-]
- source-branches:
- - develop
- - main
- - support
- tracks-release-branches: false
- is-release-branch: false
- pre-release-weight: 30000
- support:
- mode: ContinuousDeployment
- label: ''
- increment: Patch
- track-merge-target: false
- regex: ^support[/-]
- source-branches:
- - main
- tracks-release-branches: false
- is-release-branch: false
- pre-release-weight: 55000
ignore:
sha: [ ]
merge-message-formats: { }
From 4b3e5c210c3f6668e25e7d90ad2770ef34f84e98 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:04:34 +0100
Subject: [PATCH 05/73] Update `GitVersion.yml` configuration for enhanced
semantic versioning
- Added `tag-prefix` and `semantic-version-format` properties for improved version tagging.
- Simplified branch definitions by removing unused branches (`develop`, `support`, `hotfix`).
- Adjusted `pull-request` label from `PullRequest` to `PR`.
---
GitVersion.yml | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/GitVersion.yml b/GitVersion.yml
index 6460f715..e554e6f6 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -1,5 +1,7 @@
assembly-versioning-scheme: MajorMinorPatch
assembly-file-versioning-scheme: MajorMinorPatchTag
+tag-prefix: '^v?'
+semantic-version-format: Loose
major-version-bump-message: '\+semver:\s?(breaking|major)'
minor-version-bump-message: '\+semver:\s?(feature|minor)'
patch-version-bump-message: '\+semver:\s?(fix|patch)'
@@ -36,26 +38,21 @@ branches:
track-merge-target: false
regex: ^releases?[/-]
source-branches:
- - develop
- main
- - support
- release
tracks-release-branches: false
is-release-branch: true
pre-release-weight: 30000
pull-request:
mode: ContinuousDeployment
- label: PullRequest
+ label: PR
increment: Inherit
track-merge-target: false
regex: ^(pull|pull\-requests|pr)[/-]
source-branches:
- - develop
- main
- release
- feature
- - support
- - hotfix
tracks-release-branches: false
is-release-branch: false
pre-release-weight: 30000
From f2f42af96a85d8c3b55e3f85addd43206f07a052 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:13:50 +0100
Subject: [PATCH 06/73] Enhance `CleanTask` to clean solution builds
- Implement `RunAsync` method, invoking `DotNetClean` and deleting `bin`/`obj` directories.
- Introduce private `DeleteDirectories` method to simplify directory cleanup logic with glob patterns and logging.
---
.../Tasks/Templates/CleanTask.cs | 29 +++++++++++++++++--
1 file changed, 27 insertions(+), 2 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
index bf4b0f9d..e70e1514 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -1,3 +1,28 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates;
+using Cake.Common.Diagnostics;
+using Cake.Common.Tools.DotNet;
+using Cake.Core.IO;
-public class CleanTask : FrostingTaskBase where T : BuildContext { }
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class CleanTask : FrostingTaskBase where T : BuildContext
+{
+ public override async Task RunAsync(T context)
+ {
+ context.DotNetClean(context.SolutionFile.FullPath);
+
+ DeleteDirectories(context, context.RootDir.FullPath + "/**/bin");
+ DeleteDirectories(context, context.RootDir.FullPath + "/**/obj");
+ }
+
+ private static void DeleteDirectories(T context, string globPattern)
+ {
+ var dirs = context.Globber.Match(globPattern).OfType();
+
+ foreach (var dir in dirs)
+ {
+ context.Information("Deleting directory '{0}'", dir);
+
+ context.FileSystem.GetDirectory(dir).Delete(true);
+ }
+ }
+}
From 74d58ea381b12c74bc01af0c7a8470c321f0eb88 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:14:19 +0100
Subject: [PATCH 07/73] Add missing `using` directives for `System.Linq` and
`System.Threading.Tasks` in `CleanTask`
---
.../CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
index e70e1514..6a8a1ef5 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -1,4 +1,6 @@
-using Cake.Common.Diagnostics;
+using System.Linq;
+using System.Threading.Tasks;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
using Cake.Core.IO;
From ce43349d8d2af4a2c9bdc246b056de1b145ad7bd Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:22:38 +0100
Subject: [PATCH 08/73] Add `HasExecutedTask` method to `BuildContext` and
integrate with `BuildTask` for conditional `NoRestore` handling
---
.../CreativeCoders.CakeBuild/BuildContext.cs | 11 ++++++++++-
.../Tasks/Templates/BuildTask.cs | 2 +-
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index f0c0bb6b..bed79e01 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -1,4 +1,8 @@
-using Cake.Common.Diagnostics;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.GitVersion;
using Cake.Core;
using Cake.Core.IO;
@@ -67,6 +71,11 @@ public void AddExecutedTask(IFrostingTask task)
_executedTasks.Add(task);
}
+ public bool HasExecutedTask(Type taskType)
+ {
+ return _executedTasks.Any(x => x.GetType().IsAssignableTo(taskType));
+ }
+
private DirectoryPath? FindGitRootPath(DirectoryPath? startPath)
{
while (true)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 5c5f568a..fc7b0c93 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -17,7 +17,7 @@ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
var dotNetBuildSettings = new DotNetBuildSettings
{
Configuration = context.BuildConfiguration,
- NoRestore = true,
+ NoRestore = context.HasExecutedTask(typeof(RestoreTask)),
MSBuildSettings = new DotNetMSBuildSettings
{
InformationalVersion = context.Version.InformationalVersion,
From d2204ca2c2a2303871d2fbd35fe89ec5c2e06148 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:23:02 +0100
Subject: [PATCH 09/73] Add missing `using System.Threading.Tasks` directive in
`BuildTask`
---
.../CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index fc7b0c93..3e9e8696 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -1,4 +1,5 @@
-using Cake.Common.Tools.DotNet;
+using System.Threading.Tasks;
+using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Build;
using Cake.Common.Tools.DotNet.MSBuild;
using Cake.Core.Diagnostics;
From 1fce0aa66f4d3380dc5c8fc8b7b76be667d0ac3b Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:23:27 +0100
Subject: [PATCH 10/73] Add missing `using System.Threading.Tasks` directive in
`RestoreTask`
---
.../CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
index c4ece690..e24f0be9 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
@@ -1,4 +1,5 @@
-using Cake.Common.Tools.DotNet;
+using System.Threading.Tasks;
+using Cake.Common.Tools.DotNet;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
From 39380ff6f709f8b4c5b0384e8f357e98eb047cf2 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 12:28:32 +0100
Subject: [PATCH 11/73] Log `NoRestore` setting in `BuildTask` for enhanced
diagnostics when skipping restores
---
.../CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 3e9e8696..b964f88e 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Build;
using Cake.Common.Tools.DotNet.MSBuild;
@@ -29,6 +30,11 @@ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
ApplyDotNetBuildSettings(context, dotNetBuildSettings);
+ if (dotNetBuildSettings.NoRestore)
+ {
+ context.Information("Skip restore");
+ }
+
return dotNetBuildSettings;
}
From cc302bde0d8adde9888f35f31c40c96cf8c844d7 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 16:06:35 +0100
Subject: [PATCH 12/73] Add settings interfaces for task templates and refactor
`BuildContext`
- Introduce settings interfaces for task templates (`ICleanTaskSettings`, `ITestTaskSettings`, etc.).
- Refactor `BuildContext` to enhance modularity and reuse of Git root path logic.
- Add `UseBuildSetup` integration to `CakeHost` for streamlined build setup logic.
---
samples/CakeBuildSample/BuildSetup.cs | 11 ++++
samples/CakeBuildSample/Program.cs | 1 +
.../CreativeCoders.CakeBuild/BuildContext.cs | 66 +++++++++----------
.../CakeHostExtensions.cs | 2 +
.../Tasks/Defaults/DefaultBuildSetup.cs | 5 ++
.../Tasks/Templates/Settings/IBuildPaths.cs | 34 ++++++++++
.../Templates/Settings/IBuildTaskSettings.cs | 3 +
.../Templates/Settings/ICakeBuildSettings.cs | 8 +++
.../Templates/Settings/ICleanTaskSettings.cs | 3 +
.../Settings/ICodeCoverageTaskSettings.cs | 3 +
.../Settings/INuGetPublishTaskSettings.cs | 3 +
.../Templates/Settings/IPackTaskSettings.cs | 6 ++
.../Templates/Settings/ITestTaskSettings.cs | 6 ++
13 files changed, 118 insertions(+), 33 deletions(-)
create mode 100644 samples/CakeBuildSample/BuildSetup.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/DefaultBuildSetup.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
diff --git a/samples/CakeBuildSample/BuildSetup.cs b/samples/CakeBuildSample/BuildSetup.cs
new file mode 100644
index 00000000..f5e725c5
--- /dev/null
+++ b/samples/CakeBuildSample/BuildSetup.cs
@@ -0,0 +1,11 @@
+using Cake.Core;
+using Cake.Core.IO;
+using CreativeCoders.CakeBuild.Tasks.Defaults;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+namespace CakeBuildSample;
+
+public class BuildSetup(ICakeContext context) : IDefaultBuildSetup
+{
+ public ICakeContext Context { get; } = context;
+}
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 557737fc..b8997b3c 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -10,6 +10,7 @@ static int Main(string[] args)
{
return new CakeHost()
.UseContext()
+ .UseBuildSetup()
.AddTask()
.AddTask()
.AddTask()
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index bed79e01..08ef4b6d 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -1,30 +1,18 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using Cake.Common.Diagnostics;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.GitVersion;
using Cake.Core;
using Cake.Core.IO;
using Cake.Frosting;
using CreativeCoders.Core.IO;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild;
+[PublicAPI]
public class BuildContext : FrostingContext
{
private readonly List _executedTasks = [];
- public FilePath SolutionFile { get; set; }
-
- public GitVersion Version { get; set; }
-
- public DirectoryPath RootDir { get; set; }
-
- public string BuildConfiguration { get; set; } = "Release";
-
- public IEnumerable ExecutedTasks => _executedTasks;
-
public BuildContext(ICakeContext context)
: base(context)
{
@@ -39,6 +27,24 @@ public BuildContext(ICakeContext context)
Version = context.GetGitVersionSafe();
}
+ private DirectoryPath? FindGitRootPath(DirectoryPath? startPath)
+ {
+ while (true)
+ {
+ if (startPath == null)
+ {
+ return null;
+ }
+
+ if (FileSystem.Exist(startPath.Combine(".git")))
+ {
+ return startPath;
+ }
+
+ startPath = startPath.GetParent();
+ }
+ }
+
private FilePath FindRootSolution(ICakeContext context)
{
var solutionsFiles =
@@ -66,6 +72,18 @@ private FilePath FindRootSolution(ICakeContext context)
return solution;
}
+ public FilePath SolutionFile { get; set; }
+
+ public GitVersion Version { get; set; }
+
+ public DirectoryPath RootDir { get; set; }
+
+ public DirectoryPath ArtifactsDir => RootDir.Combine(".artifacts");
+
+ public string BuildConfiguration { get; set; } = "Release";
+
+ public IList ExecutedTasks => _executedTasks;
+
public void AddExecutedTask(IFrostingTask task)
{
_executedTasks.Add(task);
@@ -75,22 +93,4 @@ public bool HasExecutedTask(Type taskType)
{
return _executedTasks.Any(x => x.GetType().IsAssignableTo(taskType));
}
-
- private DirectoryPath? FindGitRootPath(DirectoryPath? startPath)
- {
- while (true)
- {
- if (startPath == null)
- {
- return null;
- }
-
- if (FileSystem.Exist(startPath.Combine(".git")))
- {
- return startPath;
- }
-
- startPath = startPath.GetParent();
- }
- }
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
index 91656e1e..992b62c7 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -1,10 +1,12 @@
using System.Reflection;
using Cake.Frosting;
+using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace CreativeCoders.CakeBuild;
+[PublicAPI]
public static class CakeHostExtensions
{
public static CakeHost AddTask(this CakeHost host)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/DefaultBuildSetup.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/DefaultBuildSetup.cs
new file mode 100644
index 00000000..8b01cdf0
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/DefaultBuildSetup.cs
@@ -0,0 +1,5 @@
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+namespace CreativeCoders.CakeBuild.Tasks.Defaults;
+
+public interface IDefaultBuildSetup : IBuildPaths { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
new file mode 100644
index 00000000..0a938364
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
@@ -0,0 +1,34 @@
+using Cake.Core;
+using Cake.Core.IO;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface IBuildPaths : ICakeBuildSettings
+{
+ DirectoryPath RootDir => FindGitRootPath(Context.Environment.WorkingDirectory) ??
+ Context.Environment.WorkingDirectory.GetParent();
+
+ DirectoryPath ArtifactsDir => RootDir.Combine(".artifacts");
+
+ DirectoryPath TestOutputBasePath => RootDir.Combine(".tests");
+
+ DirectoryPath CodeCoverageResultsDir => TestOutputBasePath.Combine("coverage-results");
+
+ DirectoryPath? FindGitRootPath(DirectoryPath? startPath)
+ {
+ while (true)
+ {
+ if (startPath == null)
+ {
+ return null;
+ }
+
+ if (this.Context.FileSystem.Exist(startPath.Combine(".git")))
+ {
+ return startPath;
+ }
+
+ startPath = startPath.GetParent();
+ }
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
new file mode 100644
index 00000000..de5000a0
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface IBuildTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs
new file mode 100644
index 00000000..163a665c
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs
@@ -0,0 +1,8 @@
+using Cake.Core;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface ICakeBuildSettings
+{
+ ICakeContext Context { get; }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
new file mode 100644
index 00000000..dde55470
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface ICleanTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
new file mode 100644
index 00000000..b73dc58d
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface ICodeCoverageTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
new file mode 100644
index 00000000..068640e6
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
@@ -0,0 +1,3 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface INuGetPublishTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
new file mode 100644
index 00000000..34422095
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
@@ -0,0 +1,6 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface IPackTaskSettings
+{
+
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
new file mode 100644
index 00000000..c52c8325
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
@@ -0,0 +1,6 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+public interface ITestTaskSettings
+{
+
+}
From 1b9124d608b068f5b321c7a2de4fa978dba6aef7 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 20:18:53 +0100
Subject: [PATCH 13/73] - Fix null reference in `IBuildPaths` by removing
redundant `this` qualifier - Update `GitVersion.Tool` to version `6.5.1` in
build project dependencies
---
build/_build.csproj | 4 ++--
.../Tasks/Templates/Settings/IBuildPaths.cs | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/build/_build.csproj b/build/_build.csproj
index 3cd974b1..c76d93b9 100644
--- a/build/_build.csproj
+++ b/build/_build.csproj
@@ -13,8 +13,8 @@
-
-
+
+
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
index 0a938364..53371624 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
@@ -23,7 +23,7 @@ public interface IBuildPaths : ICakeBuildSettings
return null;
}
- if (this.Context.FileSystem.Exist(startPath.Combine(".git")))
+ if (Context.FileSystem.Exist(startPath.Combine(".git")))
{
return startPath;
}
From 2bc0074d0617260f18cf9a31402402a6ef9a0701 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 20:26:20 +0100
Subject: [PATCH 14/73] Update GitHub Actions workflow: bump `actions/checkout`
to v5 and adjust deploy step
- Upgraded `actions/checkout` to version 5 for compatibility.
- Commented out caching and artifact upload steps.
- Modified the `DeployNuGet` step to run a specific build command within the `CakeBuildSample` directory.
---
.github/workflows/integration.yml | 32 ++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index f35bc58e..37f32667 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -26,26 +26,28 @@ jobs:
name: ubuntu-latest
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v5
with:
fetch-depth: 0
- - name: 'Cache: .nuke/temp, ~/.nuget/packages'
- uses: actions/cache@v4
- with:
- path: |
- .nuke/temp
- ~/.nuget/packages
- key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
+ # - name: 'Cache: .nuke/temp, ~/.nuget/packages'
+ # uses: actions/cache@v4
+ # with:
+ # path: |
+ # .nuke/temp
+ # ~/.nuget/packages
+ # key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- name: 'Run: DeployNuGet'
- run: ./build.cmd DeployNuGet
+ run: |
+ cd ./samples/CakeBuildSample
+ dotnet run -- -t build
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: 'Publish: coverage_report'
- uses: actions/upload-artifact@v4
- if: runner.os == 'Linux'
- with:
- name: coverage_report
- path: .tests/coverage_report
+ # - name: 'Publish: coverage_report'
+ # uses: actions/upload-artifact@v4
+ # if: runner.os == 'Linux'
+ # with:
+ # name: coverage_report
+ # path: .tests/coverage_report
windows-latest:
name: windows-latest
runs-on: windows-latest
From 847a987e809bbd076aa0f82743325a1f5e5d5ea1 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 20:31:35 +0100
Subject: [PATCH 15/73] Comment out Windows and macOS jobs in GitHub Actions
workflow and remove redundant configuration in solution file.
---
.github/workflows/integration.yml | 96 +++++++++++++++----------------
Core.sln | 1 -
2 files changed, 48 insertions(+), 49 deletions(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 37f32667..6ddd192a 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -48,51 +48,51 @@ jobs:
# with:
# name: coverage_report
# path: .tests/coverage_report
- windows-latest:
- name: windows-latest
- runs-on: windows-latest
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: 'Cache: .nuke/temp, ~/.nuget/packages'
- uses: actions/cache@v4
- with:
- path: |
- .nuke/temp
- ~/.nuget/packages
- key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- - name: 'Run: DeployNuGet'
- run: ./build.cmd DeployNuGet
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: 'Publish: coverage_report'
- uses: actions/upload-artifact@v4
- if: runner.os == 'Linux'
- with:
- name: coverage_report
- path: .tests/coverage_report
- macos-latest:
- name: macos-latest
- runs-on: macos-latest
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: 'Cache: .nuke/temp, ~/.nuget/packages'
- uses: actions/cache@v4
- with:
- path: |
- .nuke/temp
- ~/.nuget/packages
- key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- - name: 'Run: DeployNuGet'
- run: ./build.cmd DeployNuGet
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: 'Publish: coverage_report'
- uses: actions/upload-artifact@v4
- if: runner.os == 'Linux'
- with:
- name: coverage_report
- path: .tests/coverage_report
+# windows-latest:
+# name: windows-latest
+# runs-on: windows-latest
+# steps:
+# - uses: actions/checkout@v4
+# with:
+# fetch-depth: 0
+# - name: 'Cache: .nuke/temp, ~/.nuget/packages'
+# uses: actions/cache@v4
+# with:
+# path: |
+# .nuke/temp
+# ~/.nuget/packages
+# key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
+# - name: 'Run: DeployNuGet'
+# run: ./build.cmd DeployNuGet
+# env:
+# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+# - name: 'Publish: coverage_report'
+# uses: actions/upload-artifact@v4
+# if: runner.os == 'Linux'
+# with:
+# name: coverage_report
+# path: .tests/coverage_report
+# macos-latest:
+# name: macos-latest
+# runs-on: macos-latest
+# steps:
+# - uses: actions/checkout@v4
+# with:
+# fetch-depth: 0
+# - name: 'Cache: .nuke/temp, ~/.nuget/packages'
+# uses: actions/cache@v4
+# with:
+# path: |
+# .nuke/temp
+# ~/.nuget/packages
+# key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
+# - name: 'Run: DeployNuGet'
+# run: ./build.cmd DeployNuGet
+# env:
+# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+# - name: 'Publish: coverage_report'
+# uses: actions/upload-artifact@v4
+# if: runner.os == 'Linux'
+# with:
+# name: coverage_report
+# path: .tests/coverage_report
diff --git a/Core.sln b/Core.sln
index da034e61..60e35041 100644
--- a/Core.sln
+++ b/Core.sln
@@ -583,7 +583,6 @@ Global
{EB88412B-8523-4DA4-8FF9-CACECA0969E6}.Release|Any CPU.Build.0 = Release|Any CPU
{58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {58C01CB8-B65A-44FE-9BE0-22929CD474A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
From a0e22be6ea7115cd62fb3add9711aadab9e9a3b2 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 20:47:06 +0100
Subject: [PATCH 16/73] Add `CakeTaskSettings` attribute for task settings
interfaces and enhance `CakeHost` with settings support
- Introduced `[CakeTaskSettings]` attribute to annotate task settings interfaces.
- Refactored `CakeHost.UseBuildSetup` to inject and register task-specific settings interfaces.
- Added missing `using` directives and improved modularity in task setup.
---
.../CreativeCoders.CakeBuild/BuildContext.cs | 6 +++-
.../CakeHostExtensions.cs | 32 ++++++++++++-------
.../Settings/CakeTaskSettingsAttribute.cs | 6 ++++
.../Tasks/Templates/Settings/IBuildPaths.cs | 1 +
.../Templates/Settings/IBuildTaskSettings.cs | 1 +
.../Templates/Settings/ICleanTaskSettings.cs | 1 +
.../Settings/ICodeCoverageTaskSettings.cs | 1 +
.../Settings/INuGetPublishTaskSettings.cs | 1 +
.../Templates/Settings/IPackTaskSettings.cs | 6 ++--
.../Templates/Settings/ITestTaskSettings.cs | 6 ++--
10 files changed, 41 insertions(+), 20 deletions(-)
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index 08ef4b6d..d32e26fd 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -1,4 +1,8 @@
-using Cake.Common.Diagnostics;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.GitVersion;
using Cake.Core;
using Cake.Core.IO;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
index 992b62c7..527f9a4a 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -1,5 +1,7 @@
-using System.Reflection;
+using System;
+using System.Reflection;
using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
@@ -53,20 +55,28 @@ public static CakeHost AddTasks(this CakeHost host, params Type[] taskTypes)
public static CakeHost UseBuildSetup(this CakeHost host)
where TBuildSetup : class
{
- host.ConfigureServices(services => services.AddSingleton());
+ host.ConfigureServices(services =>
+ {
+ services.AddSingleton();
+ services.AddSettingsInterfacesFor(typeof(TBuildSetup), typeof(TBuildSetup));
+ });
+
+ return host;
+ }
- foreach (var propertyInfo in typeof(TBuildSetup).GetProperties(BindingFlags.Public |
- BindingFlags.Instance))
+ private static void AddSettingsInterfacesFor(this IServiceCollection services, Type type,
+ Type buildSetupType)
+ {
+ var interfaceTypes = type.GetInterfaces();
+
+ foreach (var interfaceType in interfaceTypes)
{
- host.ConfigureServices(services => services.AddSingleton(propertyInfo.PropertyType, sp =>
+ if (interfaceType.GetCustomAttribute() is not null)
{
- var buildSetup = sp.GetRequiredService();
+ services.AddSingleton(interfaceType, sp => sp.GetRequiredService(buildSetupType));
+ }
- return propertyInfo.GetValue(buildSetup) ?? throw new InvalidOperationException(
- $"Property '{propertyInfo.Name}' of BuildSetup '{typeof(TBuildSetup).FullName}' is null.");
- }));
+ services.AddSettingsInterfacesFor(interfaceType, buildSetupType);
}
-
- return host;
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs
new file mode 100644
index 00000000..5a6f0f65
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs
@@ -0,0 +1,6 @@
+using System;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+[AttributeUsage(AttributeTargets.Interface)]
+public class CakeTaskSettingsAttribute : Attribute { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
index 53371624..bef35644 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
@@ -3,6 +3,7 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+[CakeTaskSettings]
public interface IBuildPaths : ICakeBuildSettings
{
DirectoryPath RootDir => FindGitRootPath(Context.Environment.WorkingDirectory) ??
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
index de5000a0..b003e980 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
@@ -1,3 +1,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+[CakeTaskSettings]
public interface IBuildTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
index dde55470..b33ab2e7 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
@@ -1,3 +1,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+[CakeTaskSettings]
public interface ICleanTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
index b73dc58d..d071fc3b 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
@@ -1,3 +1,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+[CakeTaskSettings]
public interface ICodeCoverageTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
index 068640e6..8f76aee6 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
@@ -1,3 +1,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+[CakeTaskSettings]
public interface INuGetPublishTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
index 34422095..b6774f0a 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
@@ -1,6 +1,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-public interface IPackTaskSettings
-{
-
-}
+[CakeTaskSettings]
+public interface IPackTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
index c52c8325..b51444f0 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
@@ -1,6 +1,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-public interface ITestTaskSettings
-{
-
-}
+[CakeTaskSettings]
+public interface ITestTaskSettings { }
From 59a15a6bc8bb8eb3a6e44d70cffd3a7631b263b3 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 20:53:08 +0100
Subject: [PATCH 17/73] Set terminal environment variables in GitHub Actions
for improved console output rendering
---
.github/workflows/integration.yml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 6ddd192a..1394b372 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -25,6 +25,9 @@ jobs:
ubuntu-latest:
name: ubuntu-latest
runs-on: ubuntu-latest
+ env:
+ TERM: xterm
+ DOTNET_SYSTEM_CONSOLE_ALLOW_ANSI_COLOR_REDIRECTION: 1
steps:
- uses: actions/checkout@v5
with:
From 2425ec0e2bdbe574fbce1264089693cead2b3c9c Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 21:02:37 +0100
Subject: [PATCH 18/73] Add task setup and teardown for better grouping in Cake
Frosting builds
- Introduced `SomeTaskSetup` and `SomeTaskTeardown` to handle task-specific logic.
- Integrated GitHub Actions group commands for improved build log readability.
---
samples/CakeBuildSample/Program.cs | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index b8997b3c..07ceeef2 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,4 +1,6 @@
-using Cake.Frosting;
+using Cake.Common.Build;
+using Cake.Core;
+using Cake.Frosting;
using CreativeCoders.CakeBuild;
using CreativeCoders.CakeBuild.Tasks.Defaults;
@@ -14,6 +16,24 @@ static int Main(string[] args)
.AddTask()
.AddTask()
.AddTask()
+ .UseTaskSetup()
+ .UseTaskTeardown()
.Run(args);
}
}
+
+public class SomeTaskTeardown : IFrostingTaskTeardown
+{
+ void IFrostingTaskTeardown.Teardown(ICakeContext context, ITaskTeardownContext info)
+ {
+ context.GitHubActions().Commands.EndGroup();
+ }
+}
+
+public class SomeTaskSetup : IFrostingTaskSetup
+{
+ void IFrostingTaskSetup.Setup(ICakeContext context, ITaskSetupContext info)
+ {
+ context.GitHubActions().Commands.StartGroup(info.Task.Name);
+ }
+}
From a6dadcb72def797396692655bb80230baca9c221 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 21:05:41 +0100
Subject: [PATCH 19/73] Refactor `CleanTask` to reorder `DotNetClean` after
directory deletions
---
.../CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
index 6a8a1ef5..77575e00 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -10,10 +10,10 @@ public class CleanTask : FrostingTaskBase where T : BuildContext
{
public override async Task RunAsync(T context)
{
- context.DotNetClean(context.SolutionFile.FullPath);
-
DeleteDirectories(context, context.RootDir.FullPath + "/**/bin");
DeleteDirectories(context, context.RootDir.FullPath + "/**/obj");
+
+ context.DotNetClean(context.SolutionFile.FullPath);
}
private static void DeleteDirectories(T context, string globPattern)
From 94424d68358b39c25c392a1fa357b613515d89d2 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 21:08:07 +0100
Subject: [PATCH 20/73] Add information logging to task setup in
`SomeTaskSetup`
---
samples/CakeBuildSample/Program.cs | 2 ++
1 file changed, 2 insertions(+)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 07ceeef2..74a04a49 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,4 +1,5 @@
using Cake.Common.Build;
+using Cake.Common.Diagnostics;
using Cake.Core;
using Cake.Frosting;
using CreativeCoders.CakeBuild;
@@ -34,6 +35,7 @@ public class SomeTaskSetup : IFrostingTaskSetup
{
void IFrostingTaskSetup.Setup(ICakeContext context, ITaskSetupContext info)
{
+ context.Information("");
context.GitHubActions().Commands.StartGroup(info.Task.Name);
}
}
From 1405df86a2f8e02b521467cc6c46f5b839ff2fc3 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 3 Jan 2026 21:31:49 +0100
Subject: [PATCH 21/73] Refactor `CakeHost` to simplify task setup and
integrate build server functionality
- Added `SetupHost`, `AddDefaultTasks`, and `AddBuildServerIntegration` extension methods to streamline configuration.
- Replaced custom task setup and teardown (`SomeTaskSetup` and `SomeTaskTeardown`) with reusable GitHub Actions integrations (`StartGroupTaskSetup` and `EndGroupTaskTeardown`).
- Updated `CakeBuildSample` to utilize new streamlined APIs.
---
samples/CakeBuildSample/Program.cs | 33 +++----------------
.../BuildServer/EndGroupTaskTeardown.cs | 18 ++++++++++
.../BuildServer/StartGroupTaskSetup.cs | 20 +++++++++++
.../CakeHostExtensions.cs | 32 +++++++++++++++++-
...ultBuildSetup.cs => IDefaultBuildSetup.cs} | 0
5 files changed, 73 insertions(+), 30 deletions(-)
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs
rename source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/{DefaultBuildSetup.cs => IDefaultBuildSetup.cs} (100%)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 74a04a49..d500b4b8 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,9 +1,5 @@
-using Cake.Common.Build;
-using Cake.Common.Diagnostics;
-using Cake.Core;
-using Cake.Frosting;
+using Cake.Frosting;
using CreativeCoders.CakeBuild;
-using CreativeCoders.CakeBuild.Tasks.Defaults;
namespace CakeBuildSample;
@@ -12,30 +8,9 @@ internal static class Program
static int Main(string[] args)
{
return new CakeHost()
- .UseContext()
- .UseBuildSetup()
- .AddTask()
- .AddTask()
- .AddTask()
- .UseTaskSetup()
- .UseTaskTeardown()
+ .SetupHost()
+ .AddDefaultTasks()
+ .AddBuildServerIntegration()
.Run(args);
}
}
-
-public class SomeTaskTeardown : IFrostingTaskTeardown
-{
- void IFrostingTaskTeardown.Teardown(ICakeContext context, ITaskTeardownContext info)
- {
- context.GitHubActions().Commands.EndGroup();
- }
-}
-
-public class SomeTaskSetup : IFrostingTaskSetup
-{
- void IFrostingTaskSetup.Setup(ICakeContext context, ITaskSetupContext info)
- {
- context.Information("");
- context.GitHubActions().Commands.StartGroup(info.Task.Name);
- }
-}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
new file mode 100644
index 00000000..c4c7d292
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
@@ -0,0 +1,18 @@
+using Cake.Common.Build;
+using Cake.Core;
+using Cake.Frosting;
+using JetBrains.Annotations;
+
+namespace CreativeCoders.CakeBuild.BuildServer;
+
+[UsedImplicitly]
+public class EndGroupTaskTeardown : IFrostingTaskTeardown
+{
+ void IFrostingTaskTeardown.Teardown(ICakeContext context, ITaskTeardownContext info)
+ {
+ if (context.GitHubActions().IsRunningOnGitHubActions)
+ {
+ context.GitHubActions().Commands.EndGroup();
+ }
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs
new file mode 100644
index 00000000..f667ad82
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs
@@ -0,0 +1,20 @@
+using Cake.Common.Build;
+using Cake.Common.Diagnostics;
+using Cake.Core;
+using Cake.Frosting;
+using JetBrains.Annotations;
+
+namespace CreativeCoders.CakeBuild.BuildServer;
+
+[UsedImplicitly]
+public class StartGroupTaskSetup : IFrostingTaskSetup
+{
+ void IFrostingTaskSetup.Setup(ICakeContext context, ITaskSetupContext info)
+ {
+ if (context.GitHubActions().IsRunningOnGitHubActions)
+ {
+ context.Information("");
+ context.GitHubActions().Commands.StartGroup(info.Task.Name);
+ }
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
index 527f9a4a..64a3090b 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -1,6 +1,8 @@
using System;
using System.Reflection;
using Cake.Frosting;
+using CreativeCoders.CakeBuild.BuildServer;
+using CreativeCoders.CakeBuild.Tasks.Defaults;
using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
@@ -52,7 +54,35 @@ public static CakeHost AddTasks(this CakeHost host, params Type[] taskTypes)
});
}
- public static CakeHost UseBuildSetup(this CakeHost host)
+ public static CakeHost AddDefaultTasks(this CakeHost host)
+ {
+ return host.AddTasks(
+ typeof(CleanTask),
+ typeof(RestoreTask),
+ typeof(BuildTask),
+ typeof(TestTask),
+ typeof(CodeCoverageTask),
+ typeof(PackTask),
+ typeof(NuGetPublishTask));
+ }
+
+ public static CakeHost AddBuildServerIntegration(this CakeHost host)
+ {
+ return host
+ .UseTaskSetup()
+ .UseTaskTeardown();
+ }
+
+ public static CakeHost SetupHost(this CakeHost host)
+ where TBuildSetup : class
+ where TBuildContext : BuildContext
+ {
+ return host
+ .UseContext()
+ .UseBuildSetup();
+ }
+
+ private static CakeHost UseBuildSetup(this CakeHost host)
where TBuildSetup : class
{
host.ConfigureServices(services =>
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/DefaultBuildSetup.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultBuildSetup.cs
similarity index 100%
rename from source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/DefaultBuildSetup.cs
rename to source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultBuildSetup.cs
From 5239b44a5139e17650e7d5482e77bb218c47bb89 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sun, 4 Jan 2026 12:00:48 +0100
Subject: [PATCH 22/73] Fix typo in `Ensure.cs` and add `ICakeHostBuilder`
implementation for streamlined Cake build setup
- Corrected `UnkownParamName` to `UnknownParamName` across all methods in `Ensure.cs`.
- Introduced `ICakeHostBuilder` interface and its implementation, `CakeHostBuilder`, for simplifying Cake build configuration.
- Updated `CakeHostExtensions` and `CakeBuildSample` to leverage the new `CakeHostBuilder`.
---
samples/CakeBuildSample/Program.cs | 8 +-
.../CakeHostBuilder.cs | 82 +++++++++++++++++++
.../CakeHostExtensions.cs | 4 +-
.../ICakeHostBuilder.cs | 25 ++++++
source/Core/CreativeCoders.Core/Ensure.cs | 28 +++----
5 files changed, 128 insertions(+), 19 deletions(-)
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index d500b4b8..7de2858e 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,5 +1,4 @@
-using Cake.Frosting;
-using CreativeCoders.CakeBuild;
+using CreativeCoders.CakeBuild;
namespace CakeBuildSample;
@@ -7,10 +6,11 @@ internal static class Program
{
static int Main(string[] args)
{
- return new CakeHost()
- .SetupHost()
+ return CakeHostBuilder.Create()
+ .UseBuildSetup()
.AddDefaultTasks()
.AddBuildServerIntegration()
+ .Build()
.Run(args);
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs
new file mode 100644
index 00000000..beb885d5
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs
@@ -0,0 +1,82 @@
+using Cake.Frosting;
+using CreativeCoders.Core;
+
+namespace CreativeCoders.CakeBuild;
+
+public class CakeHostBuilder : ICakeHostBuilder
+{
+ private readonly CakeHost _cakeHost = new CakeHost();
+
+ private bool _buildContextIsSet;
+
+ public static ICakeHostBuilder Create()
+ {
+ return new CakeHostBuilder();
+ }
+
+ public ICakeHostBuilder UseBuildContext()
+ where TBuildContext : BuildContext
+ {
+ _buildContextIsSet = true;
+
+ _cakeHost.UseContext();
+
+ return this;
+ }
+
+ public ICakeHostBuilder UseBuildSetup()
+ where TBuildSetup : class
+ {
+ _cakeHost.UseBuildSetup();
+
+ return this;
+ }
+
+ public ICakeHostBuilder AddBuildServerIntegration()
+ {
+ _cakeHost.AddBuildServerIntegration();
+
+ return this;
+ }
+
+ public ICakeHostBuilder AddDefaultTasks()
+ {
+ _cakeHost.AddDefaultTasks();
+
+ return this;
+ }
+
+ public ICakeHostBuilder AddTask()
+ where TTask : class, IFrostingTask
+ {
+ _cakeHost.AddTask();
+
+ return this;
+ }
+
+ public ICakeHostBuilder AddTasks(params Type[] taskTypes)
+ {
+ _cakeHost.AddTasks(taskTypes);
+
+ return this;
+ }
+
+ public ICakeHostBuilder ConfigureHost(Action configure)
+ {
+ Ensure.NotNull(configure);
+
+ configure(_cakeHost);
+
+ return this;
+ }
+
+ public CakeHost Build()
+ {
+ if (!_buildContextIsSet)
+ {
+ _cakeHost.UseContext();
+ }
+
+ return _cakeHost;
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
index 64a3090b..adc09ea3 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -16,6 +16,8 @@ public static class CakeHostExtensions
public static CakeHost AddTask(this CakeHost host)
where TTask : class, IFrostingTask
{
+ ArgumentNullException.ThrowIfNull(host);
+
return host.ConfigureServices(x => x.AddSingleton());
}
@@ -82,7 +84,7 @@ public static CakeHost SetupHost(this CakeHost host)
.UseBuildSetup();
}
- private static CakeHost UseBuildSetup(this CakeHost host)
+ public static CakeHost UseBuildSetup(this CakeHost host)
where TBuildSetup : class
{
host.ConfigureServices(services =>
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs b/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs
new file mode 100644
index 00000000..c434be80
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs
@@ -0,0 +1,25 @@
+using Cake.Frosting;
+
+namespace CreativeCoders.CakeBuild;
+
+public interface ICakeHostBuilder
+{
+ ICakeHostBuilder AddBuildServerIntegration();
+
+ ICakeHostBuilder AddDefaultTasks();
+
+ ICakeHostBuilder AddTask()
+ where TTask : class, IFrostingTask;
+
+ ICakeHostBuilder AddTasks(params Type[] taskTypes);
+
+ ICakeHostBuilder ConfigureHost(Action configure);
+
+ ICakeHostBuilder UseBuildContext()
+ where TBuildContext : BuildContext;
+
+ ICakeHostBuilder UseBuildSetup()
+ where TBuildSetup : class;
+
+ CakeHost Build();
+}
diff --git a/source/Core/CreativeCoders.Core/Ensure.cs b/source/Core/CreativeCoders.Core/Ensure.cs
index 78215ee5..883c23a5 100644
--- a/source/Core/CreativeCoders.Core/Ensure.cs
+++ b/source/Core/CreativeCoders.Core/Ensure.cs
@@ -17,7 +17,7 @@ namespace CreativeCoders.Core;
[PublicAPI]
public static class Ensure
{
- private const string UnkownParamName = "[unknown]";
+ private const string UnknownParamName = "[unknown]";
///-------------------------------------------------------------------------------------------------
/// Ensures that is not null.
@@ -35,7 +35,7 @@ public static class Ensure
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[return: System.Diagnostics.CodeAnalysis.NotNull]
public static T NotNull([System.Diagnostics.CodeAnalysis.NotNull] [NoEnumeration] T? value,
- [CallerArgumentExpression("value")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("value")] string paramName = UnknownParamName)
{
return value ?? throw new ArgumentNullException(paramName);
}
@@ -43,7 +43,7 @@ public static T NotNull([System.Diagnostics.CodeAnalysis.NotNull] [NoEnumerat
[ContractAnnotation("value: null => halt")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotNull([System.Diagnostics.CodeAnalysis.NotNull] [NoEnumeration] object? value,
- [CallerArgumentExpression("value")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("value")] string paramName = UnknownParamName)
{
if (value is null)
{
@@ -84,7 +84,7 @@ public static void IsNotNull([System.Diagnostics.CodeAnalysis.NotNull] [NoEnu
[ContractAnnotation("halt <= value: null; value: notnull => notnull")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string IsNotNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNull] string? value,
- [CallerArgumentExpression("value")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("value")] string paramName = UnknownParamName)
{
return string.IsNullOrEmpty(value)
? throw new ArgumentException("Must not be null or empty", paramName)
@@ -104,7 +104,7 @@ public static string IsNotNullOrEmpty([System.Diagnostics.CodeAnalysis.NotNull]
[ContractAnnotation("halt <= value: null")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IsNotNullOrEmpty(IEnumerable? value,
- [CallerArgumentExpression("value")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("value")] string paramName = UnknownParamName)
{
if (value == null || !value.Any())
{
@@ -126,7 +126,7 @@ public static void IsNotNullOrEmpty(IEnumerable? value,
[ContractAnnotation("halt <= value: null; value: notnull => notnull")]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string IsNotNullOrWhitespace(string? value,
- [CallerArgumentExpression("value")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("value")] string paramName = UnknownParamName)
{
return string.IsNullOrWhiteSpace(value)
? throw new ArgumentException("Must not be null or whitespace", paramName)
@@ -143,7 +143,7 @@ public static string IsNotNullOrWhitespace(string? value,
/// Name of the parameter.
/// -------------------------------------------------------------------------------------------------
public static void FileExists(string? fileName,
- [CallerArgumentExpression("fileName")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("fileName")] string paramName = UnknownParamName)
{
if (!FileSys.File.Exists(fileName))
{
@@ -165,7 +165,7 @@ public static void FileExists(string? fileName,
///-------------------------------------------------------------------------------------------------
public static void DirectoryExists(string? directoryName,
[CallerArgumentExpression("directoryName")]
- string paramName = UnkownParamName)
+ string paramName = UnknownParamName)
{
if (!FileSys.Directory.Exists(directoryName))
{
@@ -184,7 +184,7 @@ public static void DirectoryExists(string? directoryName,
///-------------------------------------------------------------------------------------------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void GuidIsNotEmpty(Guid guid,
- [CallerArgumentExpression("guid")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("guid")] string paramName = UnknownParamName)
{
if (guid.Equals(Guid.Empty))
{
@@ -202,7 +202,7 @@ public static void GuidIsNotEmpty(Guid guid,
public static void That(bool condition,
string message = "Assertion failed",
[CallerArgumentExpression("condition")]
- string paramName = UnkownParamName)
+ string paramName = UnknownParamName)
{
if (!condition)
{
@@ -223,7 +223,7 @@ public static void That(bool condition,
public static void ThatRange(bool condition,
string message = "Assertion failed",
[CallerArgumentExpression("condition")]
- string paramName = UnkownParamName)
+ string paramName = UnknownParamName)
{
if (!condition)
{
@@ -246,7 +246,7 @@ public static void ThatRange(bool condition,
///-------------------------------------------------------------------------------------------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IndexIsInRange(int index, int startIndex, int endIndex,
- [CallerArgumentExpression("index")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("index")] string paramName = UnknownParamName)
{
if (index < startIndex || index > endIndex)
{
@@ -269,7 +269,7 @@ public static void IndexIsInRange(int index, int startIndex, int endIndex,
///-------------------------------------------------------------------------------------------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void IndexIsInRange(int index, int collectionLength,
- [CallerArgumentExpression("index")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("index")] string paramName = UnknownParamName)
{
if (index < 0 || index >= collectionLength)
{
@@ -289,7 +289,7 @@ public static void IndexIsInRange(int index, int collectionLength,
///-------------------------------------------------------------------------------------------------
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Argument Argument(T? value,
- [CallerArgumentExpression("value")] string paramName = UnkownParamName)
+ [CallerArgumentExpression("value")] string paramName = UnknownParamName)
{
return new Argument(value, paramName);
}
From 9c8f44301b1efae29c6719f5b0866374eef2f36e Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sun, 4 Jan 2026 12:08:24 +0100
Subject: [PATCH 23/73] Clean up unused and redundant package references in
Blazor and TokenAuthApi projects
---
.../BlazorWebAssemblySampleApp.csproj | 7 +++----
.../CreativeCoders.AspNetCore.TokenAuthApi.csproj | 4 ----
2 files changed, 3 insertions(+), 8 deletions(-)
diff --git a/samples/BlazorWebAssemblySampleApp/BlazorWebAssemblySampleApp.csproj b/samples/BlazorWebAssemblySampleApp/BlazorWebAssemblySampleApp.csproj
index 686eabe4..3fc58281 100644
--- a/samples/BlazorWebAssemblySampleApp/BlazorWebAssemblySampleApp.csproj
+++ b/samples/BlazorWebAssemblySampleApp/BlazorWebAssemblySampleApp.csproj
@@ -5,10 +5,9 @@
-
-
-
-
+
+
+
diff --git a/source/AspNetCore/CreativeCoders.AspNetCore.TokenAuthApi/CreativeCoders.AspNetCore.TokenAuthApi.csproj b/source/AspNetCore/CreativeCoders.AspNetCore.TokenAuthApi/CreativeCoders.AspNetCore.TokenAuthApi.csproj
index 09f4151b..63c40571 100644
--- a/source/AspNetCore/CreativeCoders.AspNetCore.TokenAuthApi/CreativeCoders.AspNetCore.TokenAuthApi.csproj
+++ b/source/AspNetCore/CreativeCoders.AspNetCore.TokenAuthApi/CreativeCoders.AspNetCore.TokenAuthApi.csproj
@@ -10,10 +10,6 @@
-
-
-
-
From 4805f33a36a187de550b956502d65e869de6b569 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 12:45:42 +0100
Subject: [PATCH 24/73] Refactor build context and task settings for enhanced
modularity and flexibility
- Removed redundant interfaces (`IDefaultBuildSetup`, `IBuildPaths`, `ICakeBuildSettings`, etc.).
- Introduced `IBuildContext` and `IBuildContextAccessor` to centralize build context management.
- Updated `CleanTask` and `BuildTask` to leverage `ICleanTaskSettings`, improving task-specific configuration.
- Refactored `BuildContext` to streamline directory and configuration management.
- Simplified sample project setup using the new `SampleBuildContext`.
---
samples/CakeBuildSample/BuildSetup.cs | 11 -----
samples/CakeBuildSample/Program.cs | 3 +-
samples/CakeBuildSample/SampleBuildContext.cs | 17 +++++++
.../CreativeCoders.CakeBuild/BuildContext.cs | 46 +++++++++++++++----
.../CakeHostExtensions.cs | 3 +-
.../CreativeCoders.CakeBuild/IBuildContext.cs | 32 +++++++++++++
.../IBuildContextAccessor.cs | 6 +++
...tBuildSetup.cs => IDefaultTaskSettings.cs} | 2 +-
.../Tasks/Templates/BuildTask.cs | 9 +---
.../Tasks/Templates/CleanTask.cs | 20 ++++----
.../Tasks/Templates/RestoreTask.cs | 3 +-
.../Settings/CakeTaskSettingsAttribute.cs | 2 -
.../Tasks/Templates/Settings/IBuildPaths.cs | 35 --------------
.../Templates/Settings/IBuildTaskSettings.cs | 4 --
.../Templates/Settings/ICakeBuildSettings.cs | 8 ----
.../Templates/Settings/ICleanTaskSettings.cs | 39 +++++++++++++++-
.../CreativeCoders.Core/ObjectExtensions.cs | 2 +
17 files changed, 148 insertions(+), 94 deletions(-)
delete mode 100644 samples/CakeBuildSample/BuildSetup.cs
create mode 100644 samples/CakeBuildSample/SampleBuildContext.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/IBuildContextAccessor.cs
rename source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/{IDefaultBuildSetup.cs => IDefaultTaskSettings.cs} (63%)
delete mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
delete mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
delete mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs
diff --git a/samples/CakeBuildSample/BuildSetup.cs b/samples/CakeBuildSample/BuildSetup.cs
deleted file mode 100644
index f5e725c5..00000000
--- a/samples/CakeBuildSample/BuildSetup.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Cake.Core;
-using Cake.Core.IO;
-using CreativeCoders.CakeBuild.Tasks.Defaults;
-using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-
-namespace CakeBuildSample;
-
-public class BuildSetup(ICakeContext context) : IDefaultBuildSetup
-{
- public ICakeContext Context { get; } = context;
-}
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 7de2858e..8889b782 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,4 +1,5 @@
using CreativeCoders.CakeBuild;
+using CreativeCoders.CakeBuild.Tasks.Defaults;
namespace CakeBuildSample;
@@ -7,7 +8,7 @@ internal static class Program
static int Main(string[] args)
{
return CakeHostBuilder.Create()
- .UseBuildSetup()
+ .UseBuildContext()
.AddDefaultTasks()
.AddBuildServerIntegration()
.Build()
diff --git a/samples/CakeBuildSample/SampleBuildContext.cs b/samples/CakeBuildSample/SampleBuildContext.cs
new file mode 100644
index 00000000..2ad66c5c
--- /dev/null
+++ b/samples/CakeBuildSample/SampleBuildContext.cs
@@ -0,0 +1,17 @@
+using Cake.Core;
+using Cake.Core.IO;
+using CreativeCoders.CakeBuild;
+using CreativeCoders.CakeBuild.Tasks.Defaults;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+using CreativeCoders.Core;
+using CreativeCoders.Core.Collections;
+
+namespace CakeBuildSample;
+
+public class SampleBuildContext : BuildContext, IDefaultTaskSettings
+{
+ public SampleBuildContext(ICakeContext context) : base(context) { }
+
+ IList ICleanTaskSettings.DirectoriesToClean =>
+ this.CastAs().DefaultDirectoriesToClean.AddRange(RootDir.Combine(".tests"));
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index d32e26fd..6ff7d070 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -1,19 +1,17 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
+using Cake.Common.Build;
using Cake.Common.Diagnostics;
using Cake.Common.Tools.GitVersion;
using Cake.Core;
using Cake.Core.IO;
using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using CreativeCoders.Core.IO;
using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild;
[PublicAPI]
-public class BuildContext : FrostingContext
+public class BuildContext : FrostingContext, IBuildContext, IBuildContextAccessor
{
private readonly List _executedTasks = [];
@@ -76,15 +74,19 @@ private FilePath FindRootSolution(ICakeContext context)
return solution;
}
- public FilePath SolutionFile { get; set; }
+ public FilePath SolutionFile { get; }
- public GitVersion Version { get; set; }
+ public DirectoryPath RootDir { get; }
- public DirectoryPath RootDir { get; set; }
+ public virtual DirectoryPath ArtifactsDir => RootDir.Combine(".artifacts");
- public DirectoryPath ArtifactsDir => RootDir.Combine(".artifacts");
+ public virtual DirectoryPath TestOutputBasePath => RootDir.Combine(".tests");
- public string BuildConfiguration { get; set; } = "Release";
+ public virtual DirectoryPath CodeCoverageResultsDir => TestOutputBasePath.Combine("coverage-results");
+
+ public virtual string BuildConfiguration => this.BuildSystem().IsLocalBuild ? "Debug" : "Release";
+
+ public GitVersion Version { get; }
public IList ExecutedTasks => _executedTasks;
@@ -97,4 +99,28 @@ public bool HasExecutedTask(Type taskType)
{
return _executedTasks.Any(x => x.GetType().IsAssignableTo(taskType));
}
+
+ public T GetSettings() where T : class
+ {
+ return this as T
+ ?? FindSettingsProperty()
+ ?? throw new InvalidOperationException($"No settings of type '{typeof(T).Name}' found");
+ }
+
+ private T? FindSettingsProperty()
+ where T : class
+ {
+ var matchingProperties = GetType()
+ .GetProperties()
+ .Where(x => x.PropertyType == typeof(T) ||
+ x.PropertyType.GetInterfaces().Any(intfType =>
+ intfType == typeof(T)));
+
+ return matchingProperties
+ .Select(x => x.GetValue(this))
+ .OfType()
+ .FirstOrDefault();
+ }
+
+ public IBuildContext Context => this;
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
index adc09ea3..a0dc5c8c 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Reflection;
+using System.Reflection;
using Cake.Frosting;
using CreativeCoders.CakeBuild.BuildServer;
using CreativeCoders.CakeBuild.Tasks.Defaults;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
new file mode 100644
index 00000000..ea25ecc6
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
@@ -0,0 +1,32 @@
+using Cake.Common.Tools.GitVersion;
+using Cake.Core;
+using Cake.Core.IO;
+using Cake.Frosting;
+
+namespace CreativeCoders.CakeBuild;
+
+public interface IBuildContext : ICakeContext
+{
+ FilePath SolutionFile { get; }
+
+ DirectoryPath RootDir { get; }
+
+ DirectoryPath ArtifactsDir { get; }
+
+ DirectoryPath TestOutputBasePath { get; }
+
+ DirectoryPath CodeCoverageResultsDir { get; }
+
+ string BuildConfiguration { get; }
+
+ GitVersion Version { get; }
+
+ IList ExecutedTasks { get; }
+
+ void AddExecutedTask(IFrostingTask task);
+
+ bool HasExecutedTask(Type taskType);
+
+ T GetSettings()
+ where T : class;
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContextAccessor.cs b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContextAccessor.cs
new file mode 100644
index 00000000..203b5571
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContextAccessor.cs
@@ -0,0 +1,6 @@
+namespace CreativeCoders.CakeBuild;
+
+public interface IBuildContextAccessor
+{
+ IBuildContext Context { get; }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultBuildSetup.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
similarity index 63%
rename from source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultBuildSetup.cs
rename to source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
index 8b01cdf0..24e79464 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultBuildSetup.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
@@ -2,4 +2,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Defaults;
-public interface IDefaultBuildSetup : IBuildPaths { }
+public interface IDefaultTaskSettings : ICleanTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index b964f88e..75cadad5 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -1,5 +1,4 @@
-using System.Threading.Tasks;
-using Cake.Common.Diagnostics;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Build;
using Cake.Common.Tools.DotNet.MSBuild;
@@ -20,6 +19,7 @@ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
{
Configuration = context.BuildConfiguration,
NoRestore = context.HasExecutedTask(typeof(RestoreTask)),
+ NoIncremental = true,
MSBuildSettings = new DotNetMSBuildSettings
{
InformationalVersion = context.Version.InformationalVersion,
@@ -50,8 +50,3 @@ public override Task RunAsync(T context)
return Task.CompletedTask;
}
}
-
-public class BuildTaskSettings
-{
- public string? Configuration { get; set; }
-}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
index 77575e00..7e385073 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -1,26 +1,26 @@
-using System.Linq;
-using System.Threading.Tasks;
-using Cake.Common.Diagnostics;
+using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
using Cake.Core.IO;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class CleanTask : FrostingTaskBase where T : BuildContext
{
- public override async Task RunAsync(T context)
+ public override Task RunAsync(T context)
{
- DeleteDirectories(context, context.RootDir.FullPath + "/**/bin");
- DeleteDirectories(context, context.RootDir.FullPath + "/**/obj");
+ var settings = context.GetSettings();
+
+ DeleteDirectories(context, settings.DirectoriesToClean);
context.DotNetClean(context.SolutionFile.FullPath);
+
+ return Task.CompletedTask;
}
- private static void DeleteDirectories(T context, string globPattern)
+ private static void DeleteDirectories(T context, IEnumerable dirsForDelete)
{
- var dirs = context.Globber.Match(globPattern).OfType();
-
- foreach (var dir in dirs)
+ foreach (var dir in dirsForDelete.Where(dir => context.FileSystem.GetDirectory(dir).Exists))
{
context.Information("Deleting directory '{0}'", dir);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
index e24f0be9..c4ece690 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
@@ -1,5 +1,4 @@
-using System.Threading.Tasks;
-using Cake.Common.Tools.DotNet;
+using Cake.Common.Tools.DotNet;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs
index 5a6f0f65..794e2faa 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/CakeTaskSettingsAttribute.cs
@@ -1,5 +1,3 @@
-using System;
-
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[AttributeUsage(AttributeTargets.Interface)]
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
deleted file mode 100644
index bef35644..00000000
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildPaths.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-using Cake.Core;
-using Cake.Core.IO;
-
-namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-
-[CakeTaskSettings]
-public interface IBuildPaths : ICakeBuildSettings
-{
- DirectoryPath RootDir => FindGitRootPath(Context.Environment.WorkingDirectory) ??
- Context.Environment.WorkingDirectory.GetParent();
-
- DirectoryPath ArtifactsDir => RootDir.Combine(".artifacts");
-
- DirectoryPath TestOutputBasePath => RootDir.Combine(".tests");
-
- DirectoryPath CodeCoverageResultsDir => TestOutputBasePath.Combine("coverage-results");
-
- DirectoryPath? FindGitRootPath(DirectoryPath? startPath)
- {
- while (true)
- {
- if (startPath == null)
- {
- return null;
- }
-
- if (Context.FileSystem.Exist(startPath.Combine(".git")))
- {
- return startPath;
- }
-
- startPath = startPath.GetParent();
- }
- }
-}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
deleted file mode 100644
index b003e980..00000000
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IBuildTaskSettings.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-
-[CakeTaskSettings]
-public interface IBuildTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs
deleted file mode 100644
index 163a665c..00000000
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICakeBuildSettings.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using Cake.Core;
-
-namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-
-public interface ICakeBuildSettings
-{
- ICakeContext Context { get; }
-}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
index b33ab2e7..54d48531 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
@@ -1,4 +1,41 @@
+using System.Collections.Generic;
+using System.Linq;
+using Cake.Core.IO;
+
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
-public interface ICleanTaskSettings { }
+public interface ICleanTaskSettings : IBuildContextAccessor
+{
+ IList DirectoriesToClean => DefaultDirectoriesToClean;
+
+ IList DefaultDirectoriesToClean
+ {
+ get
+ {
+ var dirs = new List();
+
+ string[] defaultSourceDirs = ["source", "src", "samples", "tests"];
+
+ foreach (var defaultSourceDir in defaultSourceDirs)
+ {
+ var sourceDir = Context.RootDir.Combine(defaultSourceDir);
+
+ if (Context.FileSystem.Exist(sourceDir))
+ {
+ var binDirs = Context.Globber.Match(sourceDir.FullPath + "/**/bin")
+ .OfType();
+
+ dirs.AddRange(binDirs);
+
+ var objDirs = Context.Globber.Match(sourceDir.FullPath + "/**/obj")
+ .OfType();
+
+ dirs.AddRange(objDirs);
+ }
+ }
+
+ return dirs;
+ }
+ }
+}
diff --git a/source/Core/CreativeCoders.Core/ObjectExtensions.cs b/source/Core/CreativeCoders.Core/ObjectExtensions.cs
index 014047e4..778ba00b 100644
--- a/source/Core/CreativeCoders.Core/ObjectExtensions.cs
+++ b/source/Core/CreativeCoders.Core/ObjectExtensions.cs
@@ -47,6 +47,8 @@ public static bool TryAs(this object instance, [MaybeNullWhen(false)] out T a
return false;
}
+ public static T CastAs(this object instance) => (T)Ensure.NotNull(instance);
+
public static async ValueTask TryDisposeAsync(this object instance)
{
switch (instance)
From f570ea908b878fe60f1bd57c5707ab041ea1c899 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 12:52:20 +0100
Subject: [PATCH 25/73] Add implementation for `TestTask` to execute
`DotNetTest` with configurable settings and enhance `BuildTask` syntax
consistency
---
.../Tasks/Templates/BuildTask.cs | 2 +-
.../Tasks/Templates/TestTask.cs | 36 +++++++++++++++++--
2 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 75cadad5..59af6201 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -8,7 +8,7 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates;
[PublicAPI]
-public class BuildTask() : FrostingTaskBase
+public class BuildTask : FrostingTaskBase
where T : BuildContext
{
protected virtual void ApplyDotNetBuildSettings(T context, DotNetBuildSettings dotNetBuildSettings) { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
index 377389f6..de2a083a 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
@@ -1,3 +1,35 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates;
+using Cake.Common.Diagnostics;
+using Cake.Common.Tools.DotNet;
+using Cake.Common.Tools.DotNet.Test;
-public class TestTask : FrostingTaskBase where T : BuildContext { }
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class TestTask : FrostingTaskBase where T : BuildContext
+{
+ public override Task RunAsync(T context)
+ {
+ context.DotNetTest(context.RootDir.FullPath, CreateDotNetBuildSettings(context));
+
+ return Task.CompletedTask;
+ }
+
+ protected virtual void ApplyDotNetTestSettings(T context, DotNetTestSettings dotNetBuildSettings) { }
+
+ private DotNetTestSettings CreateDotNetBuildSettings(T context)
+ {
+ var dotNetTestSettings = new DotNetTestSettings
+ {
+ Configuration = context.BuildConfiguration,
+ NoBuild = context.HasExecutedTask(typeof(BuildTask))
+ };
+
+ ApplyDotNetTestSettings(context, dotNetTestSettings);
+
+ if (dotNetTestSettings.NoBuild)
+ {
+ context.Information("Skip build");
+ }
+
+ return dotNetTestSettings;
+ }
+}
From 7ba5b51f5a105550c9595adcf77ea5a42d8869d3 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 12:52:40 +0100
Subject: [PATCH 26/73] Update integration workflow to run tests instead of
build in `DeployNuGet` step
---
.github/workflows/integration.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 1394b372..bc984aa3 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -42,7 +42,7 @@ jobs:
- name: 'Run: DeployNuGet'
run: |
cd ./samples/CakeBuildSample
- dotnet run -- -t build
+ dotnet run -- -t test
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: 'Publish: coverage_report'
From 4e6a7254a3baaf89fcdf16462892cf2ef296ab77 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 14:48:30 +0100
Subject: [PATCH 27/73] Refactor `FrostingTaskBase` and derived tasks to
streamline task execution and enhance GitHub Actions integration
- Introduced `RunAsyncCore` as a protected abstract method in `FrostingTaskBase`, replacing `RunAsync` in derived tasks.
- Added GitHub Actions group logging for better task execution visibility.
- Updated all template tasks to implement `RunAsyncCore` with appropriate logic or placeholders.
---
.../Tasks/FrostingTaskBase.cs | 36 +++++++++++++++++--
.../Tasks/Templates/BuildTask.cs | 2 +-
.../Tasks/Templates/CleanTask.cs | 2 +-
.../Tasks/Templates/CodeCoverageTask.cs | 8 ++++-
.../Tasks/Templates/NuGetPublishTask.cs | 8 ++++-
.../Tasks/Templates/PackTask.cs | 8 ++++-
.../Tasks/Templates/RestoreTask.cs | 2 +-
.../Tasks/Templates/TestTask.cs | 2 +-
8 files changed, 59 insertions(+), 9 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
index 4ced8fdc..78a1700c 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
@@ -1,10 +1,42 @@
-using Cake.Frosting;
+using System.Reflection;
+using Cake.Common.Build;
+using Cake.Common.Diagnostics;
+using Cake.Frosting;
namespace CreativeCoders.CakeBuild.Tasks;
-public class FrostingTaskBase : AsyncFrostingTask
+public abstract class FrostingTaskBase : AsyncFrostingTask
where T : BuildContext
{
+ public sealed override async Task RunAsync(T context)
+ {
+ var taskName = ReadTaskName();
+
+ if (context.GitHubActions().IsRunningOnGitHubActions)
+ {
+ context.Information("");
+ context.GitHubActions().Commands.StartGroup(taskName);
+ }
+
+ context.Information($"Running task '{taskName}' ...");
+
+ await RunAsyncCore(context).ConfigureAwait(false);
+
+ if (context.GitHubActions().IsRunningOnGitHubActions)
+ {
+ context.GitHubActions().Commands.EndGroup();
+ }
+ }
+
+ private string ReadTaskName()
+ {
+ var taskNameAttr = GetType().GetCustomAttribute();
+
+ return taskNameAttr?.Name ?? GetType().Name;
+ }
+
+ protected abstract Task RunAsyncCore(T context);
+
public override void Finally(T context)
{
base.Finally(context);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 59af6201..2eb50bf5 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -38,7 +38,7 @@ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
return dotNetBuildSettings;
}
- public override Task RunAsync(T context)
+ protected override Task RunAsyncCore(T context)
{
var dotnetSettings = CreateDotNetBuildSettings(context);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
index 7e385073..512f0431 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -7,7 +7,7 @@ namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class CleanTask : FrostingTaskBase where T : BuildContext
{
- public override Task RunAsync(T context)
+ protected override Task RunAsyncCore(T context)
{
var settings = context.GetSettings();
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
index 526c0750..4e315772 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
@@ -1,4 +1,10 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class CodeCoverageTask : FrostingTaskBase
- where T : BuildContext { }
+ where T : BuildContext
+{
+ protected override Task RunAsyncCore(T context)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
index 504b9af0..808517d3 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
@@ -1,3 +1,9 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates;
-public class NuGetPublishTask : FrostingTaskBase where T : BuildContext { }
+public class NuGetPublishTask : FrostingTaskBase where T : BuildContext
+{
+ protected override Task RunAsyncCore(T context)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
index 7a24f6ab..367aac43 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
@@ -1,4 +1,10 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class PackTask : FrostingTaskBase
- where T : BuildContext { }
+ where T : BuildContext
+{
+ protected override Task RunAsyncCore(T context)
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
index c4ece690..bb171337 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/RestoreTask.cs
@@ -5,7 +5,7 @@ namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class RestoreTask : FrostingTaskBase
where T : BuildContext
{
- public override Task RunAsync(T context)
+ protected override Task RunAsyncCore(T context)
{
context.DotNetRestore(context.RootDir.FullPath);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
index de2a083a..bf5c9f93 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
@@ -6,7 +6,7 @@ namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class TestTask : FrostingTaskBase where T : BuildContext
{
- public override Task RunAsync(T context)
+ protected override Task RunAsyncCore(T context)
{
context.DotNetTest(context.RootDir.FullPath, CreateDotNetBuildSettings(context));
From 8ad977879209bfe67476f3a44b1675bd906211b9 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 14:58:53 +0100
Subject: [PATCH 28/73] Remove `AddBuildServerIntegration` from
`CakeBuildSample` for simplification
---
samples/CakeBuildSample/Program.cs | 1 -
1 file changed, 1 deletion(-)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 8889b782..a4671162 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -10,7 +10,6 @@ static int Main(string[] args)
return CakeHostBuilder.Create()
.UseBuildContext()
.AddDefaultTasks()
- .AddBuildServerIntegration()
.Build()
.Run(args);
}
From d9d1712f26f9508588ec8f1f29f67660dc2c131a Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 15:01:48 +0100
Subject: [PATCH 29/73] Annotate `FrostingTaskBase` with [PublicAPI] and update
logging in task teardown for consistency
---
.../BuildServer/EndGroupTaskTeardown.cs | 2 ++
.../CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs | 5 ++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
index c4c7d292..b9e19dbe 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
@@ -1,4 +1,5 @@
using Cake.Common.Build;
+using Cake.Common.Diagnostics;
using Cake.Core;
using Cake.Frosting;
using JetBrains.Annotations;
@@ -12,6 +13,7 @@ void IFrostingTaskTeardown.Teardown(ICakeContext context, ITaskTeardownContext i
{
if (context.GitHubActions().IsRunningOnGitHubActions)
{
+ context.Information("");
context.GitHubActions().Commands.EndGroup();
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
index 78a1700c..55c73e6a 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
@@ -2,9 +2,11 @@
using Cake.Common.Build;
using Cake.Common.Diagnostics;
using Cake.Frosting;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild.Tasks;
+[PublicAPI]
public abstract class FrostingTaskBase : AsyncFrostingTask
where T : BuildContext
{
@@ -24,11 +26,12 @@ public sealed override async Task RunAsync(T context)
if (context.GitHubActions().IsRunningOnGitHubActions)
{
+ context.Information("");
context.GitHubActions().Commands.EndGroup();
}
}
- private string ReadTaskName()
+ protected string ReadTaskName()
{
var taskNameAttr = GetType().GetCustomAttribute();
From a578af0abc8f819f28a4bf1ad95247aee969fa83 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 15:04:28 +0100
Subject: [PATCH 30/73] Comment out GitHub Actions group logging in
`FrostingTaskBase` and add `AddBuildServerIntegration` to `CakeBuildSample`.
---
samples/CakeBuildSample/Program.cs | 1 +
.../Tasks/FrostingTaskBase.cs | 20 +++++++++----------
2 files changed, 11 insertions(+), 10 deletions(-)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index a4671162..8889b782 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -10,6 +10,7 @@ static int Main(string[] args)
return CakeHostBuilder.Create()
.UseBuildContext()
.AddDefaultTasks()
+ .AddBuildServerIntegration()
.Build()
.Run(args);
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
index 55c73e6a..793ce4d8 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
@@ -14,21 +14,21 @@ public sealed override async Task RunAsync(T context)
{
var taskName = ReadTaskName();
- if (context.GitHubActions().IsRunningOnGitHubActions)
- {
- context.Information("");
- context.GitHubActions().Commands.StartGroup(taskName);
- }
+ // if (context.GitHubActions().IsRunningOnGitHubActions)
+ // {
+ // context.Information("");
+ // context.GitHubActions().Commands.StartGroup(taskName);
+ // }
context.Information($"Running task '{taskName}' ...");
await RunAsyncCore(context).ConfigureAwait(false);
- if (context.GitHubActions().IsRunningOnGitHubActions)
- {
- context.Information("");
- context.GitHubActions().Commands.EndGroup();
- }
+ // if (context.GitHubActions().IsRunningOnGitHubActions)
+ // {
+ // context.Information("");
+ // context.GitHubActions().Commands.EndGroup();
+ // }
}
protected string ReadTaskName()
From 3129563d7c50a0aecda578d1f3b54b858526c8c5 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 17:30:33 +0100
Subject: [PATCH 31/73] Refactor and update task settings and implementations
for improved modularity and consistency
- Changed `ICleanTaskSettings.DefaultDirectoriesToClean` to method `GetDefaultDirectoriesToClean` for better clarity and extensibility.
- Introduced `TestProjects` property in `ITestTaskSettings`.
- Removed commented GitHub Actions group logging from `FrostingTaskBase` for cleanup.
- Streamlined `SampleBuildContext` to use updated `ICleanTaskSettings` API.
---
samples/CakeBuildSample/Program.cs | 1 -
samples/CakeBuildSample/SampleBuildContext.cs | 4 +-
.../Tasks/FrostingTaskBase.cs | 12 ------
.../Templates/Settings/ICleanTaskSettings.cs | 39 ++++++++-----------
.../Templates/Settings/ITestTaskSettings.cs | 5 ++-
5 files changed, 23 insertions(+), 38 deletions(-)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 8889b782..8db82481 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,5 +1,4 @@
using CreativeCoders.CakeBuild;
-using CreativeCoders.CakeBuild.Tasks.Defaults;
namespace CakeBuildSample;
diff --git a/samples/CakeBuildSample/SampleBuildContext.cs b/samples/CakeBuildSample/SampleBuildContext.cs
index 2ad66c5c..068c3ea8 100644
--- a/samples/CakeBuildSample/SampleBuildContext.cs
+++ b/samples/CakeBuildSample/SampleBuildContext.cs
@@ -12,6 +12,6 @@ public class SampleBuildContext : BuildContext, IDefaultTaskSettings
{
public SampleBuildContext(ICakeContext context) : base(context) { }
- IList ICleanTaskSettings.DirectoriesToClean =>
- this.CastAs().DefaultDirectoriesToClean.AddRange(RootDir.Combine(".tests"));
+ public IList DirectoriesToClean => this.CastAs()
+ .GetDefaultDirectoriesToClean().AddRange(RootDir.Combine(".tests"));
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
index 793ce4d8..9afce3f8 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
@@ -14,21 +14,9 @@ public sealed override async Task RunAsync(T context)
{
var taskName = ReadTaskName();
- // if (context.GitHubActions().IsRunningOnGitHubActions)
- // {
- // context.Information("");
- // context.GitHubActions().Commands.StartGroup(taskName);
- // }
-
context.Information($"Running task '{taskName}' ...");
await RunAsyncCore(context).ConfigureAwait(false);
-
- // if (context.GitHubActions().IsRunningOnGitHubActions)
- // {
- // context.Information("");
- // context.GitHubActions().Commands.EndGroup();
- // }
}
protected string ReadTaskName()
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
index 54d48531..cffeff21 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
@@ -1,5 +1,3 @@
-using System.Collections.Generic;
-using System.Linq;
using Cake.Core.IO;
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
@@ -7,35 +5,32 @@ namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
public interface ICleanTaskSettings : IBuildContextAccessor
{
- IList DirectoriesToClean => DefaultDirectoriesToClean;
+ IList DirectoriesToClean => GetDefaultDirectoriesToClean();
- IList DefaultDirectoriesToClean
+ IList GetDefaultDirectoriesToClean()
{
- get
- {
- var dirs = new List();
+ var dirs = new List();
- string[] defaultSourceDirs = ["source", "src", "samples", "tests"];
+ string[] defaultSourceDirs = ["source", "src", "samples", "tests"];
- foreach (var defaultSourceDir in defaultSourceDirs)
- {
- var sourceDir = Context.RootDir.Combine(defaultSourceDir);
+ foreach (var defaultSourceDir in defaultSourceDirs)
+ {
+ var sourceDir = Context.RootDir.Combine(defaultSourceDir);
- if (Context.FileSystem.Exist(sourceDir))
- {
- var binDirs = Context.Globber.Match(sourceDir.FullPath + "/**/bin")
- .OfType();
+ if (Context.FileSystem.Exist(sourceDir))
+ {
+ var binDirs = Context.Globber.Match(sourceDir.FullPath + "/**/bin")
+ .OfType();
- dirs.AddRange(binDirs);
+ dirs.AddRange(binDirs);
- var objDirs = Context.Globber.Match(sourceDir.FullPath + "/**/obj")
- .OfType();
+ var objDirs = Context.Globber.Match(sourceDir.FullPath + "/**/obj")
+ .OfType();
- dirs.AddRange(objDirs);
- }
+ dirs.AddRange(objDirs);
}
-
- return dirs;
}
+
+ return dirs;
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
index b51444f0..a51892dc 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
@@ -1,4 +1,7 @@
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
-public interface ITestTaskSettings { }
+public interface ITestTaskSettings
+{
+ IEnumerable TestProjects { get; }
+}
From 9c0aca6fe918517df71f0b112a362d1d4f5ec702 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 17:55:39 +0100
Subject: [PATCH 32/73] Annotate interfaces with [PublicAPI], refactor
exception handling in CakeContextExtensions, enhance `ITestTaskSettings`, and
update task implementations for improved modularity
---
.../CreativeCoders.CakeBuild/BuildContext.cs | 11 ++++-----
.../BuildServer/EndGroupTaskTeardown.cs | 8 ++++---
.../BuildServer/StartGroupTaskSetup.cs | 8 ++++---
.../CakeContextExtensions.cs | 8 +++++--
.../ICakeHostBuilder.cs | 2 ++
.../StaticGitVersion.cs | 2 +-
.../Tasks/Defaults/IDefaultTaskSettings.cs | 2 +-
.../Tasks/FrostingTaskBase.cs | 1 -
.../Templates/Settings/ITestTaskSettings.cs | 24 +++++++++++++++++--
.../Tasks/Templates/TestTask.cs | 14 ++++++++++-
10 files changed, 60 insertions(+), 20 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index 6ff7d070..db0cf9d6 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -4,7 +4,6 @@
using Cake.Core;
using Cake.Core.IO;
using Cake.Frosting;
-using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using CreativeCoders.Core.IO;
using JetBrains.Annotations;
@@ -64,14 +63,14 @@ private FilePath FindRootSolution(ICakeContext context)
var solution = solutions.FirstOrDefault();
- if (solution == null)
+ if (solution != null)
{
- context.Error("No solution file found.");
-
- throw new InvalidOperationException("No solution file found");
+ return solution;
}
- return solution;
+ context.Error("No solution file found.");
+
+ throw new InvalidOperationException("No solution file found");
}
public FilePath SolutionFile { get; }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
index b9e19dbe..9490e08d 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/EndGroupTaskTeardown.cs
@@ -11,10 +11,12 @@ public class EndGroupTaskTeardown : IFrostingTaskTeardown
{
void IFrostingTaskTeardown.Teardown(ICakeContext context, ITaskTeardownContext info)
{
- if (context.GitHubActions().IsRunningOnGitHubActions)
+ if (!context.GitHubActions().IsRunningOnGitHubActions)
{
- context.Information("");
- context.GitHubActions().Commands.EndGroup();
+ return;
}
+
+ context.Information("");
+ context.GitHubActions().Commands.EndGroup();
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs
index f667ad82..ff3c0586 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildServer/StartGroupTaskSetup.cs
@@ -11,10 +11,12 @@ public class StartGroupTaskSetup : IFrostingTaskSetup
{
void IFrostingTaskSetup.Setup(ICakeContext context, ITaskSetupContext info)
{
- if (context.GitHubActions().IsRunningOnGitHubActions)
+ if (!context.GitHubActions().IsRunningOnGitHubActions)
{
- context.Information("");
- context.GitHubActions().Commands.StartGroup(info.Task.Name);
+ return;
}
+
+ context.Information("");
+ context.GitHubActions().Commands.StartGroup(info.Task.Name);
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
index af61d656..6354feb3 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeContextExtensions.cs
@@ -1,9 +1,11 @@
using Cake.Common.Tools.GitVersion;
using Cake.Core;
using Cake.Frosting;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild;
+[PublicAPI]
public static class CakeContextExtensions
{
public static bool TaskHasRun(this BuildContext context)
@@ -18,9 +20,11 @@ public static GitVersion GetGitVersionSafe(this ICakeContext context,
{
try
{
- return context.GitVersion();
+ return gitVersionSettings == null
+ ? context.GitVersion()
+ : context.GitVersion(gitVersionSettings);
}
- catch (Exception e)
+ catch (Exception)
{
return StaticGitVersion.Create(major ?? "0", minor ?? "0", patch ?? "0", build ?? "1", "");
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs b/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs
index c434be80..cc2cbc12 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/ICakeHostBuilder.cs
@@ -1,7 +1,9 @@
using Cake.Frosting;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild;
+[PublicAPI]
public interface ICakeHostBuilder
{
ICakeHostBuilder AddBuildServerIntegration();
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs b/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs
index 4af8d11f..7fb903df 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/StaticGitVersion.cs
@@ -34,7 +34,7 @@ public static GitVersion Create(string major, string minor, string patch, string
NuGetPreReleaseTagV2 = preReleaseTag,
CommitDate = DateTimeOffset.Now.ToString(),
PreReleaseTagWithDash = $"-{preReleaseTag}",
- PreReleaseLabelWithDash = $"-{preReleaseTag}",
+ PreReleaseLabelWithDash = $"-{preReleaseTag}"
};
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
index 24e79464..65c3219f 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
@@ -2,4 +2,4 @@
namespace CreativeCoders.CakeBuild.Tasks.Defaults;
-public interface IDefaultTaskSettings : ICleanTaskSettings { }
+public interface IDefaultTaskSettings : ICleanTaskSettings, ITestTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
index 9afce3f8..e239822d 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/FrostingTaskBase.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using Cake.Common.Build;
using Cake.Common.Diagnostics;
using Cake.Frosting;
using JetBrains.Annotations;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
index a51892dc..cdf3590a 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
@@ -1,7 +1,27 @@
+using Cake.Common.Solution;
+using Cake.Core.IO;
+
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
-public interface ITestTaskSettings
+public interface ITestTaskSettings : IBuildContextAccessor
{
- IEnumerable TestProjects { get; }
+ IEnumerable TestProjects
+ {
+ get
+ {
+ var solution = Context.ParseSolution(Context.SolutionFile);
+
+ var testProjects = solution.Projects
+ .Where(p =>
+ p.Path.MakeAbsolute(Context.Environment).FullPath.StartsWith(TestSourceDir.FullPath,
+ StringComparison.InvariantCulture));
+
+ return testProjects
+ .Select(x => x.Path)
+ .Where(x => x.GetExtension()?.ToLower() == ".csproj");
+ }
+ }
+
+ DirectoryPath TestSourceDir => Context.RootDir.Combine("tests");
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
index bf5c9f93..1cdb6a03 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
@@ -1,6 +1,7 @@
using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Test;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
@@ -8,7 +9,18 @@ public class TestTask : FrostingTaskBase where T : BuildContext
{
protected override Task RunAsyncCore(T context)
{
- context.DotNetTest(context.RootDir.FullPath, CreateDotNetBuildSettings(context));
+ var testSettings = context.GetSettings();
+
+ var testProjects = testSettings.TestProjects.OrderBy(x => x.FullPath).ToArray();
+
+ context.Information($"Found {testProjects.Length} test project(s)");
+
+ foreach (var testProject in testProjects)
+ {
+ context.Information($"Test project found: {testProject.GetFilename()}");
+
+ context.DotNetTest(testProject.FullPath, CreateDotNetBuildSettings(context));
+ }
return Task.CompletedTask;
}
From 1f6795ea53a3f0e760d463673db9a4d8fe0c0d7b Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Mon, 5 Jan 2026 18:03:28 +0100
Subject: [PATCH 33/73] Annotate `TestTask` with [PublicAPI] and update
`ITestTaskSettings` to handle `.slnx` file format limitations
---
.../Tasks/Templates/Settings/ITestTaskSettings.cs | 6 ++++++
.../CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs | 2 ++
2 files changed, 8 insertions(+)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
index cdf3590a..dc861e44 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
@@ -10,6 +10,12 @@ IEnumerable TestProjects
{
get
{
+ if (Context.SolutionFile.GetExtension()?.ToLower() != ".sln")
+ {
+ // Currently no support for new xml based slnx solution file format
+ return [];
+ }
+
var solution = Context.ParseSolution(Context.SolutionFile);
var testProjects = solution.Projects
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
index 1cdb6a03..d7efecf6 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
@@ -2,9 +2,11 @@
using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Test;
using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
+[PublicAPI]
public class TestTask : FrostingTaskBase where T : BuildContext
{
protected override Task RunAsyncCore(T context)
From 66dc309c9d2b6e02cf6ec698881133a488c41957 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 13:05:13 +0100
Subject: [PATCH 34/73] Add code coverage task implementation and update
related settings for enhanced test reporting
- Implement `CodeCoverageTask` using `ReportGenerator`.
- Enhance `IBuildContext` with properties for managing code coverage directories and reports.
- Update `TestTask` to support coverage collection and generate TRX reports.
- Refactor `ITestTaskSettings` to include coverage-related settings.
- Modify `.github/workflows` to execute the `codecoverage` task in the integration pipeline.
- Add `ReportGenerator` to `CakeBuildSample` dependencies.
---
.github/workflows/integration.yml | 2 +-
samples/CakeBuildSample/CakeBuildSample.csproj | 1 +
.../CreativeCoders.CakeBuild/BuildContext.cs | 6 +++++-
.../CreativeCoders.CakeBuild/IBuildContext.cs | 6 +++++-
.../Tasks/Templates/CodeCoverageTask.cs | 10 ++++++++--
.../Templates/Settings/ICleanTaskSettings.cs | 2 +-
.../Tasks/Templates/Settings/ITestTaskSettings.cs | 4 +++-
.../Tasks/Templates/TestTask.cs | 15 ++++++++++++---
8 files changed, 36 insertions(+), 10 deletions(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index bc984aa3..ed42a225 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -42,7 +42,7 @@ jobs:
- name: 'Run: DeployNuGet'
run: |
cd ./samples/CakeBuildSample
- dotnet run -- -t test
+ dotnet run -- -t codecoverage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: 'Publish: coverage_report'
diff --git a/samples/CakeBuildSample/CakeBuildSample.csproj b/samples/CakeBuildSample/CakeBuildSample.csproj
index ec82a3ec..c9145951 100644
--- a/samples/CakeBuildSample/CakeBuildSample.csproj
+++ b/samples/CakeBuildSample/CakeBuildSample.csproj
@@ -9,6 +9,7 @@
+
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index db0cf9d6..05cc583f 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -81,7 +81,11 @@ private FilePath FindRootSolution(ICakeContext context)
public virtual DirectoryPath TestOutputBasePath => RootDir.Combine(".tests");
- public virtual DirectoryPath CodeCoverageResultsDir => TestOutputBasePath.Combine("coverage-results");
+ public virtual DirectoryPath TestResultsDir => TestOutputBasePath.Combine("results");
+
+ public virtual DirectoryPath CodeCoverageDir => TestOutputBasePath.Combine("coverage");
+
+ public virtual DirectoryPath CodeCoverageReportDir => TestOutputBasePath.Combine("coverage-report");
public virtual string BuildConfiguration => this.BuildSystem().IsLocalBuild ? "Debug" : "Release";
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
index ea25ecc6..e7091f7b 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
@@ -15,7 +15,11 @@ public interface IBuildContext : ICakeContext
DirectoryPath TestOutputBasePath { get; }
- DirectoryPath CodeCoverageResultsDir { get; }
+ DirectoryPath TestResultsDir { get; }
+
+ DirectoryPath CodeCoverageDir { get; }
+
+ DirectoryPath CodeCoverageReportDir { get; }
string BuildConfiguration { get; }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
index 4e315772..86c6dec8 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
@@ -1,10 +1,16 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates;
+using Cake.Common.Tools.ReportGenerator;
+using Cake.Core.IO;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class CodeCoverageTask : FrostingTaskBase
where T : BuildContext
{
protected override Task RunAsyncCore(T context)
{
- throw new NotImplementedException();
+ context.ReportGenerator(new GlobPattern(context.CodeCoverageDir.FullPath + "/**/*.xml"),
+ context.CodeCoverageReportDir);
+
+ return Task.CompletedTask;
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
index cffeff21..43c4d02e 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICleanTaskSettings.cs
@@ -11,7 +11,7 @@ IList GetDefaultDirectoriesToClean()
{
var dirs = new List();
- string[] defaultSourceDirs = ["source", "src", "samples", "tests"];
+ string[] defaultSourceDirs = ["source", "src", "tests"];
foreach (var defaultSourceDir in defaultSourceDirs)
{
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
index dc861e44..56879aff 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ITestTaskSettings.cs
@@ -12,7 +12,7 @@ IEnumerable TestProjects
{
if (Context.SolutionFile.GetExtension()?.ToLower() != ".sln")
{
- // Currently no support for new xml based slnx solution file format
+ // Currently no support for new XML based slnx solution file format
return [];
}
@@ -29,5 +29,7 @@ IEnumerable TestProjects
}
}
+ bool GenerateCoverageReport => true;
+
DirectoryPath TestSourceDir => Context.RootDir.Combine("tests");
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
index d7efecf6..8b5d75ae 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/TestTask.cs
@@ -1,6 +1,7 @@
using Cake.Common.Diagnostics;
using Cake.Common.Tools.DotNet;
using Cake.Common.Tools.DotNet.Test;
+using Cake.Core.IO;
using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using JetBrains.Annotations;
@@ -21,7 +22,8 @@ protected override Task RunAsyncCore(T context)
{
context.Information($"Test project found: {testProject.GetFilename()}");
- context.DotNetTest(testProject.FullPath, CreateDotNetBuildSettings(context));
+ context.DotNetTest(testProject.FullPath,
+ CreateDotNetBuildSettings(context, testProject, testSettings));
}
return Task.CompletedTask;
@@ -29,12 +31,19 @@ protected override Task RunAsyncCore(T context)
protected virtual void ApplyDotNetTestSettings(T context, DotNetTestSettings dotNetBuildSettings) { }
- private DotNetTestSettings CreateDotNetBuildSettings(T context)
+ private DotNetTestSettings CreateDotNetBuildSettings(T context, FilePath testProject,
+ ITestTaskSettings testSettings)
{
+ var testResultFile =
+ context.TestResultsDir.CombineWithFilePath($"{testProject.GetFilenameWithoutExtension()}.trx");
+
var dotNetTestSettings = new DotNetTestSettings
{
Configuration = context.BuildConfiguration,
- NoBuild = context.HasExecutedTask(typeof(BuildTask))
+ NoBuild = context.HasExecutedTask(typeof(BuildTask)),
+ Loggers = [$"trx;LogFileName={testResultFile}"],
+ Collectors = testSettings.GenerateCoverageReport ? ["XPlat Code Coverage"] : [],
+ ResultsDirectory = context.CodeCoverageDir
};
ApplyDotNetTestSettings(context, dotNetTestSettings);
From e742b8eaa552bf79e1ea4dd363e5566f90521ffe Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 13:15:13 +0100
Subject: [PATCH 35/73] Add detailed build version logging to `BuildTask`
- Log informational, assembly, and file versions during solution build for improved traceability.
---
.../CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 2eb50bf5..83ab3f41 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -45,6 +45,11 @@ protected override Task RunAsyncCore(T context)
context.Log.Information("Building solution {0} with configuration {1}",
context.SolutionFile.FullPath, dotnetSettings.Configuration);
+ context.Information("Build with informational version: " +
+ dotnetSettings.MSBuildSettings.InformationalVersion);
+ context.Information("Build with assembly version: " + dotnetSettings.MSBuildSettings.AssemblyVersion);
+ context.Information("Build with file version: " + dotnetSettings.MSBuildSettings.FileVersion);
+
context.DotNetBuild(context.SolutionFile.FullPath, dotnetSettings);
return Task.CompletedTask;
From 88bec6acbec79f88954910790e8c189d2ea24cc8 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 13:17:23 +0100
Subject: [PATCH 36/73] Add `GitVersion.Tool` as a dependency to
`CakeBuildSample`
---
samples/CakeBuildSample/CakeBuildSample.csproj | 1 +
1 file changed, 1 insertion(+)
diff --git a/samples/CakeBuildSample/CakeBuildSample.csproj b/samples/CakeBuildSample/CakeBuildSample.csproj
index c9145951..d9b57ee9 100644
--- a/samples/CakeBuildSample/CakeBuildSample.csproj
+++ b/samples/CakeBuildSample/CakeBuildSample.csproj
@@ -10,6 +10,7 @@
+
From 85c3aa2fa09788ceb0d642b97b0140c52216afde Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 13:47:28 +0100
Subject: [PATCH 37/73] Update `ICodeCoverageTaskSettings` with .NET framework
property and configure tool paths in `CakeBuildSample`
- Added `Framework` property to `ICodeCoverageTaskSettings` for dynamic .NET version handling.
- Configured `CakeHost` in `CakeBuildSample` to use a temporary tools directory and install required tools.
---
samples/CakeBuildSample/Program.cs | 17 ++++++++++++++++-
.../Settings/ICodeCoverageTaskSettings.cs | 7 ++++++-
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index 8db82481..d13bf478 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,4 +1,8 @@
-using CreativeCoders.CakeBuild;
+using Cake.Core.IO;
+using Cake.Frosting;
+using CreativeCoders.CakeBuild;
+using CreativeCoders.Core.IO;
+using CreativeCoders.Core.SysEnvironment;
namespace CakeBuildSample;
@@ -10,6 +14,17 @@ static int Main(string[] args)
.UseBuildContext()
.AddDefaultTasks()
.AddBuildServerIntegration()
+ .ConfigureHost(x =>
+ {
+ var tempToolsPath = FileSys.Path.Combine(FileSys.Path.GetTempPath(), ".cake-tools");
+
+ Console.WriteLine($"Using temp tools path: {tempToolsPath}");
+
+ x.SetToolPath(tempToolsPath);
+
+ x.InstallTool(new Uri("nuget:?package=GitVersion.Tool&version=6.5.1"));
+ x.InstallTool(new Uri("nuget:?package=dotnet-reportgenerator-globaltool&version=5.5.1"));
+ })
.Build()
.Run(args);
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
index d071fc3b..a5e1f324 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
@@ -1,4 +1,9 @@
+using CreativeCoders.Core.SysEnvironment;
+
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
-public interface ICodeCoverageTaskSettings { }
+public interface ICodeCoverageTaskSettings
+{
+ string Framework => $"net{Env.Version.Major}.0";
+}
From a7fe54662a6b264a068efdb1cd3d3ba29f42586c Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 13:51:46 +0100
Subject: [PATCH 38/73] Enable `windows-latest` runner in the integration
workflow and update `DeployNuGet` step to run code coverage task.
---
.github/workflows/integration.yml | 38 ++++++++++++++++---------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index ed42a225..3e8cbfb5 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -51,24 +51,26 @@ jobs:
# with:
# name: coverage_report
# path: .tests/coverage_report
-# windows-latest:
-# name: windows-latest
-# runs-on: windows-latest
-# steps:
-# - uses: actions/checkout@v4
-# with:
-# fetch-depth: 0
-# - name: 'Cache: .nuke/temp, ~/.nuget/packages'
-# uses: actions/cache@v4
-# with:
-# path: |
-# .nuke/temp
-# ~/.nuget/packages
-# key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
-# - name: 'Run: DeployNuGet'
-# run: ./build.cmd DeployNuGet
-# env:
-# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ windows-latest:
+ name: windows-latest
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v5
+ with:
+ fetch-depth: 0
+ # - name: 'Cache: .nuke/temp, ~/.nuget/packages'
+ # uses: actions/cache@v4
+ # with:
+ # path: |
+ # .nuke/temp
+ # ~/.nuget/packages
+ # key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
+ - name: 'Run: DeployNuGet'
+ run: |
+ cd ./samples/CakeBuildSample
+ dotnet run -- -t codecoverage
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: 'Publish: coverage_report'
# uses: actions/upload-artifact@v4
# if: runner.os == 'Linux'
From 46afa079d4d445a34012fa5a2a231d748115f2f6 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 14:14:19 +0100
Subject: [PATCH 39/73] Update `CodeCoverageTask` to log ReportGenerator
process arguments and enhance tool installation in `CakeBuildSample`
- Add diagnostic logging for ReportGenerator process arguments in `CodeCoverageTask` using `Information`.
- Use `DotNetToolPackageInstaller` in `CakeBuildSample` for improved tool installation patterns.
- Update tool URIs to use `dotnet:` scheme for consistency.
---
samples/CakeBuildSample/Program.cs | 6 ++++--
.../Tasks/Templates/CodeCoverageTask.cs | 14 ++++++++++++--
2 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/samples/CakeBuildSample/Program.cs b/samples/CakeBuildSample/Program.cs
index d13bf478..a80e4197 100644
--- a/samples/CakeBuildSample/Program.cs
+++ b/samples/CakeBuildSample/Program.cs
@@ -1,4 +1,5 @@
using Cake.Core.IO;
+using Cake.DotNetTool.Module;
using Cake.Frosting;
using CreativeCoders.CakeBuild;
using CreativeCoders.Core.IO;
@@ -22,8 +23,9 @@ static int Main(string[] args)
x.SetToolPath(tempToolsPath);
- x.InstallTool(new Uri("nuget:?package=GitVersion.Tool&version=6.5.1"));
- x.InstallTool(new Uri("nuget:?package=dotnet-reportgenerator-globaltool&version=5.5.1"));
+ x.UsePackageInstaller();
+ x.InstallTool(new Uri("dotnet:?package=GitVersion.Tool&version=6.5.1"));
+ x.InstallTool(new Uri("dotnet:?package=dotnet-reportgenerator-globaltool&version=5.5.1"));
})
.Build()
.Run(args);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
index 86c6dec8..c486059e 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
@@ -1,4 +1,5 @@
-using Cake.Common.Tools.ReportGenerator;
+using Cake.Common.Diagnostics;
+using Cake.Common.Tools.ReportGenerator;
using Cake.Core.IO;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
@@ -8,8 +9,17 @@ public class CodeCoverageTask : FrostingTaskBase
{
protected override Task RunAsyncCore(T context)
{
+ var reportGeneratorSettings = new ReportGeneratorSettings
+ {
+ SetupProcessSettings = x =>
+ {
+ context.Information(
+ $"ReportGenerator Process Args: {string.Join("", x.Arguments.Select(arg => arg.RenderSafe()))}");
+ }
+ };
+
context.ReportGenerator(new GlobPattern(context.CodeCoverageDir.FullPath + "/**/*.xml"),
- context.CodeCoverageReportDir);
+ context.CodeCoverageReportDir, reportGeneratorSettings);
return Task.CompletedTask;
}
From fc0c589adcbdcfc32fe23c5b99736699e9bb1f50 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 16:16:58 +0100
Subject: [PATCH 40/73] Update `CodeCoverageTask` to use
`ICodeCoverageTaskSettings` for dynamic configuration
- Refactor `CodeCoverageTask` to retrieve settings from `ICodeCoverageTaskSettings`.
- Add `ReportGlobPattern` and `ReportTypes`
---
.../Tasks/Templates/CodeCoverageTask.cs | 11 +++++------
.../Templates/Settings/ICodeCoverageTaskSettings.cs | 12 +++++++++---
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
index c486059e..cc4ece41 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
@@ -1,6 +1,7 @@
using Cake.Common.Diagnostics;
using Cake.Common.Tools.ReportGenerator;
using Cake.Core.IO;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
namespace CreativeCoders.CakeBuild.Tasks.Templates;
@@ -9,16 +10,14 @@ public class CodeCoverageTask : FrostingTaskBase
{
protected override Task RunAsyncCore(T context)
{
+ var codeCoverageSettings = context.GetSettings();
+
var reportGeneratorSettings = new ReportGeneratorSettings
{
- SetupProcessSettings = x =>
- {
- context.Information(
- $"ReportGenerator Process Args: {string.Join("", x.Arguments.Select(arg => arg.RenderSafe()))}");
- }
+ ReportTypes = codeCoverageSettings.ReportTypes.ToList()
};
- context.ReportGenerator(new GlobPattern(context.CodeCoverageDir.FullPath + "/**/*.xml"),
+ context.ReportGenerator(new GlobPattern(codeCoverageSettings.ReportGlobPattern),
context.CodeCoverageReportDir, reportGeneratorSettings);
return Task.CompletedTask;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
index a5e1f324..eaf19585 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/ICodeCoverageTaskSettings.cs
@@ -1,9 +1,15 @@
-using CreativeCoders.Core.SysEnvironment;
+using Cake.Common.Tools.ReportGenerator;
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
-public interface ICodeCoverageTaskSettings
+public interface ICodeCoverageTaskSettings : IBuildContextAccessor
{
- string Framework => $"net{Env.Version.Major}.0";
+ IEnumerable ReportTypes =>
+ [
+ ReportGeneratorReportType.Html,
+ ReportGeneratorReportType.MarkdownSummaryGithub
+ ];
+
+ string ReportGlobPattern => Context.CodeCoverageDir.FullPath + "/**/*.xml";
}
From 0f49c194bd0c9986bedfe76af9236675ae469c27 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Tue, 6 Jan 2026 17:03:06 +0100
Subject: [PATCH 41/73] Add `IPackTaskSettings` and implement `PackTask` with
NuGet packaging functionality
- Introduced `IPackTaskSettings` for configuring NuGet packaging properties.
- Implemented `PackTask` to use `DotNetPack` with dynamic settings retrieval.
- Updated `IDefaultTaskSettings` to include `IPackTaskSettings`.
- Enhanced `BuildTask` with detailed package version logging.
- Modified `GitVersion.yml` for improved feature branch regex and deployment configurations.
---
GitVersion.yml | 7 +++-
.../Tasks/Defaults/IDefaultTaskSettings.cs | 3 +-
.../Tasks/Templates/BuildTask.cs | 4 +-
.../Tasks/Templates/PackTask.cs | 40 ++++++++++++++++++-
.../Templates/Settings/IPackTaskSettings.cs | 15 ++++++-
5 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/GitVersion.yml b/GitVersion.yml
index e554e6f6..cc29f663 100644
--- a/GitVersion.yml
+++ b/GitVersion.yml
@@ -9,15 +9,18 @@ no-bump-message: '\+semver:\s?(none|skip)'
mode: ContinuousDeployment
branches:
feature:
- mode: ContinuousDeployment
+ mode: ManualDeployment
label: feature.{BranchName}
increment: Minor
track-merge-target: false
- regex: ^features?[/-]
+ regex: ^features?[\/-](?.+)
+ prevent-increment:
+ when-current-commit-tagged: false
source-branches:
- main
tracks-release-branches: false
is-release-branch: false
+ is-main-branch: false
pre-release-weight: 30000
main:
mode: ContinuousDeployment
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
index 65c3219f..a1543cbe 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
@@ -2,4 +2,5 @@
namespace CreativeCoders.CakeBuild.Tasks.Defaults;
-public interface IDefaultTaskSettings : ICleanTaskSettings, ITestTaskSettings { }
+public interface IDefaultTaskSettings : ICleanTaskSettings, ITestTaskSettings, ICodeCoverageTaskSettings,
+ IPackTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 83ab3f41..480de321 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -24,7 +24,8 @@ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
{
InformationalVersion = context.Version.InformationalVersion,
AssemblyVersion = context.Version.AssemblySemVer,
- FileVersion = context.Version.AssemblySemFileVer
+ FileVersion = context.Version.AssemblySemFileVer,
+ PackageVersion = context.Version.SemVer
}
};
@@ -49,6 +50,7 @@ protected override Task RunAsyncCore(T context)
dotnetSettings.MSBuildSettings.InformationalVersion);
context.Information("Build with assembly version: " + dotnetSettings.MSBuildSettings.AssemblyVersion);
context.Information("Build with file version: " + dotnetSettings.MSBuildSettings.FileVersion);
+ context.Information("Build with package version: " + dotnetSettings.MSBuildSettings.PackageVersion);
context.DotNetBuild(context.SolutionFile.FullPath, dotnetSettings);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
index 367aac43..d4afdaf5 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
@@ -1,10 +1,46 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates;
+using Cake.Common.Tools.DotNet;
+using Cake.Common.Tools.DotNet.MSBuild;
+using Cake.Common.Tools.DotNet.Pack;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
public class PackTask : FrostingTaskBase
where T : BuildContext
{
protected override Task RunAsyncCore(T context)
{
- throw new NotImplementedException();
+ var packSettings = context.GetSettings();
+
+ context.DotNetPack(context.SolutionFile.FullPath, CreateDotNetPackSettings(context, packSettings));
+
+ return Task.CompletedTask;
+ }
+
+ private DotNetPackSettings CreateDotNetPackSettings(T context, IPackTaskSettings packSettings)
+ {
+ var dotNetPackSettings = new DotNetPackSettings
+ {
+ OutputDirectory = packSettings.OutputDirectory,
+ Configuration = context.BuildConfiguration,
+ NoBuild = context.HasExecutedTask(typeof(BuildTask)),
+ IncludeSymbols = true,
+ SymbolPackageFormat = "snupkg",
+
+ MSBuildSettings = new DotNetMSBuildSettings
+ {
+ InformationalVersion = context.Version.InformationalVersion,
+ AssemblyVersion = context.Version.AssemblySemVer,
+ FileVersion = context.Version.AssemblySemFileVer,
+ PackageVersion = context.Version.SemVer,
+ }
+ };
+
+ dotNetPackSettings.MSBuildSettings.WithProperty("PackageProjectUrl", packSettings.PackageProjectUrl);
+ dotNetPackSettings.MSBuildSettings.WithProperty("PackageLicenseExpression",
+ packSettings.PackageLicenseExpression);
+ dotNetPackSettings.MSBuildSettings.WithProperty("PackageLicenseUrl", packSettings.PackageLicenseUrl);
+
+ return dotNetPackSettings;
}
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
index b6774f0a..4b74a908 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/IPackTaskSettings.cs
@@ -1,4 +1,17 @@
+using Cake.Core.IO;
+
namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
[CakeTaskSettings]
-public interface IPackTaskSettings { }
+public interface IPackTaskSettings : IBuildContextAccessor
+{
+ DirectoryPath OutputDirectory => Context.ArtifactsDir.Combine("nuget");
+
+ string Copyright => string.Empty;
+
+ string PackageProjectUrl => string.Empty;
+
+ string PackageLicenseUrl => string.Empty;
+
+ string PackageLicenseExpression => string.Empty;
+}
From 560af6ecf31db0160e83639626c3bd7f39686b5a Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Wed, 7 Jan 2026 18:51:23 +0100
Subject: [PATCH 42/73] Add `PackageLicenseExpression` and MSBuild settings
extensions for enhanced packaging configuration
- Introduced `PackageLicenseExpression` with predefined license constants.
- Added MSBuild settings extension methods for configuring package properties (`WithPackageProjectUrl`, `WithPackageLicenseUrl`, `WithPackageLicenseExpression`, and `WithCopyright`).
- Updated `PackTask` to utilize the new extension methods for cleaner configuration of packaging settings.
---
.../DotNetMSBuildSettingsExtensions.cs | 45 +++++++++++++++++++
.../Tasks/Templates/PackTask.cs | 9 ++--
.../Settings/PackageLicenseExpression.cs | 21 +++++++++
3 files changed, 71 insertions(+), 4 deletions(-)
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/DotNetMSBuildSettingsExtensions.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/PackageLicenseExpression.cs
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/DotNetMSBuildSettingsExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/DotNetMSBuildSettingsExtensions.cs
new file mode 100644
index 00000000..d69b2589
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/DotNetMSBuildSettingsExtensions.cs
@@ -0,0 +1,45 @@
+using Cake.Common.Tools.DotNet.MSBuild;
+
+namespace CreativeCoders.CakeBuild;
+
+public static class DotNetMSBuildSettingsExtensions
+{
+ public static DotNetMSBuildSettings WithPackageProjectUrl(this DotNetMSBuildSettings settings,
+ string packageProjectUrl)
+ {
+ return settings.SetPropertyIfNotEmpty("PackageProjectUrl", packageProjectUrl);
+ }
+
+ public static DotNetMSBuildSettings WithPackageLicenseUrl(this DotNetMSBuildSettings settings,
+ string packageLicenseUrl)
+ {
+ return settings.SetPropertyIfNotEmpty("PackageLicenseUrl", packageLicenseUrl);
+ }
+
+ public static DotNetMSBuildSettings WithPackageLicenseExpression(this DotNetMSBuildSettings settings,
+ string packageLicenseExpression)
+ {
+ return settings.SetPropertyIfNotEmpty("PackageLicenseExpression", packageLicenseExpression);
+ }
+
+ public static DotNetMSBuildSettings WithCopyright(this DotNetMSBuildSettings settings, string copyright)
+ {
+ return settings.SetPropertyIfNotEmpty("Copyright", copyright);
+ }
+
+ public static DotNetMSBuildSettings SetProperty(this DotNetMSBuildSettings settings, string propertyName,
+ string propertyValue)
+ {
+ settings.Properties[propertyName] = [propertyValue];
+ return settings;
+ }
+
+ public static DotNetMSBuildSettings SetPropertyIfNotEmpty(this DotNetMSBuildSettings settings,
+ string propertyName,
+ string? propertyValue)
+ {
+ return string.IsNullOrEmpty(propertyValue)
+ ? settings
+ : settings.SetProperty(propertyName, propertyValue);
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
index d4afdaf5..02f0a519 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/PackTask.cs
@@ -36,10 +36,11 @@ private DotNetPackSettings CreateDotNetPackSettings(T context, IPackTaskSettings
}
};
- dotNetPackSettings.MSBuildSettings.WithProperty("PackageProjectUrl", packSettings.PackageProjectUrl);
- dotNetPackSettings.MSBuildSettings.WithProperty("PackageLicenseExpression",
- packSettings.PackageLicenseExpression);
- dotNetPackSettings.MSBuildSettings.WithProperty("PackageLicenseUrl", packSettings.PackageLicenseUrl);
+ dotNetPackSettings.MSBuildSettings
+ .WithPackageProjectUrl(packSettings.PackageProjectUrl)
+ .WithPackageLicenseUrl(packSettings.PackageLicenseUrl)
+ .WithPackageLicenseExpression(packSettings.PackageLicenseExpression)
+ .WithCopyright(packSettings.Copyright);
return dotNetPackSettings;
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/PackageLicenseExpression.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/PackageLicenseExpression.cs
new file mode 100644
index 00000000..b1b93938
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/PackageLicenseExpression.cs
@@ -0,0 +1,21 @@
+using JetBrains.Annotations;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+[PublicAPI]
+public static class PackageLicenseExpression
+{
+ public const string LGPL30Only = "LGPL-3.0-only";
+
+ public const string LGPL30OrLater = "LGPL-3.0-or-later";
+
+ public const string MIT = "MIT";
+
+ public const string GPL30Only = "GPL-3.0-only";
+
+ public const string GPL30OrLater = "GPL-3.0-or-later";
+
+ public const string ApacheLicense20 = "Apache-2.0";
+
+ public const string MPL20 = "MPL-2.0";
+}
From 448393701bedd9d74886ce0693a2dcb54b69fee3 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Wed, 7 Jan 2026 19:05:49 +0100
Subject: [PATCH 43/73] Rename `NuGetPublishTask` to `NuGetPushTask` and
implement push functionality
- Updated class, interfaces, and settings from `NuGetPublish` to `NuGetPush` for consistency with naming conventions.
- Added NuGet push implementation using `DotNetNuGetPush` with configurable settings.
- Extended `IDefaultTaskSettings` to include `INuGetPushTaskSettings`.
---
.../CakeHostExtensions.cs | 2 +-
.../Tasks/Defaults/IDefaultTaskSettings.cs | 8 +++-
.../{NuGetPublishTask.cs => NuGetPushTask.cs} | 2 +-
.../Tasks/Templates/NuGetPublishTask.cs | 9 ----
.../Tasks/Templates/NuGetPushTask.cs | 41 +++++++++++++++++++
.../Settings/INuGetPublishTaskSettings.cs | 4 --
.../Settings/INuGetPushTaskSettings.cs | 11 +++++
7 files changed, 60 insertions(+), 17 deletions(-)
rename source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/{NuGetPublishTask.cs => NuGetPushTask.cs} (73%)
delete mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
create mode 100755 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPushTask.cs
delete mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
create mode 100644 source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPushTaskSettings.cs
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
index a0dc5c8c..07a84a8c 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostExtensions.cs
@@ -64,7 +64,7 @@ public static CakeHost AddDefaultTasks(this CakeHost host)
typeof(TestTask),
typeof(CodeCoverageTask),
typeof(PackTask),
- typeof(NuGetPublishTask));
+ typeof(NuGetPushTask));
}
public static CakeHost AddBuildServerIntegration(this CakeHost host)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
index a1543cbe..60885f0f 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/IDefaultTaskSettings.cs
@@ -2,5 +2,9 @@
namespace CreativeCoders.CakeBuild.Tasks.Defaults;
-public interface IDefaultTaskSettings : ICleanTaskSettings, ITestTaskSettings, ICodeCoverageTaskSettings,
- IPackTaskSettings { }
+public interface IDefaultTaskSettings :
+ ICleanTaskSettings,
+ ITestTaskSettings,
+ ICodeCoverageTaskSettings,
+ IPackTaskSettings,
+ INuGetPushTaskSettings;
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs
similarity index 73%
rename from source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs
rename to source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs
index e401e7b8..f0711290 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPublishTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs
@@ -5,4 +5,4 @@ namespace CreativeCoders.CakeBuild.Tasks.Defaults;
[TaskName("NuGetPublish")]
[IsDependentOn(typeof(PackTask))]
-public class NuGetPublishTask : NuGetPublishTask { }
+public class NuGetPushTask : NuGetPushTask { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
deleted file mode 100755
index 808517d3..00000000
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPublishTask.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates;
-
-public class NuGetPublishTask : FrostingTaskBase where T : BuildContext
-{
- protected override Task RunAsyncCore(T context)
- {
- throw new NotImplementedException();
- }
-}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPushTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPushTask.cs
new file mode 100755
index 00000000..3b08d58f
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/NuGetPushTask.cs
@@ -0,0 +1,41 @@
+using Cake.Common.Diagnostics;
+using Cake.Common.Tools.DotNet;
+using Cake.Common.Tools.DotNet.NuGet.Push;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+namespace CreativeCoders.CakeBuild.Tasks.Templates;
+
+public class NuGetPushTask : FrostingTaskBase where T : BuildContext
+{
+ protected override Task RunAsyncCore(T context)
+ {
+ var pushSettings = context.GetSettings();
+
+ if (pushSettings.SkipPush)
+ {
+ context.Information("Skip NuGet push");
+ return Task.CompletedTask;
+ }
+
+ var packSettings = context.GetSettings();
+
+ var filePath = packSettings.OutputDirectory.GetFilePath("*.nupkg");
+
+ context.DotNetNuGetPush(filePath, CreateNuGetPushSettings(pushSettings));
+
+ return Task.CompletedTask;
+ }
+
+ private static DotNetNuGetPushSettings CreateNuGetPushSettings(INuGetPushTaskSettings settings)
+ {
+ var nugetPushSettings = new DotNetNuGetPushSettings
+ {
+ Source = settings.NuGetFeedUrl,
+ ApiKey = settings.NuGetApiKey,
+ SkipDuplicate = true,
+ IgnoreSymbols = false
+ };
+
+ return nugetPushSettings;
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
deleted file mode 100644
index 8f76aee6..00000000
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPublishTaskSettings.cs
+++ /dev/null
@@ -1,4 +0,0 @@
-namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
-
-[CakeTaskSettings]
-public interface INuGetPublishTaskSettings { }
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPushTaskSettings.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPushTaskSettings.cs
new file mode 100644
index 00000000..e10aa5d9
--- /dev/null
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/INuGetPushTaskSettings.cs
@@ -0,0 +1,11 @@
+namespace CreativeCoders.CakeBuild.Tasks.Templates.Settings;
+
+[CakeTaskSettings]
+public interface INuGetPushTaskSettings
+{
+ string NuGetFeedUrl => string.Empty;
+
+ string NuGetApiKey => string.Empty;
+
+ bool SkipPush => false;
+}
From 2f48d58974414fe110bcef912f3485abdb262ca6 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Wed, 7 Jan 2026 19:06:05 +0100
Subject: [PATCH 44/73] Rename `[TaskName]` from `NuGetPublish` to `NuGetPush`
for consistency with task naming conventions.
---
.../CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs
index f0711290..4b45190d 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Defaults/NuGetPushTask.cs
@@ -3,6 +3,6 @@
namespace CreativeCoders.CakeBuild.Tasks.Defaults;
-[TaskName("NuGetPublish")]
+[TaskName("NuGetPush")]
[IsDependentOn(typeof(PackTask))]
public class NuGetPushTask : NuGetPushTask { }
From a5cff4a48aa22f85d59aa5ada6da34a2098370a4 Mon Sep 17 00:00:00 2001
From: darthsharp <48331467+darthsharp@users.noreply.github.com>
Date: Sat, 10 Jan 2026 13:35:03 +0100
Subject: [PATCH 45/73] - Update task settings to use `GetRequiredSettings`
for improved error handling - Add `DefaultHostSetup` to summarize setup
configuration during execution - Rename `PackageLicenseExpression` to
`PackageLicenseExpressions` for consistency - Introduce `PrintSetupSummary`
property for better control over setup logging - Enhance integration workflow
for NuGet push with added `NUGET_TOKEN` configuration
---
.github/workflows/integration.yml | 9 +++---
samples/CakeBuildSample/SampleBuildContext.cs | 22 ++++++++++++--
.../CreativeCoders.CakeBuild/BuildContext.cs | 14 +++++++--
.../CakeHostBuilder.cs | 30 +++++++++++++++++++
.../CreativeCoders.CakeBuild/IBuildContext.cs | 4 ++-
.../Tasks/Templates/BuildTask.cs | 3 +-
.../Tasks/Templates/CleanTask.cs | 2 +-
.../Tasks/Templates/CodeCoverageTask.cs | 2 +-
.../Tasks/Templates/NuGetPushTask.cs | 4 +--
.../Tasks/Templates/PackTask.cs | 2 +-
.../Templates/Settings/ICleanTaskSettings.cs | 2 ++
.../Settings/INuGetPushTaskSettings.cs | 6 ++--
...ession.cs => PackageLicenseExpressions.cs} | 2 +-
.../Tasks/Templates/TestTask.cs | 2 +-
14 files changed, 83 insertions(+), 21 deletions(-)
rename source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/Settings/{PackageLicenseExpression.cs => PackageLicenseExpressions.cs} (91%)
diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index 3e8cbfb5..f7f4b928 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -40,11 +40,12 @@ jobs:
# ~/.nuget/packages
# key: ${{ runner.os }}-${{ hashFiles('**/global.json', '**/*.csproj', '**/Directory.Packages.props') }}
- name: 'Run: DeployNuGet'
- run: |
- cd ./samples/CakeBuildSample
- dotnet run -- -t codecoverage
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ NUGET_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ cd ./samples/CakeBuildSample
+ dotnet run -- -t nugetpush
# - name: 'Publish: coverage_report'
# uses: actions/upload-artifact@v4
# if: runner.os == 'Linux'
@@ -68,7 +69,7 @@ jobs:
- name: 'Run: DeployNuGet'
run: |
cd ./samples/CakeBuildSample
- dotnet run -- -t codecoverage
+ dotnet run -- -t nugetpush
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# - name: 'Publish: coverage_report'
diff --git a/samples/CakeBuildSample/SampleBuildContext.cs b/samples/CakeBuildSample/SampleBuildContext.cs
index 068c3ea8..90c8b099 100644
--- a/samples/CakeBuildSample/SampleBuildContext.cs
+++ b/samples/CakeBuildSample/SampleBuildContext.cs
@@ -1,3 +1,4 @@
+using Cake.Common.Build;
using Cake.Core;
using Cake.Core.IO;
using CreativeCoders.CakeBuild;
@@ -5,13 +6,28 @@
using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using CreativeCoders.Core;
using CreativeCoders.Core.Collections;
+using JetBrains.Annotations;
namespace CakeBuildSample;
-public class SampleBuildContext : BuildContext, IDefaultTaskSettings
+[UsedImplicitly]
+public class SampleBuildContext(ICakeContext context) : BuildContext(context), IDefaultTaskSettings
{
- public SampleBuildContext(ICakeContext context) : base(context) { }
-
public IList DirectoriesToClean => this.CastAs()
.GetDefaultDirectoriesToClean().AddRange(RootDir.Combine(".tests"));
+
+
+ public string Copyright => $"{DateTime.Now.Year} CreativeCoders";
+
+ public string PackageProjectUrl => "https://github.com/CreativeCodersTeam/Core";
+
+ public string PackageLicenseExpression => PackageLicenseExpressions.ApacheLicense20;
+
+ public string NuGetFeedUrl => this.GitHubActions().Environment.Workflow.Workflow == "release"
+ ? "nuget.org"
+ : "https://nuget.pkg.github.com/CreativeCodersTeam/index.json";
+
+ public bool SkipPush => this.BuildSystem().IsPullRequest ||
+ this.BuildSystem().IsLocalBuild ||
+ this.GitHubActions().Environment.Runner.OS != "Linux";
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
index 05cc583f..46673389 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/BuildContext.cs
@@ -93,6 +93,8 @@ private FilePath FindRootSolution(ICakeContext context)
public IList ExecutedTasks => _executedTasks;
+ public bool PrintSetupSummary => true;
+
public void AddExecutedTask(IFrostingTask task)
{
_executedTasks.Add(task);
@@ -103,11 +105,19 @@ public bool HasExecutedTask(Type taskType)
return _executedTasks.Any(x => x.GetType().IsAssignableTo(taskType));
}
- public T GetSettings() where T : class
+ public T GetRequiredSettings()
+ where T : class
+ {
+ return GetSettings()
+ ?? throw new InvalidOperationException($"No settings of type '{typeof(T).Name}' found");
+ }
+
+ public T? GetSettings()
+ where T : class
{
return this as T
?? FindSettingsProperty()
- ?? throw new InvalidOperationException($"No settings of type '{typeof(T).Name}' found");
+ ?? null;
}
private T? FindSettingsProperty()
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs
index beb885d5..d8b55ed6 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/CakeHostBuilder.cs
@@ -1,5 +1,9 @@
+using Cake.Common.Diagnostics;
+using Cake.Core;
using Cake.Frosting;
+using CreativeCoders.CakeBuild.Tasks.Templates.Settings;
using CreativeCoders.Core;
+using JetBrains.Annotations;
namespace CreativeCoders.CakeBuild;
@@ -77,6 +81,32 @@ public CakeHost Build()
_cakeHost.UseContext();
}
+ _cakeHost.UseSetup();
+
return _cakeHost;
}
}
+
+[UsedImplicitly]
+public class DefaultHostSetup : IFrostingSetup
+{
+ public void Setup(ICakeContext context, ISetupContext info)
+ {
+ if (context is not BuildContext buildContext)
+ {
+ return;
+ }
+
+ if (!buildContext.PrintSetupSummary)
+ {
+ return;
+ }
+
+ var pushSettings = buildContext.GetSettings();
+
+ if (pushSettings != null)
+ {
+ context.Information($"Skip Push: {pushSettings.SkipPush}");
+ }
+ }
+}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
index e7091f7b..01c4e2ed 100644
--- a/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/IBuildContext.cs
@@ -25,12 +25,14 @@ public interface IBuildContext : ICakeContext
GitVersion Version { get; }
+ bool PrintSetupSummary { get; }
+
IList ExecutedTasks { get; }
void AddExecutedTask(IFrostingTask task);
bool HasExecutedTask(Type taskType);
- T GetSettings()
+ T GetRequiredSettings()
where T : class;
}
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
index 480de321..e4bad9b8 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/BuildTask.cs
@@ -25,7 +25,8 @@ private DotNetBuildSettings CreateDotNetBuildSettings(T context)
InformationalVersion = context.Version.InformationalVersion,
AssemblyVersion = context.Version.AssemblySemVer,
FileVersion = context.Version.AssemblySemFileVer,
- PackageVersion = context.Version.SemVer
+ PackageVersion = context.Version.SemVer,
+ Version = context.Version.SemVer
}
};
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
index 512f0431..664d384f 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CleanTask.cs
@@ -9,7 +9,7 @@ public class CleanTask : FrostingTaskBase where T : BuildContext
{
protected override Task RunAsyncCore(T context)
{
- var settings = context.GetSettings();
+ var settings = context.GetRequiredSettings();
DeleteDirectories(context, settings.DirectoriesToClean);
diff --git a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
index cc4ece41..bc9e297d 100755
--- a/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
+++ b/source/CakeBuild/CreativeCoders.CakeBuild/Tasks/Templates/CodeCoverageTask.cs
@@ -10,7 +10,7 @@ public class CodeCoverageTask