From 7cf717bc7f895fc099ff5d8d7b757b9a355204c2 Mon Sep 17 00:00:00 2001 From: Nick Josevski Date: Thu, 6 Aug 2026 16:10:26 +1000 Subject: [PATCH] Make the build.sh SDK bootstrap diagnosable, and stop assuming curl and perl build.sh uses the machine's dotnet if `dotnet --version` succeeds, and otherwise downloads an SDK. That fallback shells out to curl and perl, neither of which is guaranteed in our Linux execution containers, so the first symptom is an opaque `exit 127` from a missing tool. That misleads twice over: reaching the fallback at all means `dotnet --version` failed, which is almost always global.json pinning an SDK the machine does not have. The "command not found" points away from the cause. - Log why the bootstrap ran, and list the SDKs that are installed - Use wget when curl is absent; name the problem when neither exists - Use sed when perl is absent Verified with the SDK install stubbed, in the containers that actually broke: amazonlinux:2 (curl, no perl) and debian:12 +wget (no curl) now complete the bootstrap instead of exiting 127; with neither downloader present it fails with a named error; and SDK 8 against a global.json pinning 10.0.302 now reports "global.json likely pins an SDK that is not installed (found: 8.0.423)". The sed fallback returns 8.0.419 for this repo's global.json, matching perl. A machine that already satisfies global.json still skips the bootstrap entirely. Deliberately out of scope: the hardcoded DOTNET_CHANNEL="8.0" (belongs with the .NET 10 work), and build.ps1 (Windows ships curl.exe and needs no perl). Co-Authored-By: Claude Opus 5 (1M context) --- build.sh | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/build.sh b/build.sh index 1089acffb9..f10b818403 100755 --- a/build.sh +++ b/build.sh @@ -24,17 +24,53 @@ export DOTNET_MULTILEVEL_LOOKUP=0 ########################################################################### function FirstJsonValue { - perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}" + # Stock Nuke shells out to perl. The Amazon Linux execution container does not ship it, so fall + # back to sed rather than dying with "perl: command not found". + if command -v perl &>/dev/null; then + perl -nle 'print $1 if m{"'"$1"'": "([^"]+)",?}' <<< "${@:2}" + else + sed -n 's/.*"'"$1"'"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' <<< "${@:2}" | head -n 1 + fi +} + +# ----- Octopus Deploy Modification ----- +# Stock Nuke assumes curl. The Linux execution containers install wget instead +function DownloadFile { + local url="$1" + local destination="$2" + + if command -v curl &>/dev/null; then + curl -Lsfo "$destination" "$url" + elif command -v wget &>/dev/null; then + wget -qO "$destination" "$url" + else + echo "Unable to download $url - neither curl nor wget is available on this machine." >&2 + return 1 + fi +} + +# Without this you get "command not found", makes you think missing tool but it's actually missing SDK +function DotnetBootstrapReason { + if [[ ! -x "$(command -v dotnet)" ]]; then + echo "no 'dotnet' found on PATH" + else + local installed + installed=$(dotnet --list-sdks 2>/dev/null | cut -d' ' -f1 | paste -sd' ' -) + echo "'dotnet --version' failed - global.json likely pins an SDK that is not installed (found: ${installed:-none})" + fi } +# ----- End Octopus Deploy Modification ----- # If dotnet CLI is installed globally and it matches requested version, use for execution if [ -x "$(command -v dotnet)" ] && dotnet --version &>/dev/null; then export DOTNET_EXE="$(command -v dotnet)" else + echo "Bootstrapping a local .NET SDK: $(DotnetBootstrapReason)" + # Download install script DOTNET_INSTALL_FILE="$TEMP_DIRECTORY/dotnet-install.sh" mkdir -p "$TEMP_DIRECTORY" - curl -Lsfo "$DOTNET_INSTALL_FILE" "$DOTNET_INSTALL_URL" + DownloadFile "$DOTNET_INSTALL_URL" "$DOTNET_INSTALL_FILE" chmod +x "$DOTNET_INSTALL_FILE" # If global.json exists, load expected version