Skip to content

Honor @(RuntimeEnvironmentVariable) item changes when launching the app#54922

Open
rolfbjarne wants to merge 7 commits into
dotnet:mainfrom
rolfbjarne:runtime-environment-variable
Open

Honor @(RuntimeEnvironmentVariable) item changes when launching the app#54922
rolfbjarne wants to merge 7 commits into
dotnet:mainfrom
rolfbjarne:runtime-environment-variable

Conversation

@rolfbjarne

@rolfbjarne rolfbjarne commented Jun 22, 2026

Copy link
Copy Markdown
Member

Commit bd5d3af added support for passing dotnet run -e KEY=VALUE environment variables to MSBuild as the @(RuntimeEnvironmentVariable) item group (opt-in via the RuntimeEnvironmentVariableSupport project capability), so targets can inspect them.

However, when the app/executable was eventually launched, only the original -e values were applied to the process environment. Any additions or changes a target (e.g. ComputeRunArguments) made to the @(RuntimeEnvironmentVariable) item group were ignored.

Fix

For opted-in projects, after ComputeRunArguments runs, read the final @(RuntimeEnvironmentVariable) item group back and apply it to the launched command instead of the raw -e dictionary. Non-opted-in projects keep using the -e values directly, so their behavior is unchanged.

  • Added EnvironmentVariablesToMSBuild.HasRuntimeEnvironmentVariableSupport (de-duplicating the capability check) and EnvironmentVariablesToMSBuild.ReadFromItems.
  • Made InvokeRunArgumentsTarget return whether the project opted in, so GetTargetCommandForProject can read the item group back and pass it to SetEnvironmentVariables.

Behavior change

For opted-in projects this is an intentional, user-visible behavior change: the final @(RuntimeEnvironmentVariable) item group now wins over the raw -e values when launching the app. Projects without the RuntimeEnvironmentVariableSupport capability are unaffected.

Tests

Added a regression test (ItHonorsRuntimeEnvironmentVariableChangesFromTargetsWhenRunningApp) and a test-asset target (_ModifyRuntimeEnvironmentVariable) that changes/injects RUNE_* variables before the app runs; the launched app now observes the modified/injected values. Verified the full GivenDotnetRunSelectsDevice class (23 tests) and the standard dotnet run -e override tests pass.

Commit bd5d3af added support for passing `dotnet run -e KEY=VALUE`
environment variables to MSBuild as the `@(RuntimeEnvironmentVariable)`
item group (opt-in via the `RuntimeEnvironmentVariableSupport` project
capability), so targets can inspect them.

However, when the app/executable was eventually launched, only the
original `-e` values were applied to the process environment. Any
additions or changes a target (e.g. `ComputeRunArguments`) made to the
`@(RuntimeEnvironmentVariable)` item group were ignored.

Fix: for opted-in projects, after `ComputeRunArguments` runs, read the
final `@(RuntimeEnvironmentVariable)` item group back and apply it to the
launched command instead of the raw `-e` dictionary. Non-opted-in
projects keep using the `-e` values directly, so behavior is unchanged.

Added `EnvironmentVariablesToMSBuild.HasRuntimeEnvironmentVariableSupport`
and `ReadFromItems`, plus a regression test and a test-asset target that
modifies the item group before the app runs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@rolfbjarne

Copy link
Copy Markdown
Member Author

CC @jonathanpeppers

@rolfbjarne rolfbjarne marked this pull request as ready for review June 22, 2026 18:26
Copilot AI review requested due to automatic review settings June 22, 2026 18:26

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes dotnet run -e KEY=VALUE handling for projects that opt in to @(RuntimeEnvironmentVariable) support, ensuring that any MSBuild target modifications to the item group (e.g., via ComputeRunArguments) are reflected in the launched app’s process environment.

Changes:

  • Update RunCommand to (for opted-in projects) read back the final @(RuntimeEnvironmentVariable) items after ComputeRunArguments and apply them when launching the app.
  • Add EnvironmentVariablesToMSBuild.HasRuntimeEnvironmentVariableSupport and EnvironmentVariablesToMSBuild.ReadFromItems helpers to centralize capability checks and item reading.
  • Add a regression test plus a test-asset target/app output to verify that target-injected/modified environment variables are honored at execution time.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Cli/dotnet/Commands/Run/RunCommand.cs Uses final @(RuntimeEnvironmentVariable) items (when opted in) to set the launched command’s environment variables.
src/Cli/dotnet/Commands/Run/EnvironmentVariablesToMSBuild.cs Adds helpers to detect opt-in capability and read environment variables back from MSBuild items.
test/dotnet.Tests/CommandTests/Run/GivenDotnetRunSelectsDevice.cs Adds regression coverage asserting MSBuild target changes to env var items affect the launched app.
test/TestAssets/TestProjects/DotnetRunDevices/DotnetRunDevices.csproj Adds a target that mutates/injects @(RuntimeEnvironmentVariable) items prior to ComputeRunArguments for testing.
test/TestAssets/TestProjects/DotnetRunDevices/Program.cs Emits RUNE_* environment variables so tests can validate what the app actually received.

Comment thread src/Cli/dotnet/Commands/Run/EnvironmentVariablesToMSBuild.cs
rolfbjarne and others added 2 commits June 23, 2026 09:37
`ReadFromItems` hardcoded `StringComparer.Ordinal`, but `-e/--environment`
parsing uses `OrdinalIgnoreCase` on Windows (where environment variable
names are case-insensitive) and `Ordinal` elsewhere. Match that comparer so
the read-back item group dedups variable names consistently with the
original `-e` dictionary, avoiding subtle override/duplication issues when a
target changes the casing of a `@(RuntimeEnvironmentVariable)` item.

Addresses PR review feedback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/Cli/dotnet/Commands/Run/EnvironmentVariablesToMSBuild.cs Outdated
rolfbjarne and others added 2 commits June 24, 2026 13:03
Revert the previous OS-specific comparer change. As Jonathan Peppers noted,
the OS running `dotnet run` doesn't necessarily match the OS the app will run
on (e.g. building an Android project on Windows), so basing the comparer on
RuntimeInformation of the current process is incorrect. Use Ordinal and
preserve the @(RuntimeEnvironmentVariable) items exactly as MSBuild produced
them, with a comment explaining the reasoning.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The ReadFromItems and HasRuntimeEnvironmentVariableSupport helpers added for
'dotnet run -e' RuntimeEnvironmentVariable support previously only had
indirect, end-to-end coverage via the DotnetRunDevices CLI test. Add focused
in-memory unit tests that build a ProjectInstance from inline XML and exercise
both helpers directly:

- HasRuntimeEnvironmentVariableSupport: capability present/absent, only-other
  capabilities, and case-insensitive matching.
- ReadFromItems: empty, single, multiple items, and missing Value metadata.
- AddAsItems -> ReadFromItems round-trip.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread test/dotnet.Tests/CommandTests/Run/EnvironmentVariablesToMSBuildTests.cs Outdated
dotnet.Tests was migrated to MSTest.Sdk on main; merging that in left the two
test additions from this branch using xUnit [Fact], which no longer compiles
(CS0246 'Fact'). Convert them to MSTest:

- EnvironmentVariablesToMSBuildTests: add [TestClass], [Fact] -> [TestMethod].
- GivenDotnetRunSelectsDevice.ItHonorsRuntimeEnvironmentVariableChangesFromTargetsWhenRunningApp:
  [Fact] -> [TestMethod] (the rest of the class was already migrated by the merge).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants