Make SdkResolver-provided environment variables take precedence over ambient environment#12655
Make SdkResolver-provided environment variables take precedence over ambient environment#12655
Conversation
|
Hello @@copilot, I noticed that you’re changing an .swr file or any file under src/Package/MSBuild.VSSetup.. Please make sure to validate this change by an experimental VS insertion. This is accomplished by pushing to an exp/* branch, which requires write permissions to this repo. |
|
The package vuln thing that's plaguing other builds is hitting this one too, so it's hard to tell if this change actually passes tests. |
Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
c24c943 to
5b852f6
Compare
There was a problem hiding this comment.
Pull Request Overview
This PR fixes the precedence order for SDK resolver environment variables, making them override ambient environment variables from the host process as originally intended, rather than being overridden by them.
Key Changes:
- Modified
ProjectInstance.csandProject.csto allow SDK-resolved environment variables to override ambient environment variables - Fixed a serialization bug in
SdkResult.cswhere_environmentVariablesToAddwasn't being translated for out-of-proc scenarios - Added logging when SDK variables override ambient ones through a new resource string
SdkEnvironmentVariableOverridingAmbient
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| ProjectInstance.cs | Removed check preventing SDK env vars from overriding ambient vars; added logic to remove conflicting ambient vars and log overrides |
| Project.cs | Removed check preventing SDK env vars from overriding ambient vars; SDK values now always override ambient values |
| SdkResult.cs | Fixed serialization bug by adding translation for _environmentVariablesToAdd; updated Equals and GetHashCode to include the field |
| Strings.resx | Added new log message resource string for SDK variable overrides |
| Strings.*.xlf | Added translations (marked as "new") for the new log message across all localization files |
| SdkResultEvaluation_Tests.cs | Added two tests verifying SDK env vars override ambient vars and first SDK wins when multiple SDKs set the same variable |
| // Set the property, overriding ambient environment variables but not regular properties defined in XML. | ||
| // If we're overriding an ambient variable, or if the property doesn't exist, set it. | ||
| // Otherwise, prioritize regular properties defined in XML. | ||
| if (overridingAmbient || GetProperty(name) is null) |
There was a problem hiding this comment.
The logic in the conditional at line 1414 needs clarification. When overridingAmbient is true, GetProperty(name) will never return null because the ambient property already exists (it was just removed from _environmentVariableProperties). This means the GetProperty(name) is null check is only meaningful when overridingAmbient is false. Consider simplifying this to make the logic clearer, such as checking GetProperty(name) is null first, then handling the override case separately.
| @@ -112,6 +113,7 @@ public override bool Equals(object obj) | |||
| _additionalPaths?.Count == result._additionalPaths?.Count && | |||
| _propertiesToAdd?.Count == result._propertiesToAdd?.Count && | |||
| _itemsToAdd?.Count == result._propertiesToAdd?.Count && | |||
There was a problem hiding this comment.
The equality check is comparing _itemsToAdd?.Count with result._propertiesToAdd?.Count instead of result._itemsToAdd?.Count. This is a copy-paste error that makes the equality comparison incorrect.
| _itemsToAdd?.Count == result._propertiesToAdd?.Count && | |
| _itemsToAdd?.Count == result._itemsToAdd?.Count && |
| // Only set the local property if it does not already exist, prioritizing regular properties defined in XML. | ||
| if (GetProperty(name) is null) | ||
| // SDK-resolved environment variables override ambient environment variables. | ||
| bool overridingAmbient = _environmentVariableProperties.Contains(name); |
There was a problem hiding this comment.
@copilot ensure that null environment variable names are handled in the Project and ProjectInstance handling
There was a problem hiding this comment.
Added null checks for both name and value parameters in AddSdkResolvedEnvironmentVariable methods in ProjectInstance.cs and Project.cs. The validation uses ErrorUtilities.VerifyThrowArgumentLength(name) and ErrorUtilities.VerifyThrowArgumentNull(value) to match the pattern used in other MSBuild property-setting methods. (commit c24c943 updated)
Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
AddSdkResolvedEnvironmentVariablein ProjectInstance.cs to allow SDK env vars to override ambient env varsAddSdkResolvedEnvironmentVariablein Project.cs to allow SDK env vars to override ambient env varsSummary
This PR implements the feature requested in the issue where SdkResolver-provided environment variables now take precedence over ambient environment variables from the host process.
Changes Made:
ProjectInstance.cs: Modified
AddSdkResolvedEnvironmentVariableto:nameandvalueusingErrorUtilities_environmentVariablePropertiesdictionary when SDK sets themProject.cs: Modified
AddSdkResolvedEnvironmentVariableto:nameandvalueusingErrorUtilitiesSdkResult.cs: Fixed serialization bug by:
_environmentVariablesToAddto theTranslatemethodEqualsmethod to compare_environmentVariablesToAddGetHashCodeto include_environmentVariablesToAddStrings.resx: Added new log message "SdkEnvironmentVariableOverridingAmbient"
Tests: Added two new tests:
SdkResolverEnvironmentVariablesOverrideAmbientEnvironmentVariables: Verifies SDK values override ambient env varsFirstSdkEnvironmentVariableWinsOverSubsequentSdks: Verifies first SDK wins among multiple SDKsBehavior:
nameandvalueparameters are validated to prevent null valuesAll existing SdkResultEvaluation tests pass, confirming backward compatibility is maintained.
Original prompt
Fixes #12654
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.