diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json new file mode 100644 index 000000000..a8483d332 --- /dev/null +++ b/.config/dotnet-tools.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "isRoot": true, + "tools": { + "fallout.globaltool": { + "version": "10.4.0", + "commands": [ + "fallout" + ] + } + } +} 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 6c323a9c0..c762f7ff0 100644 --- a/.nuke/build.schema.json +++ b/.fallout/build.schema.json @@ -51,7 +51,7 @@ "Quiet" ] }, - "NukeBuild": { + "FalloutBuild": { "properties": { "Continue": { "type": "boolean", @@ -105,6 +105,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." } } } @@ -118,15 +125,15 @@ }, "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)" }, "NuGetApiKey": { "type": "string", - "default": "Secrets must be entered via 'nuke :secrets [profile]'" + "default": "Secrets must be entered via 'fallout :secrets [profile]'" }, "NuGetSource": { "type": "string" @@ -157,7 +164,7 @@ } }, { - "$ref": "#/definitions/NukeBuild" + "$ref": "#/definitions/FalloutBuild" } ] } diff --git a/.fallout/parameters.json b/.fallout/parameters.json new file mode 100644 index 000000000..b1b94afb6 --- /dev/null +++ b/.fallout/parameters.json @@ -0,0 +1,5 @@ +{ + "$schema": "./build.schema.json", + "Solution": "Spring.Net.sln", + "BuildProjectFile": "build-support/build/_build.csproj" +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index f84af230b..b9102f1a3 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ _ReSharper*/ #Project files [Bb]uild/ +!/build-support/build/ s3-credentials.ps1 TIBCO.EMS.* @@ -88,5 +89,5 @@ project.lock.json BenchmarkDotNet.Artifacts* /artifacts -/.nuke/temp +/.fallout/temp node_modules \ No newline at end of file diff --git a/.nuke/parameters.json b/.nuke/parameters.json deleted file mode 100644 index cd89d7cd9..000000000 --- a/.nuke/parameters.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "$schema": "./build.schema.json", - "Solution": "Spring.Net.sln" -} \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 5c21793c5..f0719902c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -8,7 +8,7 @@ Spring.NET is a port and extension of the Java Spring Framework for .NET: IoC co ## Build and test commands -Build orchestration is NUKE (`build-support/nuke-build`). Root-level bootstrap scripts install the pinned .NET SDK if missing (`global.json`: 10.0.100, rollForward latestMinor). +Build orchestration is Fallout (`build-support/build`), the maintained successor to NUKE. Root-level bootstrap scripts install the pinned .NET SDK if missing (`global.json`: 10.0.100, rollForward latestMinor), then run the build through the `fallout` local tool (`dotnet tool restore` + `dotnet fallout`). ``` ./build.cmd # Windows (build.sh on Linux/macOS); default target = Compile @@ -34,7 +34,7 @@ dotnet test test/Spring/Spring.Core.Tests/Spring.Core.Tests.csproj -f net8.0 --f ### Integration tests -NUKE's `Test` target excludes `*.Integration.Tests` projects (and `Spring.Web.Conversation.NHibernate5.Tests`) by default; they need external infrastructure and are gated behind flags: `--test-full`, `--test-integration-data`, `--test-integration-nms`, `--test-integration-ms-mq`, `--test-integration-ems`. `Spring.Services.Tests` is always excluded. Several test projects are Windows-only (net462: Web, Mvc5, Velocity, Messaging/MSMQ). +Fallout's `Test` target excludes `*.Integration.Tests` projects (and `Spring.Web.Conversation.NHibernate5.Tests`) by default; they need external infrastructure and are gated behind flags: `--test-full`, `--test-integration-data`, `--test-integration-nms`, `--test-integration-ms-mq`, `--test-integration-ems`. `Spring.Services.Tests` is always excluded. Several test projects are Windows-only (net462: Web, Mvc5, Velocity, Messaging/MSMQ). - SQL Server-backed tests (`Spring.Data.Integration.Tests`, `Spring.Data.NHibernate5.Integration.Tests`, `Spring.Scheduling.Quartz3.Integration.Tests`): `docker-compose.yml` brings up SQL Server; setup scripts in `build-support/*.sql` and the test projects' `Data/` folders. See README.md "Running tests" for the full recipe. - TIBCO EMS projects need `TIBCO.EMS.dll` (not in the repo) and are excluded from the solution build; enable with `--build-ems`. @@ -71,10 +71,10 @@ Key mechanics (defined in `src/Directory.Build.props` and `test/Directory.Build. ## Legacy areas — do not modify -- NAnt-era build files, superseded by NUKE but still committed: `Spring.build`, `*.include`, `Build-ci.cmd`, `build-release-all.cmd`, `appveyor.yml.old`, most of `build-support/` (exception: `build-support/tools/antlr-2.7.6` is still used by the `Antlr` target). +- NAnt-era build files, superseded by the Fallout build but still committed: `Spring.build`, `*.include`, `Build-ci.cmd`, `build-release-all.cmd`, `appveyor.yml.old`, most of `build-support/` (exception: `build-support/tools/antlr-2.7.6` is still used by the `Antlr` target). - `dev-support/`, `templates/` — VS 2008-era templates. `lib/` — checked-in legacy third-party DLLs. `doc/` — DocBook sources + vendored toolchain (CI ignores `doc/**`). - Orphan test folders not in the solution (reference removed projects): `test/Spring/Spring.Web.Mvc.Tests`, `Spring.Messaging.Ems.Tests`, `Spring.Data.NHibernate.Tests`. ## Website -`website/` is a Gatsby 5 + React + TypeScript site (package manager: **yarn**). Local dev: `yarn install && yarn start`. The full build is `./build.sh website` (NUKE target; also builds the DocBook reference docs, which require Java on PATH). Deployed to GitHub Pages by `.github/workflows/website.yml` on pushes to `main`. +`website/` is a Gatsby 5 + React + TypeScript site (package manager: **yarn**). Local dev: `yarn install && yarn start`. The full build is `./build.sh website` (Fallout target; also builds the DocBook reference docs, which require Java on PATH). Deployed to GitHub Pages by `.github/workflows/website.yml` on pushes to `main`. diff --git a/Directory.Packages.props b/Directory.Packages.props index 97445e544..0e675d5e3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -11,6 +11,7 @@ + @@ -25,7 +26,6 @@ - @@ -38,6 +38,6 @@ - + \ No newline at end of file diff --git a/Spring.Net.sln b/Spring.Net.sln index 90d80b2c4..a2538b351 100644 --- a/Spring.Net.sln +++ b/Spring.Net.sln @@ -102,7 +102,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Spring.Benchmark", "test\Sp EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tools", "Tools", "{9537C677-ADE5-4503-AFD7-3E0C3B0960EB}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build-support\nuke-build\_build.csproj", "{0D135B50-2B59-44C1-941A-32B5EC798C88}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "build-support\build\_build.csproj", "{0D135B50-2B59-44C1-941A-32B5EC798C88}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{C0BAC5A1-AC38-4D36-BE28-F5A74BD9FECD}" ProjectSection(SolutionItems) = preProject diff --git a/build-support/nuke-build/.editorconfig b/build-support/build/.editorconfig similarity index 100% rename from build-support/nuke-build/.editorconfig rename to build-support/build/.editorconfig diff --git a/build-support/nuke-build/Build.Documentation.cs b/build-support/build/Build.Documentation.cs similarity index 96% rename from build-support/nuke-build/Build.Documentation.cs rename to build-support/build/Build.Documentation.cs index a905e0f58..19f98fa44 100644 --- a/build-support/nuke-build/Build.Documentation.cs +++ b/build-support/build/Build.Documentation.cs @@ -1,6 +1,6 @@ -using Nuke.Common; -using Nuke.Common.IO; -using Nuke.Common.Tooling; +using Fallout.Common; +using Fallout.Common.IO; +using Fallout.Common.Tooling; public partial class Build { diff --git a/build-support/nuke-build/Build.GitHubActions.cs b/build-support/build/Build.GitHubActions.cs similarity index 84% rename from build-support/nuke-build/Build.GitHubActions.cs rename to build-support/build/Build.GitHubActions.cs index f61ff311f..738d8606e 100644 --- a/build-support/nuke-build/Build.GitHubActions.cs +++ b/build-support/build/Build.GitHubActions.cs @@ -1,4 +1,4 @@ -using Nuke.Common; +using Fallout.Common; public partial class Build { diff --git a/build-support/nuke-build/Build.Publish.cs b/build-support/build/Build.Publish.cs similarity index 88% rename from build-support/nuke-build/Build.Publish.cs rename to build-support/build/Build.Publish.cs index 205568b69..d54e8d95d 100644 --- a/build-support/nuke-build/Build.Publish.cs +++ b/build-support/build/Build.Publish.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; -using Nuke.Common; -using Nuke.Common.IO; -using Nuke.Common.Tooling; -using Nuke.Common.Tools.DotNet; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using Fallout.Common; +using Fallout.Common.IO; +using Fallout.Common.Tooling; +using Fallout.Common.Tools.DotNet; +using static Fallout.Common.Tools.DotNet.DotNetTasks; public partial class Build { diff --git a/build-support/nuke-build/Build.Test.cs b/build-support/build/Build.Test.cs similarity index 95% rename from build-support/nuke-build/Build.Test.cs rename to build-support/build/Build.Test.cs index fd1a0f5e4..27dc78a82 100644 --- a/build-support/nuke-build/Build.Test.cs +++ b/build-support/build/Build.Test.cs @@ -1,7 +1,7 @@ using System.Linq; -using Nuke.Common; -using Nuke.Common.Tools.DotNet; -using static Nuke.Common.Tools.DotNet.DotNetTasks; +using Fallout.Common; +using Fallout.Common.Tools.DotNet; +using static Fallout.Common.Tools.DotNet.DotNetTasks; public partial class Build { diff --git a/build-support/nuke-build/Build.cs b/build-support/build/Build.cs similarity index 88% rename from build-support/nuke-build/Build.cs rename to build-support/build/Build.cs index b07d3cf9d..621926b3e 100644 --- a/build-support/nuke-build/Build.cs +++ b/build-support/build/Build.cs @@ -3,30 +3,25 @@ using System.IO; using System.Linq; using System.Runtime.InteropServices; -using Nuke.Common; -using Nuke.Common.CI; -using Nuke.Common.CI.AppVeyor; -using Nuke.Common.CI.GitHubActions; -using Nuke.Common.Git; -using Nuke.Common.IO; -using Nuke.Common.ProjectModel; -using Nuke.Common.Tools.DotNet; -using Nuke.Common.Tools.MSBuild; -using Nuke.Common.Utilities.Collections; +using Fallout.Common; +using Fallout.Common.CI; +using Fallout.Common.CI.AppVeyor; +using Fallout.Common.CI.GitHubActions; +using Fallout.Common.Git; +using Fallout.Common.IO; +using Fallout.Common.Tools.DotNet; +using Fallout.Common.Tools.MSBuild; +using Fallout.Common.Utilities.Collections; +using Fallout.Solutions; using Serilog; -using static Nuke.Common.Tooling.ProcessTasks; -using static Nuke.Common.Tools.DotNet.DotNetTasks; -using static Nuke.Common.Tools.MSBuild.MSBuildTasks; +using static Fallout.Common.Tooling.ProcessTasks; +using static Fallout.Common.Tools.DotNet.DotNetTasks; +using static Fallout.Common.Tools.MSBuild.MSBuildTasks; [ShutdownDotNetAfterServerBuild] -partial class Build : NukeBuild +partial class Build : FalloutBuild { - /// Support plugins are available for: - /// - JetBrains ReSharper https://nuke.build/resharper - /// - JetBrains Rider https://nuke.build/rider - /// - Microsoft VisualStudio https://nuke.build/visualstudio - /// - Microsoft VSCode https://nuke.build/vscode public static int Main() => Execute(x => x.Compile); [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; @@ -47,7 +42,7 @@ partial class Build : NukeBuild AbsolutePath ExamplesDirectory => RootDirectory / "examples"; AbsolutePath ArtifactsDirectory => RootDirectory / "artifacts"; - string TagVersion => GitRepository.Tags.SingleOrDefault(x => x.StartsWith("v"))?[1..]; + string TagVersion => GitRepository?.Tags.SingleOrDefault(x => x.StartsWith("v"))?[1..]; bool IsTaggedBuild => !string.IsNullOrWhiteSpace(TagVersion); diff --git a/build-support/nuke-build/Configuration.cs b/build-support/build/Configuration.cs similarity index 93% rename from build-support/nuke-build/Configuration.cs rename to build-support/build/Configuration.cs index 9b22a3bd9..2e1260566 100644 --- a/build-support/nuke-build/Configuration.cs +++ b/build-support/build/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/build-support/nuke-build/Directory.Build.props b/build-support/build/Directory.Build.props similarity index 100% rename from build-support/nuke-build/Directory.Build.props rename to build-support/build/Directory.Build.props diff --git a/build-support/nuke-build/Directory.Build.targets b/build-support/build/Directory.Build.targets similarity index 100% rename from build-support/nuke-build/Directory.Build.targets rename to build-support/build/Directory.Build.targets diff --git a/build-support/build/_build.csproj b/build-support/build/_build.csproj new file mode 100644 index 000000000..5ce96c526 --- /dev/null +++ b/build-support/build/_build.csproj @@ -0,0 +1,16 @@ + + + + Exe + net10.0 + + CS0649;CS0169 + ..\.. + ..\.. + + + + + + + diff --git a/build-support/nuke-build/_build.csproj.DotSettings b/build-support/build/_build.csproj.DotSettings similarity index 100% rename from build-support/nuke-build/_build.csproj.DotSettings rename to build-support/build/_build.csproj.DotSettings diff --git a/build-support/nuke-build/_build.csproj b/build-support/nuke-build/_build.csproj deleted file mode 100644 index 91bddd5f1..000000000 --- a/build-support/nuke-build/_build.csproj +++ /dev/null @@ -1,18 +0,0 @@ - - - - Exe - net10.0 - - CS0649;CS0169 - ..\.. - ..\.. - 1 - true - - - - - - - diff --git a/build.ps1 b/build.ps1 index 44475eee2..3ea0b34c1 100644 --- a/build.ps1 +++ b/build.ps1 @@ -13,15 +13,15 @@ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent # CONFIGURATION ########################################################################### -$BuildProjectFile = "$PSScriptRoot\build-support\nuke-build\_build.csproj" -$TempDirectory = "$PSScriptRoot\\.nuke\temp" +$TempDirectory = Join-Path $PSScriptRoot '.fallout/temp' -$DotNetGlobalFile = "$PSScriptRoot\\global.json" +$DotNetGlobalFile = Join-Path $PSScriptRoot 'global.json' $DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" $DotNetChannel = "STS" $env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 $env:DOTNET_NOLOGO = 1 +$env:DOTNET_ROLL_FORWARD = "Major" ########################################################################### # EXECUTION @@ -32,19 +32,17 @@ function ExecSafe([scriptblock] $cmd) { if ($LASTEXITCODE) { exit $LASTEXITCODE } } -# If dotnet CLI is installed globally and it matches requested version, use for execution +# If dotnet CLI is installed globally, use it; otherwise provision a local copy under .fallout\temp. if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` - $(dotnet --version) -and $LASTEXITCODE -eq 0) { + $(dotnet --version) -and $LASTEXITCODE -eq 0) { $env:DOTNET_EXE = (Get-Command "dotnet").Path } else { - # Download install script - $DotNetInstallFile = "$TempDirectory\dotnet-install.ps1" + $DotNetInstallFile = Join-Path $TempDirectory 'dotnet-install.ps1' New-Item -ItemType Directory -Path $TempDirectory -Force | Out-Null [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 (New-Object System.Net.WebClient).DownloadFile($DotNetInstallUrl, $DotNetInstallFile) - # If global.json exists, load expected version if (Test-Path $DotNetGlobalFile) { $DotNetGlobal = $(Get-Content $DotNetGlobalFile | Out-String | ConvertFrom-Json) if ($DotNetGlobal.PSObject.Properties["sdk"] -and $DotNetGlobal.sdk.PSObject.Properties["version"]) { @@ -52,23 +50,17 @@ else { } } - # Install by channel or version - $DotNetDirectory = "$TempDirectory\dotnet-win" + $DotNetDirectory = Join-Path $TempDirectory 'dotnet-win' if (!(Test-Path variable:DotNetVersion)) { ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel -NoPath } } else { ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion -NoPath } } - $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" + $env:DOTNET_EXE = Join-Path $DotNetDirectory 'dotnet.exe' $env:PATH = "$DotNetDirectory;$env:PATH" } 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 } +ExecSafe { & $env:DOTNET_EXE tool restore } +ExecSafe { & $env:DOTNET_EXE fallout $BuildArguments } diff --git a/build.sh b/build.sh index 7df2c5967..bd0eb8400 100755 --- a/build.sh +++ b/build.sh @@ -9,15 +9,15 @@ SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) # CONFIGURATION ########################################################################### -BUILD_PROJECT_FILE="$SCRIPT_DIR/build-support/nuke-build/_build.csproj" -TEMP_DIRECTORY="$SCRIPT_DIR//.nuke/temp" +TEMP_DIRECTORY="$SCRIPT_DIR/.fallout/temp" -DOTNET_GLOBAL_FILE="$SCRIPT_DIR//global.json" +DOTNET_GLOBAL_FILE="$SCRIPT_DIR/global.json" DOTNET_INSTALL_URL="https://dot.net/v1/dotnet-install.sh" DOTNET_CHANNEL="STS" export DOTNET_CLI_TELEMETRY_OPTOUT=1 export DOTNET_NOLOGO=1 +export DOTNET_ROLL_FORWARD="Major" ########################################################################### # EXECUTION @@ -27,17 +27,15 @@ function FirstJsonValue { perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}" } -# If dotnet CLI is installed globally and it matches requested version, use for execution +# If dotnet CLI is installed globally, use it; otherwise provision a local copy under .fallout/temp. if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then export DOTNET_EXE="$(command -v dotnet)" else - # Download install script DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh" mkdir -p "$TEMP_DIRECTORY" curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL" chmod +x "$DOTNET_INSTALL_FILE" - # If global.json exists, load expected version if [[ -f "$DOTNET_GLOBAL_FILE" ]]; then DOTNET_VERSION=$(FirstJsonValue "version" "$(cat "$DOTNET_GLOBAL_FILE")") if [[ "$DOTNET_VERSION" == "" ]]; then @@ -45,7 +43,6 @@ else fi fi - # Install by channel or version DOTNET_DIRECTORY="$TEMP_DIRECTORY/dotnet-unix" if [[ -z ${DOTNET_VERSION+x} ]]; then "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path @@ -58,10 +55,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 -- "$@" +"$DOTNET_EXE" tool restore +exec "$DOTNET_EXE" fallout "$@"