The fact that MSBuild initializes properties with environment variables is very bad for reproducible builds. CI servers often have different sets of environment variables set, and investigating on the CI server is usually hard.
For compatibility reasons, I doubt we'll ever get rid of reading environment, but I hope there can be "Strict Mode" where environment is not read at all. Builds could opt in to strict mode and use other means of initializing global state.
Example:
https://github.com/NuGet/NuGet.Client/blob/2aad8d25e66e9c3737b220631f3661bb6235d14b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets#L555-L565
Imagine if the CI Server defines the VERSION environment variable and sets it to something like a Git SHA.
You get a build failure like this:
/Library/Frameworks/Mono.framework/Versions/5.8.0/lib/mono/xbuild/NuGet.targets(102,5): error : 'fbc5117dcb21f0d180c4b199d828d4f4b9d6f4a8' is not a valid version string. [/Users/builder/data/lanes/5668/fbc5117d/source/md-addins/MacSetup/build/BinaryChecker.proj]
/Library/Frameworks/Mono.framework/Versions/5.8.0/lib/mono/xbuild/NuGet.targets(102,5): error : Parameter name: value [/Users/builder/data/lanes/5668/fbc5117d/source/md-addins/MacSetup/build/BinaryChecker.proj]
Tracking it down from that failure to that line to NuGet.targets is highly non-trivial.
The fact that MSBuild initializes properties with environment variables is very bad for reproducible builds. CI servers often have different sets of environment variables set, and investigating on the CI server is usually hard.
For compatibility reasons, I doubt we'll ever get rid of reading environment, but I hope there can be "Strict Mode" where environment is not read at all. Builds could opt in to strict mode and use other means of initializing global state.
Example:
https://github.com/NuGet/NuGet.Client/blob/2aad8d25e66e9c3737b220631f3661bb6235d14b/src/NuGet.Core/NuGet.Build.Tasks/NuGet.targets#L555-L565
Imagine if the CI Server defines the VERSION environment variable and sets it to something like a Git SHA.
You get a build failure like this:
Tracking it down from that failure to that line to NuGet.targets is highly non-trivial.