From 38d748673a60f2da46580ee83b6cf723cead55e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sun, 18 Oct 2026 10:23:07 +0200 Subject: [PATCH] build: migrate the build pipeline from Nuke to Fallout The other Testably repositories build with Fallout, so Mockolate is the odd one out in its build scripts, pipeline code, Dependabot groups and tooling folder. Moving it over lets the pipelines be shared and aligned across the repositories. The SDK pin follows them too and only rolls forward to new patches. --- {.nuke => .fallout}/build.schema.json | 17 ++++++++++++----- {.nuke => .fallout}/parameters.json | 1 + .github/dependabot.yml | 4 ++-- .gitignore | 3 +++ AGENTS.md | 2 +- Directory.Packages.props | 5 +++-- Docs/agents/project-structure.md | 2 +- Docs/agents/workflows.md | 4 ++-- Pipeline/Build.ApiChecks.cs | 10 +++++----- Pipeline/Build.Benchmarks.cs | 14 +++++++------- Pipeline/Build.CodeAnalysis.cs | 4 ++-- Pipeline/Build.CodeCoverage.cs | 8 ++++---- Pipeline/Build.Compile.cs | 14 +++++++------- Pipeline/Build.MutationTests.cs | 14 +++++++------- Pipeline/Build.Pack.cs | 8 ++++---- Pipeline/Build.UnitTest.cs | 10 +++++----- Pipeline/Build.cs | 12 ++++++------ Pipeline/Build.csproj | 10 +++++----- Pipeline/BuildExtensions.cs | 6 +++--- Pipeline/Configuration.cs | 2 +- Source/Directory.Build.props | 2 +- build.ps1 | 7 +------ build.sh | 7 +------ global.json | 2 +- 24 files changed, 85 insertions(+), 83 deletions(-) rename {.nuke => .fallout}/build.schema.json (88%) rename {.nuke => .fallout}/parameters.json (59%) diff --git a/.nuke/build.schema.json b/.fallout/build.schema.json similarity index 88% rename from .nuke/build.schema.json rename to .fallout/build.schema.json index 42be27abc..8d7001157 100644 --- a/.nuke/build.schema.json +++ b/.fallout/build.schema.json @@ -58,7 +58,7 @@ "Quiet" ] }, - "NukeBuild": { + "FalloutBuild": { "properties": { "Continue": { "type": "boolean", @@ -112,6 +112,13 @@ "Verbosity": { "description": "Logging verbosity during build execution. Default is 'Normal'", "$ref": "#/definitions/Verbosity" + }, + "BuildProjectFile": { + "type": [ + "null", + "string" + ], + "description": "Path to the build project (.csproj) relative to the repository root. Defaults to 'build/_build.csproj' when unset. Read by the Fallout global tool's in-tool runner." } } } @@ -125,11 +132,11 @@ }, "Configuration": { "type": "string", - "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)", "enum": [ "Debug", "Release" - ] + ], + "description": "Configuration to build - Default is 'Debug' (local) or 'Release' (server)" }, "GithubToken": { "type": "string", @@ -142,12 +149,12 @@ "SonarToken": { "type": "string", "description": "The key to push to sonarcloud", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" + "default": "Secrets must be entered via 'fallout :secrets [profile]'" } } }, { - "$ref": "#/definitions/NukeBuild" + "$ref": "#/definitions/FalloutBuild" } ] } diff --git a/.nuke/parameters.json b/.fallout/parameters.json similarity index 59% rename from .nuke/parameters.json rename to .fallout/parameters.json index 512285103..bba249120 100644 --- a/.nuke/parameters.json +++ b/.fallout/parameters.json @@ -1,4 +1,5 @@ { "$schema": "build.schema.json", + "BuildProjectFile": "Pipeline/Build.csproj", "Solution": "Mockolate.slnx" } diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 15b9d36d1..39b08e4b7 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -20,9 +20,9 @@ updates: commit-message: prefix: chore groups: - nuke: + fallout: patterns: - - "Nuke*" + - "Fallout*" xunit: patterns: - "xunit*" diff --git a/.gitignore b/.gitignore index 355619c97..47a099db7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,9 @@ /Artifacts /TestResults +# Fallout temporary files +.fallout/temp/ + # Temporary files from Sonarqube .sonarqube/ diff --git a/AGENTS.md b/AGENTS.md index cf1d42e35..4de2825d8 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -50,5 +50,5 @@ Correctness is a must. The other goals are strong defaults and win in this order ## References - [Design goals](Docs/agents/design-goals.md): the goals and code rules for every change, the checks before a commit and the goals of this repository. -- [Workflows](Docs/agents/workflows.md): build, test, snapshot, benchmark, mutation, AOT and documentation commands, the Nuke targets in `Pipeline/` and the CI workflows. +- [Workflows](Docs/agents/workflows.md): build, test, snapshot, benchmark, mutation, AOT and documentation commands, the Fallout targets in `Pipeline/` and the CI workflows. - [Project structure](Docs/agents/project-structure.md): projects, architecture and where code lives. diff --git a/Directory.Packages.props b/Directory.Packages.props index c12dfeb02..4ff7250fe 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,10 +8,11 @@ - - + + + diff --git a/Docs/agents/project-structure.md b/Docs/agents/project-structure.md index a4bc65fad..6f7d9b95f 100644 --- a/Docs/agents/project-structure.md +++ b/Docs/agents/project-structure.md @@ -7,7 +7,7 @@ | `Source/` | The shipped projects | | `Tests/` | Test projects and the AOT smoke test app | | `Benchmarks/` | BenchmarkDotNet comparison with other mocking libraries | -| `Pipeline/` | Nuke build (`Build.csproj`) and the benchmark report generator | +| `Pipeline/` | Fallout build (`Build.csproj`) and the benchmark report generator | | `Docs/pages/` | User docs published to https://docs.testably.org/Mockolate/ | | `Docs/agents/` | Guides for contributors and agents (this folder) | | `.github/` | CI workflows, Dependabot and Mergify configuration | diff --git a/Docs/agents/workflows.md b/Docs/agents/workflows.md index ceddf8d94..3c8da5c91 100644 --- a/Docs/agents/workflows.md +++ b/Docs/agents/workflows.md @@ -104,9 +104,9 @@ Stryker mutates `Source/Mockolate` against `Mockolate.Tests` and `Mockolate.Inte Reports go to `Artifacts/Stryker`. The `MutationTests` target also prepares the PR comment and expects to run in GitHub Actions. -## Build Pipeline (Nuke) +## Build Pipeline (Fallout) -`Pipeline/Build.csproj` is a Nuke build, started through `build.ps1`, `build.sh` or `build.cmd`. Always name a target: without one, Nuke runs the defaults `ApiChecks`, `Benchmarks` and `CodeAnalysis`. `./build.ps1 --help` lists the targets. The configuration is Debug locally and Release on CI. Every run cleans `Artifacts/` and `TestResults/` first. +`Pipeline/Build.csproj` is a Fallout build, started through `build.ps1`, `build.sh` or `build.cmd`. Always name a target: without one, Fallout runs the defaults `ApiChecks`, `Benchmarks` and `CodeAnalysis`. `./build.ps1 --help` lists the targets. The configuration is Debug locally and Release on CI. Every run cleans `Artifacts/` and `TestResults/` first. | Target | Purpose | |---|---| diff --git a/Pipeline/Build.ApiChecks.cs b/Pipeline/Build.ApiChecks.cs index d1b95bb19..fee643576 100644 --- a/Pipeline/Build.ApiChecks.cs +++ b/Pipeline/Build.ApiChecks.cs @@ -1,8 +1,8 @@ -using Nuke.Common; -using Nuke.Common.ProjectModel; -using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using Fallout.Common; +using Fallout.Solutions; +using Fallout.Common.Tooling; +using Fallout.Common.Tools.DotNet; +using static Fallout.Common.Tools.DotNet.DotNetTasks; // ReSharper disable AllUnderscoreLocalParameterName diff --git a/Pipeline/Build.Benchmarks.cs b/Pipeline/Build.Benchmarks.cs index f70e688e3..641852ec4 100644 --- a/Pipeline/Build.Benchmarks.cs +++ b/Pipeline/Build.Benchmarks.cs @@ -3,14 +3,14 @@ using System.IO; using System.Linq; using System.Threading.Tasks; -using Nuke.Common; -using Nuke.Common.IO; -using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; -using Nuke.Common.Tools.Git; +using Fallout.Common; +using Fallout.Common.IO; +using Fallout.Common.Tooling; +using Fallout.Common.Tools.DotNet; +using Fallout.Common.Tools.Git; using Octokit; using Serilog; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using static Fallout.Common.Tools.DotNet.DotNetTasks; // ReSharper disable AllUnderscoreLocalParameterName @@ -101,7 +101,7 @@ partial class Build Log.Debug("Pull request number: {PullRequestId}", prNumber); if (int.TryParse(prNumber, out int prId)) { - GitHubClient gitHubClient = new(new ProductHeaderValue("Nuke")); + GitHubClient gitHubClient = new(new ProductHeaderValue("Fallout")); Credentials tokenAuth = new(GithubToken); gitHubClient.Credentials = tokenAuth; IReadOnlyList comments = diff --git a/Pipeline/Build.CodeAnalysis.cs b/Pipeline/Build.CodeAnalysis.cs index 4e94a5ddc..ec5c70199 100644 --- a/Pipeline/Build.CodeAnalysis.cs +++ b/Pipeline/Build.CodeAnalysis.cs @@ -1,5 +1,5 @@ -using Nuke.Common; -using Nuke.Common.Tools.SonarScanner; +using Fallout.Common; +using Fallout.Common.Tools.SonarScanner; // ReSharper disable AllUnderscoreLocalParameterName diff --git a/Pipeline/Build.CodeCoverage.cs b/Pipeline/Build.CodeCoverage.cs index 230874e6b..7631d451a 100644 --- a/Pipeline/Build.CodeCoverage.cs +++ b/Pipeline/Build.CodeCoverage.cs @@ -1,7 +1,7 @@ -using Nuke.Common; -using Nuke.Common.Tooling; -using Nuke.Common.Tools.ReportGenerator; -using static Nuke.Common.Tools.ReportGenerator.ReportGeneratorTasks; +using Fallout.Common; +using Fallout.Common.Tooling; +using Fallout.Common.Tools.ReportGenerator; +using static Fallout.Common.Tools.ReportGenerator.ReportGeneratorTasks; // ReSharper disable AllUnderscoreLocalParameterName diff --git a/Pipeline/Build.Compile.cs b/Pipeline/Build.Compile.cs index f035ffa10..1cd95957d 100644 --- a/Pipeline/Build.Compile.cs +++ b/Pipeline/Build.Compile.cs @@ -1,13 +1,13 @@ using System; using System.Linq; -using Nuke.Common; -using Nuke.Common.IO; -using Nuke.Common.Tools.DotNet; -using Nuke.Common.Tools.GitVersion; -using Nuke.Common.Utilities; -using Nuke.Common.Utilities.Collections; +using Fallout.Common; +using Fallout.Common.IO; +using Fallout.Common.Tools.DotNet; +using Fallout.Common.Tools.GitVersion; +using Fallout.Common.Utilities; +using Fallout.Common.Utilities.Collections; using Serilog; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using static Fallout.Common.Tools.DotNet.DotNetTasks; // ReSharper disable AllUnderscoreLocalParameterName diff --git a/Pipeline/Build.MutationTests.cs b/Pipeline/Build.MutationTests.cs index e2545ebb1..dedfd0bb3 100644 --- a/Pipeline/Build.MutationTests.cs +++ b/Pipeline/Build.MutationTests.cs @@ -5,15 +5,15 @@ using System.Net.Http; using System.Net.Http.Headers; using System.Text; -using Nuke.Common; -using Nuke.Common.IO; -using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; +using Fallout.Common; +using Fallout.Common.IO; +using Fallout.Common.Tooling; +using Fallout.Common.Tools.DotNet; using Octokit; using Serilog; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using static Fallout.Common.Tools.DotNet.DotNetTasks; using ProductHeaderValue = Octokit.ProductHeaderValue; -using Project = Nuke.Common.ProjectModel.Project; +using Project = Fallout.Solutions.Project; // ReSharper disable UnusedMember.Local // ReSharper disable AllUnderscoreLocalParameterName @@ -176,7 +176,7 @@ await client.PutAsync( string body = File.ReadAllText(ArtifactsDirectory / "PR_Comment.md"); if (int.TryParse(prNumber, out int prId)) { - GitHubClient gitHubClient = new(new ProductHeaderValue("Nuke")); + GitHubClient gitHubClient = new(new ProductHeaderValue("Fallout")); Credentials tokenAuth = new(GithubToken); gitHubClient.Credentials = tokenAuth; IReadOnlyList comments = diff --git a/Pipeline/Build.Pack.cs b/Pipeline/Build.Pack.cs index 3118eb3b1..16df45eda 100644 --- a/Pipeline/Build.Pack.cs +++ b/Pipeline/Build.Pack.cs @@ -2,10 +2,10 @@ using System.IO; using System.Linq; using System.Text; -using Nuke.Common; -using Nuke.Common.IO; -using Nuke.Common.ProjectModel; -using Nuke.Common.Utilities.Collections; +using Fallout.Common; +using Fallout.Common.IO; +using Fallout.Solutions; +using Fallout.Common.Utilities.Collections; using static Serilog.Log; // ReSharper disable AllUnderscoreLocalParameterName diff --git a/Pipeline/Build.UnitTest.cs b/Pipeline/Build.UnitTest.cs index 78f32d740..6b1533e9e 100644 --- a/Pipeline/Build.UnitTest.cs +++ b/Pipeline/Build.UnitTest.cs @@ -1,9 +1,9 @@ using System.Linq; -using Nuke.Common; -using Nuke.Common.ProjectModel; -using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using Fallout.Common; +using Fallout.Solutions; +using Fallout.Common.Tooling; +using Fallout.Common.Tools.DotNet; +using static Fallout.Common.Tools.DotNet.DotNetTasks; // ReSharper disable AllUnderscoreLocalParameterName diff --git a/Pipeline/Build.cs b/Pipeline/Build.cs index 439c929bf..8f0a9ad27 100644 --- a/Pipeline/Build.cs +++ b/Pipeline/Build.cs @@ -1,8 +1,8 @@ -using Nuke.Common; -using Nuke.Common.CI.GitHubActions; -using Nuke.Common.IO; -using Nuke.Common.ProjectModel; -using Nuke.Common.Tools.GitVersion; +using Fallout.Common; +using Fallout.Common.CI.GitHubActions; +using Fallout.Common.IO; +using Fallout.Solutions; +using Fallout.Common.Tools.GitVersion; namespace Build; @@ -12,7 +12,7 @@ namespace Build; AutoGenerate = false, ImportSecrets = [nameof(GithubToken),] )] -partial class Build : NukeBuild +partial class Build : FalloutBuild { [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; diff --git a/Pipeline/Build.csproj b/Pipeline/Build.csproj index b30b9d14f..cd7dc33f4 100644 --- a/Pipeline/Build.csproj +++ b/Pipeline/Build.csproj @@ -4,9 +4,8 @@ Exe net10.0 CS0649;CS0169;CA1050;CA1822;CA2211;IDE1006;CS8632;NU1901;NU1902;NU1903 - .. - .. - 1 + .. + .. false @@ -21,8 +20,9 @@ - - + + + diff --git a/Pipeline/BuildExtensions.cs b/Pipeline/BuildExtensions.cs index 7e6f762e2..2c1decfa4 100644 --- a/Pipeline/BuildExtensions.cs +++ b/Pipeline/BuildExtensions.cs @@ -7,9 +7,9 @@ using System.Text; using System.Text.Json; using System.Threading.Tasks; -using Nuke.Common.CI.GitHubActions; -using Nuke.Common.Tools.GitVersion; -using Nuke.Common.Tools.SonarScanner; +using Fallout.Common.CI.GitHubActions; +using Fallout.Common.Tools.GitVersion; +using Fallout.Common.Tools.SonarScanner; using Serilog; namespace Build; diff --git a/Pipeline/Configuration.cs b/Pipeline/Configuration.cs index 82b0beadc..5a4d2e493 100644 --- a/Pipeline/Configuration.cs +++ b/Pipeline/Configuration.cs @@ -1,5 +1,5 @@ using System.ComponentModel; -using Nuke.Common.Tooling; +using Fallout.Common.Tooling; [TypeConverter(typeof(TypeConverter))] public class Configuration : Enumeration diff --git a/Source/Directory.Build.props b/Source/Directory.Build.props index fa71b8e77..25e8d1b5a 100644 --- a/Source/Directory.Build.props +++ b/Source/Directory.Build.props @@ -74,7 +74,7 @@ + In the build pipeline it is overwritten with the actual version in the `fallout Compile` step --> 255.255.255.255 diff --git a/build.ps1 b/build.ps1 index 8b218a560..a8e1ed7c4 100644 --- a/build.ps1 +++ b/build.ps1 @@ -14,7 +14,7 @@ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent ########################################################################### $BuildProjectFile = "$PSScriptRoot\Pipeline\Build.csproj" -$TempDirectory = "$PSScriptRoot\\.nuke\temp" +$TempDirectory = "$PSScriptRoot\\.fallout\temp" $DotNetGlobalFile = "$PSScriptRoot\\global.json" $DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" @@ -65,10 +65,5 @@ else { Write-Output "Microsoft (R) .NET SDK version $(& $env:DOTNET_EXE --version)" -if (Test-Path env:NUKE_ENTERPRISE_TOKEN) { - & $env:DOTNET_EXE nuget remove source "nuke-enterprise" > $null - & $env:DOTNET_EXE nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password $env:NUKE_ENTERPRISE_TOKEN > $null -} - ExecSafe { & $env:DOTNET_EXE build $BuildProjectFile /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet } ExecSafe { & $env:DOTNET_EXE run --project $BuildProjectFile --no-build -- $BuildArguments } diff --git a/build.sh b/build.sh index 46f2bac0a..131453d33 100755 --- a/build.sh +++ b/build.sh @@ -10,7 +10,7 @@ SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) ########################################################################### BUILD_PROJECT_FILE="$SCRIPT_DIR/Pipeline/Build.csproj" -TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp" +TEMP_DIRECTORY="$SCRIPT_DIR//.fallout/temp" DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh" @@ -58,10 +58,5 @@ fi echo "Microsoft (R) .NET SDK version $("$DOTNET_EXE" --version)" -if [[ ! -z ${NUKE_ENTERPRISE_TOKEN+x} && "$NUKE_ENTERPRISE_TOKEN" != "" ]]; then - "$DOTNET_EXE" nuget remove source "nuke-enterprise" &>/dev/null || true - "$DOTNET_EXE" nuget add source "https://f.feedz.io/nuke/enterprise/nuget" --name "nuke-enterprise" --username "PAT" --password "$NUKE_ENTERPRISE_TOKEN" --store-password-in-clear-text &>/dev/null || true -fi - "$DOTNET_EXE" build "$BUILD_PROJECT_FILE" /nodeReuse:false /p:UseSharedCompilation=false -nologo -clp:NoSummary --verbosity quiet "$DOTNET_EXE" run --project "$BUILD_PROJECT_FILE" --no-build -- "$@" diff --git a/global.json b/global.json index 9cfde950a..00ba24c2b 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { "version": "10.0.300", - "rollForward": "latestMinor" + "rollForward": "latestPatch" } }