From f98697b4a36eeb984ee6303fc50965cce57f1390 Mon Sep 17 00:00:00 2001 From: Matt Richardson Date: Tue, 24 Feb 2026 15:17:32 +1100 Subject: [PATCH 1/3] Upgrade to nuke 9.0.4 --- build.cmd | 29 +---- build.ps1 | 202 ++++++++++++++++---------------- build.sh | 8 +- build/Build.Consolidation.cs | 7 +- build/Build.sbom.cs | 3 - build/CalamariTestRunBuilder.cs | 4 +- build/_build.csproj | 2 +- 7 files changed, 114 insertions(+), 141 deletions(-) mode change 100644 => 100755 build.cmd diff --git a/build.cmd b/build.cmd old mode 100644 new mode 100755 index a013d75594..b08cc590f4 --- a/build.cmd +++ b/build.cmd @@ -1,24 +1,7 @@ -@ECHO OFF -REM see http://joshua.poehls.me/powershell-batch-file-wrapper/ - -SET SCRIPTNAME=%~d0%~p0%~n0.ps1 -SET ARGS=%* -IF [%1] NEQ [] GOTO ESCAPE_ARGS - -:POWERSHELL -PowerShell.exe -NoProfile -NonInteractive -NoLogo -ExecutionPolicy Unrestricted -Command "& { $ErrorActionPreference = 'Stop'; & '%SCRIPTNAME%' @args; EXIT $LASTEXITCODE }" %ARGS% -EXIT /B %ERRORLEVEL% +:; set -eo pipefail +:; SCRIPT_DIR=$(cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd) +:; ${SCRIPT_DIR}/build.sh "$@" +:; exit $? -:ESCAPE_ARGS -SET ARGS=%ARGS:"=\"% -SET ARGS=%ARGS:`=``% -SET ARGS=%ARGS:'=`'% -SET ARGS=%ARGS:$=`$% -SET ARGS=%ARGS:{=`}% -SET ARGS=%ARGS:}=`}% -SET ARGS=%ARGS:(=`(% -SET ARGS=%ARGS:)=`)% -SET ARGS=%ARGS:,=`,% -SET ARGS=%ARGS:^%=% - -GOTO POWERSHELL \ No newline at end of file +@ECHO OFF +powershell -ExecutionPolicy ByPass -NoProfile -File "%~dp0build.ps1" %* diff --git a/build.ps1 b/build.ps1 index f667ed6ef8..a7ae09dc9f 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,103 +1,99 @@ -[CmdletBinding()] -Param( - [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] - [string[]]$BuildArguments -) - -Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)" - -Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 } -$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent - -$env:SIGNTOOL_EXE = "$PSScriptRoot/certificates/signtool.exe" - -########################################################################### -# CONFIGURATION -########################################################################### - -$BuildProjectFile = "$PSScriptRoot\build\_build.csproj" -$TempDirectory = "$PSScriptRoot\\.nuke\temp" - -$DotNetGlobalFile = "$PSScriptRoot\\global.json" -$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" -$DotNetChannel = "Current" - -$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 -$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 -$env:DOTNET_MULTILEVEL_LOOKUP = 0 - -########################################################################### -# EXECUTION -########################################################################### - -function ExecSafe([scriptblock] $cmd) { - & $cmd - if ($LASTEXITCODE) { exit $LASTEXITCODE } -} - -# If dotnet CLI is installed globally and it matches requested version, use for execution -if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` - $(dotnet --version) -and $LASTEXITCODE -eq 0) { - $env:DOTNET_EXE = (Get-Command "dotnet").Path -} -else { - # Download install script - $DotNetInstallFile = "$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"]) { - $DotNetVersion = $DotNetGlobal.sdk.version - } - } - - # ----- Octopus Deploy Modification ----- - # - # The default behaviour of the Nuke Bootstrapper (when .NET is not already preinstalled) is - # to read from the global.json, then install that exact version. It doesn't roll forward. - # This means that if our global.json says 8.0.100, and the latest version is 8.0.200, it will - # always install 8.0.100 and we will not pick up any security or bug fixes that 8.0.200 carries. - # - # This means we would need to manually update our global.json file every time there is a new - # .NET SDK available, and then all developers would need to immediately install this on their machines. - # - # In our builds, we want the same "automatic roll-forward" behaviour that we get when we use the dotnet/sdk:8.0 docker - # images -- where we always get the latest patch version of the SDK without manual intervention. - # - # We achieve this with a small tweak to the Nuke bootstrapper to tell it to install the latest version from - # the 8.0 channel, regardless of what's in the global.json. - - Remove-Variable DotNetVersion - $DotNetChannel = "8.0" - # ----- End Octopus Deploy Modification ----- - - # Install by channel or version - $DotNetDirectory = "$TempDirectory\dotnet-win" - if (!(Test-Path variable:DotNetVersion)) { - ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Channel $DotNetChannel } - } else { - ExecSafe { & powershell $DotNetInstallFile -InstallDir $DotNetDirectory -Version $DotNetVersion } - } - $env:DOTNET_EXE = "$DotNetDirectory\dotnet.exe" - - # ----- Octopus Deploy Modification ----- - # Update the path with the temporary dotnet exe so it can be found by anything be run out of this shell - $env:PATH = "$($env:Path);$DotNetDirectory" - # We update the global path - [Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine) - Write-Output "Updating Path variable to $($env:PATH)" - # ----- End Octopus Deploy Modification ----- -} - -Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" - -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 } - - - - +[CmdletBinding()] +Param( + [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)] + [string[]]$BuildArguments +) + +Write-Output "PowerShell $($PSVersionTable.PSEdition) version $($PSVersionTable.PSVersion)" + +Set-StrictMode -Version 2.0; $ErrorActionPreference = "Stop"; $ConfirmPreference = "None"; trap { Write-Error $_ -ErrorAction Continue; exit 1 } +$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent + +$env:SIGNTOOL_EXE = "$PSScriptRoot/certificates/signtool.exe" + +########################################################################### +# CONFIGURATION +########################################################################### + +$BuildProjectFile = "$PSScriptRoot\build\_build.csproj" +$TempDirectory = "$PSScriptRoot\\.nuke\temp" + +$DotNetGlobalFile = "$PSScriptRoot\\global.json" +$DotNetInstallUrl = "https://dot.net/v1/dotnet-install.ps1" +$DotNetChannel = "Current" + +$env:DOTNET_SKIP_FIRST_TIME_EXPERIENCE = 1 +$env:DOTNET_CLI_TELEMETRY_OPTOUT = 1 +$env:DOTNET_MULTILEVEL_LOOKUP = 0 + +########################################################################### +# EXECUTION +########################################################################### + +function ExecSafe([scriptblock] $cmd) { + & $cmd + if ($LASTEXITCODE) { exit $LASTEXITCODE } +} + +# If dotnet CLI is installed globally and it matches requested version, use for execution +if ($null -ne (Get-Command "dotnet" -ErrorAction SilentlyContinue) -and ` + $(dotnet --version) -and $LASTEXITCODE -eq 0) { + $env:DOTNET_EXE = (Get-Command "dotnet").Path +} +else { + # Download install script + $DotNetInstallFile = "$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"]) { + $DotNetVersion = $DotNetGlobal.sdk.version + } + } + + # ----- Octopus Deploy Modification ----- + # + # The default behaviour of the Nuke Bootstrapper (when .NET is not already preinstalled) is + # to read from the global.json, then install that exact version. It doesn't roll forward. + # This means that if our global.json says 8.0.100, and the latest version is 8.0.200, it will + # always install 8.0.100 and we will not pick up any security or bug fixes that 8.0.200 carries. + # + # This means we would need to manually update our global.json file every time there is a new + # .NET SDK available, and then all developers would need to immediately install this on their machines. + # + # In our builds, we want the same "automatic roll-forward" behaviour that we get when we use the dotnet/sdk:8.0 docker + # images -- where we always get the latest patch version of the SDK without manual intervention. + # + # We achieve this with a small tweak to the Nuke bootstrapper to tell it to install the latest version from + # the 8.0 channel, regardless of what's in the global.json. + + Remove-Variable DotNetVersion + $DotNetChannel = "8.0" + # ----- End Octopus Deploy Modification ----- + + # Install by channel or version + $DotNetDirectory = "$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" + + # ----- Octopus Deploy Modification ----- + # Update the path with the temporary dotnet exe so it can be found by anything be run out of this shell + $env:PATH = "$($env:Path);$DotNetDirectory" + # We update the global path + [Environment]::SetEnvironmentVariable("Path", $env:Path, [System.EnvironmentVariableTarget]::Machine) + Write-Output "Updating Path variable to $($env:PATH)" + # ----- End Octopus Deploy Modification ----- +} + +Write-Output "Microsoft (R) .NET Core SDK version $(& $env:DOTNET_EXE --version)" + +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 805bd1bf15..0ceb4a17d5 100755 --- a/build.sh +++ b/build.sh @@ -44,7 +44,7 @@ else unset DOTNET_VERSION fi fi - + # ----- Octopus Deploy Modification ----- # # The default behaviour of the Nuke Bootstrapper (when .NET is not already preinstalled) is @@ -68,12 +68,12 @@ else # 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" + "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --channel "$DOTNET_CHANNEL" --no-path else - "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" + "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path fi export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" - + # ----- Octopus Deploy Modification ----- # Update the path with the temporary dotnet exe so it can be found by anything be run out of this shell export PATH="$PATH:$DOTNET_DIRECTORY" diff --git a/build/Build.Consolidation.cs b/build/Build.Consolidation.cs index 951b9cacf9..32272eda8f 100644 --- a/build/Build.Consolidation.cs +++ b/build/Build.Consolidation.cs @@ -80,10 +80,7 @@ public partial class Build DotNetTest(s => s .SetProjectFile(ConsolidateCalamariPackagesProject) .SetConfiguration(Configuration) - .SetProcessArgumentConfigurator(args => - args.Add("--logger:\"console;verbosity=detailed\"") - .Add("--") - .Add("NUnit.ShowInternalProperties=true"))); + .SetProcessAdditionalArguments("--logger:\"console;verbosity=detailed\"", "--", "NUnit.ShowInternalProperties=true")); }); Target PackConsolidationLibrariesNugetPackages => @@ -133,4 +130,4 @@ public partial class Build .SetVersion(NugetVersion.Value) .SetOutputDirectory(KnownPaths.ArtifactsDirectory)); }); -} \ No newline at end of file +} diff --git a/build/Build.sbom.cs b/build/Build.sbom.cs index e415dcc432..0e7a6e42b7 100644 --- a/build/Build.sbom.cs +++ b/build/Build.sbom.cs @@ -32,9 +32,6 @@ partial class Build var octoVersionInfo = OctoVersionInfo.Value ?? throw new InvalidOperationException("Required OctoVersionInfo was not populated"); var combinedFileName = $"calamari.{octoVersionInfo.FullSemVer}-sbom.cdx.json"; - // redirect all docker output to stdout, as lots of it goes as stderr when it's just progress messages - DockerTasks.DockerLogger = (_, message) => Log.Information("[Docker] {Message}", message); - EnsureDockerImagesExistLocally(); var results = new List(); diff --git a/build/CalamariTestRunBuilder.cs b/build/CalamariTestRunBuilder.cs index 32543a9691..7ea2921478 100644 --- a/build/CalamariTestRunBuilder.cs +++ b/build/CalamariTestRunBuilder.cs @@ -39,7 +39,7 @@ DotNetTestSettings BuildTestSettings() _ => throw new ProcessException(process) }) .AddLoggers("console;verbose=normal") - .When(runningInTeamCity, x => x.EnableTeamCityTestLogger(OutputDirectory)); + .When(_ => runningInTeamCity, x => x.EnableTeamCityTestLogger(OutputDirectory)); var runSettingsFilePath = TryBuildExcludedTestsSettingsFile(Filter); if (runSettingsFilePath is not null) @@ -106,4 +106,4 @@ public void Execute() return null; } -} \ No newline at end of file +} diff --git a/build/_build.csproj b/build/_build.csproj index 5ddaa28c67..b178179720 100644 --- a/build/_build.csproj +++ b/build/_build.csproj @@ -28,7 +28,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + From 3b9d8c60eab7934c1147182119a189e1e53e873c Mon Sep 17 00:00:00 2001 From: Matt Richardson Date: Tue, 24 Feb 2026 15:25:59 +1100 Subject: [PATCH 2/3] Update build.sh --- build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.sh b/build.sh index 0ceb4a17d5..1089acffb9 100755 --- a/build.sh +++ b/build.sh @@ -73,7 +73,7 @@ else "$DOTNET_INSTALL_FILE" --install-dir "$DOTNET_DIRECTORY" --version "$DOTNET_VERSION" --no-path fi export DOTNET_EXE="$DOTNET_DIRECTORY/dotnet" - + # ----- Octopus Deploy Modification ----- # Update the path with the temporary dotnet exe so it can be found by anything be run out of this shell export PATH="$PATH:$DOTNET_DIRECTORY" From 7106349b162261d45764aec80c1a7ae1868bf0a1 Mon Sep 17 00:00:00 2001 From: Matt Richardson Date: Tue, 24 Feb 2026 15:30:50 +1100 Subject: [PATCH 3/3] Update Build.sbom.cs --- build/Build.sbom.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/Build.sbom.cs b/build/Build.sbom.cs index 0e7a6e42b7..0d88273ad7 100644 --- a/build/Build.sbom.cs +++ b/build/Build.sbom.cs @@ -128,7 +128,7 @@ await Logging.InBlock($"Uploading SBOM to Dependency Track", () => $"SBOM_UPLOADER_TAGS={projectName},{parentName}") .SetArgs(args) .SetRm(true) - .SetProcessLogInvocation(false)); // don't log the invocation, as in this version of nuke (8.1.4), it logs the api key + .AddProcessRedactedSecrets(DependencyTrackApiKey)); return Task.CompletedTask; });