dotnet run -e FOO=BAR passes @(RuntimeEnvironmentVariable)#52664
dotnet run -e FOO=BAR passes @(RuntimeEnvironmentVariable)#52664jonathanpeppers merged 12 commits intorelease/10.0.3xxfrom
dotnet run -e FOO=BAR passes @(RuntimeEnvironmentVariable)#52664Conversation
Context: #52492 In investigating how to pass implement `dotnet-watch` for mobile, we found that we need to make use of: dotnet run -e FOO=BAR Where `FOO=BAR` is passed as an MSBuild item `@(RuntimeEnvironmentVariable)` to the build, `DeployToDevice` target, and `ComputeRunArguments` target: <ItemGroup> <RuntimeEnvironmentVariable Include="FOO" Value="BAR" /> </ItemGroup> This is straightforward for the in-process MSBuild target invocations, but for the build step, we need to generate a temporary `.props` file and import using `$(CustomBeforeMicrosoftCommonProps)`. In the iOS & Android workloads, we would handle processing the `@(RuntimeEnvironmentVariable)` item to pass the environment variables to the device/emulator when deploying and running the app. I added a test to verify environment variables are passed through correctly to all targets.
Updated the props file path generation to use Path.GetFullPath, ensuring that MSBuild receives an absolute path for the generated props file. This improves reliability when referencing the file in build processes.
Replaces backslashes with the system's directory separator in intermediateOutputPath to ensure consistent path handling across platforms. This prevents issues when MSBuild returns paths with Windows-style separators on non-Windows systems.
| // directly to ProjectInstance for in-process target invocations. | ||
| var additionalProperties = new ReadOnlyDictionary<string, string>(new Dictionary<string, string> | ||
| { | ||
| [Constants.CustomBeforeMicrosoftCommonProps] = propsFilePath |
There was a problem hiding this comment.
I'm a little worried about this negatively impacting existing build processes - but I don't really have a way to validate how widely used this is.
There was a problem hiding this comment.
A quick search around github shows ~250 instances, but none really appear foundational and some are in unrelated tooling. I'd expect large 1P customers to have some kind of use of this though, because they use all of the weird extensiblity points. I suppose if MSbuild ever makes a first-class way of injecting Items we could move to that.
There was a problem hiding this comment.
This was a spot I didn't like either, here is a GitHub search:
We could introduce a new property?
I really wanted to avoid creating a temp .props file but saw no other way
There was a problem hiding this comment.
I think this is fine to get in for the first revision and revisit. If we did a new property we'd need to add 'massaging' of that property into Items, and that can also be an error-prone activity due to weird user inputs.
There was a problem hiding this comment.
Pull request overview
This PR adds support for passing environment variables from dotnet run -e to MSBuild targets as @(RuntimeEnvironmentVariable) items. Projects opt in to this feature by declaring the RuntimeEnvironmentVariableSupport project capability.
Changes:
- Environment variables from
-eflags are converted to MSBuild items and passed to build, deploy, and ComputeRunArguments targets - Opt-in mechanism using project capabilities to avoid impacting projects that don't need this feature
- Temporary
.propsfile generation for out-of-process build steps
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsDevice.cs | Added tests to verify environment variables are passed to targets when opted in, and not passed when opt-out |
| test/TestAssets/TestProjects/DotnetRunDevices/DotnetRunDevices.csproj | Test project updated to opt in to capability and log environment variables in targets for verification |
| src/Cli/dotnet/Commands/Run/RunCommandSelector.cs | Added properties to check opt-in capability and retrieve IntermediateOutputPath for props file creation |
| src/Cli/dotnet/Commands/Run/RunCommand.cs | Modified to pass environment variables to selector, create props file for build, and add items for in-process targets |
| src/Cli/dotnet/Commands/Run/EnvironmentVariablesToMSBuild.cs | New utility class for converting environment variables to MSBuild items and managing temporary props files |
| src/Cli/Microsoft.DotNet.Cli.Utils/Constants.cs | Added constants for RuntimeEnvironmentVariable items, ProjectCapability, and related properties |
| documentation/specs/dotnet-run-for-maui.md | Documentation explaining the opt-in mechanism and implementation details |
test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsDevice.cs
Outdated
Show resolved
Hide resolved
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Add support for the '@(RuntimeEnvironmentVariable)' item group, which is set when using 'dotnet run' and passing environment variables using '-e|--environment NAME=VALUE' to 'dotnet run'. This required adding the 'RuntimeEnvironmentVariableSupport' capability to tell 'dotnet run' that we support this. References: * dotnet/android#10770 * dotnet/sdk#52664
Add support for the '@(RuntimeEnvironmentVariable)' item group, which is set when using 'dotnet run' and passing environment variables using '-e|--environment NAME=VALUE' to 'dotnet run'. This required adding the 'RuntimeEnvironmentVariableSupport' capability to tell 'dotnet run' that we support this. References: * dotnet/android#10770 * dotnet/sdk#52664 --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Context: #52492
In investigating how to pass implement
dotnet-watchfor mobile, we found that we need to make use of:Where
FOO=BARis passed as an MSBuild item@(RuntimeEnvironmentVariable)to the build,DeployToDevicetarget, andComputeRunArgumentstarget:This is straightforward for the in-process MSBuild target invocations, but for the build step, we need to generate a temporary
.propsfile and import using$(CustomBeforeMicrosoftCommonProps).You will have to opt into this behavior by setting
<ProjectCapability Include="RuntimeEnvironmentVariableSupport" />in your project. The iOS and Android workloads would automatically set this capability.In the iOS & Android workloads, we would handle processing the
@(RuntimeEnvironmentVariable)item to pass the environment variables to the device/emulator when deploying and running the app.I added a test to verify environment variables are passed through correctly to all targets.