From 4965ff4c006045c189b884666e7e48920b8d46cb Mon Sep 17 00:00:00 2001 From: fpellet Date: Mon, 31 Aug 2026 19:32:30 +0200 Subject: [PATCH 1/2] build: run build.fsx with dotnet fsi instead of the FAKE runner The build was started through `mono packages/build/FAKE/tools/FAKE.exe`, a .NET Framework executable. That runner is what forced Mono on Linux, pulled in the legacy MSBuild discovery, and had to stay in step with the .NET SDK. Run the script with `dotnet fsi` instead. FAKE 4.64.17 is now used as a library only: build.fsx itself, its targets and the produced artifacts are unchanged. Without the runner the script has to parse its own command line, so translate ` key=value ...` into the environment variables FAKE reads back through getBuildParam/hasBuildParam. This happens before any other binding, since top-level values such as testSuiteFilterFlakyTests read build parameters while the script loads. Also drop the ServicePointManager.SecurityProtocol assignment: it enabled TLS 1.2 on old runtimes and now throws NotSupportedException on .NET 10, because it also requests SSL3. Mono is still required for the targets that execute .NET Framework binaries, namely MergePaketTool (ILRepack) and the net461 test passes; FAKE keeps prefixing those with mono on its own. Refs #4348 --- build.cmd | 2 +- build.fsx | 15 +++++++++++++-- build.sh | 41 ++++++++--------------------------------- 3 files changed, 22 insertions(+), 36 deletions(-) diff --git a/build.cmd b/build.cmd index 26a9bfdd30..3b7a36c79c 100644 --- a/build.cmd +++ b/build.cmd @@ -9,6 +9,6 @@ if errorlevel 1 ( setlocal -packages\build\FAKE\tools\FAKE.exe build.fsx %* +dotnet fsi build.fsx %* endlocal \ No newline at end of file diff --git a/build.fsx b/build.fsx index b93ddbf618..f390e4fc7c 100644 --- a/build.fsx +++ b/build.fsx @@ -15,6 +15,19 @@ open Fake.Testing.NUnit3 open System.Security.Cryptography open System.Xml.Linq +// This script is run with `dotnet fsi`, so there is no FAKE.exe runner to parse the +// command line for us. The runner used to turn `build.sh key=value ...` into +// environment variables, which FAKE then reads back through getBuildParam/hasBuildParam. +// Do that translation here, before any value below reads a build parameter. +let private commandLineArgs = + let all = Environment.GetCommandLineArgs() + if all.Length > 2 then all.[2..] else [||] // skip fsi.dll and build.fsx + +for arg in commandLineArgs do + match arg.IndexOf '=' with + | i when i > 0 -> Environment.SetEnvironmentVariable(arg.Substring(0, i), arg.Substring(i + 1)) + | _ -> Environment.SetEnvironmentVariable("target", arg) + // Information about the project are used // - for version and project name in generated AssemblyInfo file // - by the generated NuGet package @@ -77,8 +90,6 @@ let paketFile = buildMergedDir @@ "paket.exe" Environment.CurrentDirectory <- __SOURCE_DIRECTORY__ -System.Net.ServicePointManager.SecurityProtocol <- unbox 192 ||| unbox 768 ||| unbox 3072 ||| unbox 48 - // Read additional information from the release notes document let releaseNotesData = File.ReadAllLines "RELEASE_NOTES.md" diff --git a/build.sh b/build.sh index cd26161e7c..59a0176c48 100755 --- a/build.sh +++ b/build.sh @@ -1,35 +1,10 @@ #!/usr/bin/env bash -if test "$OS" = "Windows_NT" -then - # use .Net - dotnet tool restore - dotnet paket restore - exit_code=$? - if [ $exit_code -ne 0 ]; then - exit $exit_code - fi - MSBuild=`pwd -W`/packages/build/RoslynTools.MSBuild/tools/msbuild/MSBuild.exe packages/build/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx -else - dotnet tool restore - dotnet paket restore - exit_code=$? - if [ $exit_code -ne 0 ]; then - certificate_count=$(certmgr -list -c Trust | grep X.509 | wc -l) - if [ $certificate_count -le 1 ]; then - echo "Couldn't download Paket. This might be because your Mono installation" - echo "doesn't have the right SSL root certificates installed. One way" - echo "to fix this would be to download the list of SSL root certificates" - echo "from the Mozilla project by running the following command:" - echo "" - echo " mozroots --import --sync" - echo "" - echo "This will import over 100 SSL root certificates into your Mono" - echo "certificate repository. Then try running the build script again." - fi - exit $exit_code - fi - # Note: the bundled MSBuild crashes hard on linux, so we still rely on the system-installed version - #export MSBuild=packages/build/RoslynTools.MSBuild/tools/msbuild/MSBuild.exe - mono packages/build/FAKE/tools/FAKE.exe $@ --fsiargs -d:MONO build.fsx -fi +set -eu +set -o pipefail +cd "$(dirname "$0")" + +dotnet tool restore +dotnet paket restore + +dotnet fsi build.fsx "$@" From 7231cb9a72fb12fa2353b0629b3584813ae374a8 Mon Sep 17 00:00:00 2001 From: fpellet Date: Mon, 31 Aug 2026 19:32:40 +0200 Subject: [PATCH 2/2] docs: describe the dotnet fsi build entry point State that build.cmd and build.sh run build.fsx with dotnet fsi and that FAKE is used as a library, so no runner has to be installed and its version no longer has to match the SDK. Keep saying that Mono is still needed on Linux, but narrow it to what actually needs it: MergePaketTool and the net461 test passes. Fix the skip examples in CLAUDE.md along the way. Skip switches are build parameters, not targets, so they take a value and follow the target name; the documented `build.cmd SkipTests` was read as a target name and never worked. Refs #4348 --- AGENTS.md | 2 +- CLAUDE.md | 13 ++++++++++--- DEV_GUIDE.md | 12 ++++++++++++ README.md | 2 +- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index e72c885949..1fd6d90dd2 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,7 +51,7 @@ Repository build targets: ./build.sh ``` -On Windows, use the corresponding `build.cmd` commands. The full build restores tools and dependencies, builds all projects, and runs broad test suites; on Linux it also depends on Mono and system tooling. If those prerequisites are unavailable, run the relevant `dotnet test` command and report what was not validated. +On Windows, use the corresponding `build.cmd` commands. Both scripts run `build.fsx` with `dotnet fsi`, so the build script itself only needs the .NET SDK declared in `global.json`. The full build restores tools and dependencies, builds all projects, and runs broad test suites; on Linux it still depends on Mono for the targets that run .NET Framework binaries, namely `MergePaketTool` (ILRepack) and the `net461` test passes. If those prerequisites are unavailable, run the relevant `dotnet test` command and report what was not validated. ## Tests diff --git a/CLAUDE.md b/CLAUDE.md index 15f90ed219..3967caf7a9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,6 +8,9 @@ Paket is a dependency manager for .NET with support for NuGet packages and git r ## Build Commands +Both scripts run `build.fsx` with `dotnet fsi`; FAKE is used as a library, there is no FAKE runner +to install. + ```bash # Full build (restores, builds, runs tests) build.cmd # Windows @@ -21,11 +24,15 @@ build.cmd QuickIntegrationTests # Run quick integration tests (scriptgen catego build.cmd RunIntegrationTestsNet # Run full .NET Framework integration tests build.cmd RunIntegrationTestsNetCore # Run full .NET Core integration tests -# Skip specific stages -build.cmd SkipTests # Skip all tests -build.cmd SkipIntegrationTests # Skip integration tests only +# Skip specific stages: these are build parameters, so they take a value and +# come after the target name (they can also be passed as environment variables) +build.cmd BuildPackage SkipTests=true # Skip all tests +build.cmd BuildPackage SkipIntegrationTests=true # Skip integration tests only ``` +Mono is still required on Linux for the targets that run .NET Framework binaries: `MergePaketTool` +(ILRepack) and the `net461` test passes. + ## Testing **Unit Tests:** diff --git a/DEV_GUIDE.md b/DEV_GUIDE.md index af4e808c6a..0df2c68b6f 100644 --- a/DEV_GUIDE.md +++ b/DEV_GUIDE.md @@ -4,6 +4,18 @@ Please contribute any notes that made your contributions easier here. Note that historically, the bulk of the development occured on Windows before dotnet got cross platform, for now, the tooling to target .NET Framework is still required for some areas. +# Notes about the build script + +`build.cmd` and `build.sh` run `build.fsx` with `dotnet fsi`. FAKE is used as a library only: there +is no FAKE runner to install, and its version no longer has to match the .NET SDK. Targets and +parameters are unchanged, so `./build.sh [key=value ...]` keeps working as before — the +script translates those arguments into environment variables itself, which is what the FAKE runner +used to do. + +Mono is still needed on Linux for the targets that execute .NET Framework binaries: `MergePaketTool` +(which runs `ILRepack.exe`) and the `net461` test passes. Removing that is tracked separately in +[#4348](https://github.com/fsprojects/Paket/issues/4348). + # Notes about the Paket F# Interactive extension Some pointers to help efforts to foster the F# Interactive extension ecosystem: diff --git a/README.md b/README.md index d28e1866f5..1549bd0cf7 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ For more reasons see the [FAQ][10]. - Build the solution with Visual Studio, `build.cmd` or `build.sh`. - Create a topic specific branch in git. Add a nice feature in the code. Do not forget to add tests and/or docs. - - Run `build.cmd` (`build.sh` on Mono) to make sure all tests are still + - Run `build.cmd` (`build.sh` on Linux/macOS) to make sure all tests are still passing. - When built, you'll find the binaries in `./bin` which you can then test with locally, to ensure the bug or feature has been successfully implemented.