Skip to content

[msbuild] Merge runtimeconfig.dev.json into the runtime configuration. Fixes #26330 - #26332

Open
rolfbjarne wants to merge 3 commits into
mainfrom
dev/rolf/runtimeconfig-dev-json
Open

[msbuild] Merge runtimeconfig.dev.json into the runtime configuration. Fixes #26330#26332
rolfbjarne wants to merge 3 commits into
mainfrom
dev/rolf/runtimeconfig-dev-json

Conversation

@rolfbjarne

Copy link
Copy Markdown
Member

We bake the runtime configuration directly into the app and hand it to the runtime, bypassing hostfxr. hostfxr is what would normally merge the companion *.runtimeconfig.dev.json file into the main runtime configuration, so the Debug-only switches the .NET SDK writes there (such as Hot Reload's System.StartupHookProvider.IsSupported and System.Reflection.Metadata.MetadataUpdater.IsSupported) never reached the runtime.

Fix

Rather than teach the shared RuntimeConfigParserTask (from dotnet/runtime) about the dev file, this does the merge locally and keeps using that task unchanged:

  • New MergeRuntimeConfigFiles MSBuild task overlays the dev file's runtimeOptions.configProperties on top of the main file's (dev wins, matching hostfxr) and writes a merged json. If there is no dev file, or it has no configProperties, the main file is written out unchanged so the target's incremental Inputs/Outputs logic stays consistent.
  • _CreateRuntimeConfiguration now runs the merge into runtimeconfig.merged.json in the device-specific intermediate dir, feeds that to RuntimeConfigParserTask, adds the dev file to the target Inputs, and adds the merged file to FileWrites.
  • Added a unit test covering the merge (dev wins, main-only preserved, dev-only added), the no-dev-file case, and a dev file without configProperties.

This mirrors the equivalent fix in dotnet/android#12249.

Fixes #26330

🤖 Pull request created by Copilot

We bake the runtime configuration directly into the app and hand it to the
runtime, bypassing hostfxr. hostfxr is what would normally merge the companion
'*.runtimeconfig.dev.json' file (where the .NET SDK writes Debug-only switches
such as Hot Reload's System.StartupHookProvider.IsSupported and
System.Reflection.Metadata.MetadataUpdater.IsSupported) into the main runtime
configuration, so those switches never reached the runtime.

Add a new MergeRuntimeConfigFiles MSBuild task that overlays the dev file's
'runtimeOptions.configProperties' on top of the main file's (dev wins, matching
hostfxr), and feed the merged file to the existing RuntimeConfigParserTask.

Fixes #26330

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 28, 2026 14:42
@rolfbjarne
rolfbjarne requested a review from mauroa as a code owner July 28, 2026 14:42

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 a gap in the Apple workloads’ runtime initialization path: because we bypass hostfxr and bake runtime configuration directly into the app, *.runtimeconfig.dev.json wasn’t being merged, so Debug-only runtimeOptions.configProperties switches (notably Hot Reload-related switches) never reached the runtime.

Changes:

  • Add a new MSBuild task (MergeRuntimeConfigFiles) to overlay runtimeOptions.configProperties from *.runtimeconfig.dev.json onto the main *.runtimeconfig.json (dev wins), producing a merged JSON input for the existing RuntimeConfigParserTask.
  • Update _CreateRuntimeConfiguration to run the merge step, include the dev file in Inputs, and track the merged file in FileWrites.
  • Add unit tests covering merge behavior, missing dev file, and dev file without configProperties.

Reviewed changes

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

File Description
tests/msbuild/Xamarin.MacDev.Tasks.Tests/TaskTests/MergeRuntimeConfigFilesTaskTest.cs Adds unit coverage for merge semantics and no-dev/configProperties-absent cases.
msbuild/Xamarin.MacDev.Tasks/Tasks/MergeRuntimeConfigFiles.cs Implements the merge logic for runtimeOptions.configProperties into a merged runtimeconfig JSON.
msbuild/Xamarin.Localization.MSBuild/MSBStrings.resx Adds a localized error string for invalid runtimeconfig JSON root.
dotnet/targets/Xamarin.Shared.Sdk.targets Wires the merge task into _CreateRuntimeConfiguration and switches RuntimeConfigParserTask to use the merged file.
Comments suppressed due to low confidence (1)

msbuild/Xamarin.MacDev.Tasks/Tasks/MergeRuntimeConfigFiles.cs:65

  • The null-forgiving operator is used on outputDirectory!, but outputDirectory is already proven non-null by the IsNullOrEmpty check. The postfix ! operator is banned in this repo; use a simple block instead.
			var outputDirectory = Path.GetDirectoryName (OutputFile);
			if (!string.IsNullOrEmpty (outputDirectory))
				Directory.CreateDirectory (outputDirectory!);

Comment thread msbuild/Xamarin.MacDev.Tasks/Tasks/MergeRuntimeConfigFiles.cs Outdated
…, DeepClone.

Address Copilot review feedback on MergeRuntimeConfigFiles:
- Remove the banned null-forgiving (!) operator; use explicit null/length
  checks (netstandard2.0's string.IsNullOrEmpty isn't null-annotated).
- Catch read/parse failures and report them as an MSBuild error (E7186)
  instead of letting the task crash.
- Clone dev values with JsonNode.DeepClone () instead of serialize+parse.
- Add a regression test for the invalid-JSON error path.

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

@jonathanpeppers jonathanpeppers left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is a minimal perf thing I saw, but up to you if you want to fix. Those files are small, so may be fine. 👍

Comment thread msbuild/Xamarin.MacDev.Tasks/Tasks/MergeRuntimeConfigFiles.cs Outdated
Comment thread msbuild/Xamarin.MacDev.Tasks/Tasks/MergeRuntimeConfigFiles.cs Outdated
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

Per review feedback, avoid materializing the whole runtimeconfig file as a
string: parse directly from a FileStream (JsonNode.Parse (Stream)) and write
the merged result through a Utf8JsonWriter over a FileStream instead of
File.ReadAllText / File.WriteAllText.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@rolfbjarne rolfbjarne added the ready-to-review This PR is ready to review/merge. label Jul 28, 2026
@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

This comment has been minimized.

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

✅ API diff for current PR / commit

NET (empty diffs)

✅ API diff vs stable

NET (empty diffs)

ℹ️ Generator diff

Generator Diff: vsdrops (html) vsdrops (raw diff) gist (raw diff) - Please review changes)

Pipeline on Agent
Hash: eb03d7b1905dcbdacf1c1faa22abb26d401ae8bb [PR build]

@vs-mobiletools-engineering-service2

Copy link
Copy Markdown
Collaborator

🚀 [CI Build #eb03d7b] Test results 🚀

Test results

✅ All tests passed on VSTS: test results.

🎉 All 203 tests passed 🎉

Tests counts

✅ assembly-processing: All 1 tests passed. Html Report (VSDrops) Download
✅ cecil: All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (iOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (MacCatalyst): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (macOS): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (Multiple platforms): All 1 tests passed. Html Report (VSDrops) Download
✅ dotnettests (tvOS): All 1 tests passed. Html Report (VSDrops) Download
✅ framework: All 2 tests passed. Html Report (VSDrops) Download
✅ fsharp: All 4 tests passed. Html Report (VSDrops) Download
✅ generator: All 5 tests passed. Html Report (VSDrops) Download
✅ interdependent-binding-projects: All 4 tests passed. Html Report (VSDrops) Download
✅ introspection: All 4 tests passed. Html Report (VSDrops) Download
✅ linker (iOS): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (MacCatalyst): All 15 tests passed. Html Report (VSDrops) Download
✅ linker (macOS): All 21 tests passed. Html Report (VSDrops) Download
✅ linker (tvOS): All 15 tests passed. Html Report (VSDrops) Download
✅ monotouch (iOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (MacCatalyst): All 18 tests passed. Html Report (VSDrops) Download
✅ monotouch (macOS): All 19 tests passed. Html Report (VSDrops) Download
✅ monotouch (tvOS): All 19 tests passed. Html Report (VSDrops) Download
✅ msbuild: All 2 tests passed. Html Report (VSDrops) Download
✅ sharpie: All 1 tests passed. Html Report (VSDrops) Download
✅ windows: All 3 tests passed. Html Report (VSDrops) Download
✅ xcframework: All 4 tests passed. Html Report (VSDrops) Download
✅ xtro: All 1 tests passed. Html Report (VSDrops) Download

macOS tests

✅ Tests on macOS Monterey (12): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Ventura (13): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sonoma (14): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Sequoia (15): All 5 tests passed. Html Report (VSDrops) Download
✅ Tests on macOS Tahoe (26): All 5 tests passed. Html Report (VSDrops) Download

Linux Build Verification

Linux build succeeded

Pipeline on Agent
Hash: eb03d7b1905dcbdacf1c1faa22abb26d401ae8bb [PR build]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

copilot ready-to-review This PR is ready to review/merge.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

*.runtimeconfig.dev.json is ignored: Debug-only configProperties (Hot Reload switches) don't reach the runtime

5 participants