Fix #4079: make stable Roslyn restorable from the solution directory - #4081
Merged
Merged
Conversation
Closed
ICSharpCode.Decompiler.Generators pins a stable Microsoft.CodeAnalysis.CSharp (a source generator must not reference a Roslyn newer than the host compiler) and ILSpy.AddIn.VS2022 pins a stable 4.0.1. Stable Roslyn lives only on nuget.org, but the repo-root NuGet.config mapped Microsoft.CodeAnalysis.* exclusively to the dotnet-tools feed, which carries only prerelease builds. Both projects worked around that with a per-project NuGet.config. dotnet restore honors it, since settings are computed per project directory, but Visual Studio starts NuGet.config discovery at the solution directory and never sees it: the first restore in VS on a machine with a cold NuGet cache fails with NU1103 exactly as reported. Once any successful restore has put the stable package into the global packages folder, source mapping is satisfied from the cache and the problem never reappears on that machine, which is why #3835 was closed as unreproducible. NuGet consults every source that declares the longest pattern matching a package id, so mapping Microsoft.CodeAnalysis.* to nuget.org as well as to dotnet-tools makes both feeds available for the whole family: the stable versions resolve from nuget.org and the prerelease $(RoslynVersion) from dotnet-tools. Both per-project configs are then redundant and removed. Verified with an empty NUGET_PACKAGES and the root config forced as the only config (simulating VS's discovery): the old config reproduces the reported NU1103; with the new config the generator, the decompiler tests (prerelease Roslyn) and the VS add-in (stable 4.0.1 with its Workspaces dependencies) all restore; restore.ps1 over ILSpy.sln leaves the lock files unchanged. Assisted-by: Claude:claude-fable-5:Claude Code
siegfriedpammer
force-pushed
the
fix/4079-vs-nuget-source-mapping
branch
from
August 30, 2026 08:37
9262ad3 to
cd10506
Compare
christophwille
approved these changes
Aug 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #4079 (and the earlier, closed-as-unreproducible #3835).
Root cause.
ICSharpCode.Decompiler.Generatorspins a stableMicrosoft.CodeAnalysis.CSharp 5.0.0(a source generator must not reference a Roslyn newer than the host compiler) andILSpy.AddIn.VS2022pins a stable4.0.1. Stable Roslyn lives only on nuget.org, but the rootNuGet.configmappedMicrosoft.CodeAnalysis.*exclusively to the dotnet-tools feed, which carries only prerelease builds. Both projects worked around that with a per-projectNuGet.config-- whichdotnet restorehonors (settings are computed per project directory), but Visual Studio starts NuGet.config discovery at the solution directory and never sees it. So the first restore in VS on a machine with a cold NuGet cache fails with NU1103 exactly as reported. Once any successful restore lands the stable package in the global packages folder, source mapping is satisfied from the cache and the problem never reappears on that machine -- which is why it looked unreproducible for everyone who had built ILSpy before.Fix. Map
Microsoft.CodeAnalysis.*to nuget.org as well as to dotnet-tools. NuGet consults every source that declares the longest pattern matching a package id, so with the same pattern on both feeds the stable versions resolve from nuget.org and the prerelease$(RoslynVersion)from dotnet-tools. Both per-projectNuGet.configs are then redundant and removed.Verification (each with an empty
NUGET_PACKAGESand--configfile NuGet.config, i.e. the root config as the only config, simulating VS's solution-dir discovery):ICSharpCode.Decompiler.Generatorsrestores (5.0.0from nuget.org);ICSharpCode.Decompiler.Testsrestores (5.10.0-1.xfrom dotnet-tools);ILSpy.AddIn.VS2022restores (4.0.1plus itsWorkspaces/VisualBasic/Featuresdependencies from nuget.org);restore.ps1over the full solution: clean, nopackages.lock.jsonchanges.The reporter's
git rev-parse HEAD^^{commit}exit code 9009 is unrelated: git is not on their PATH (fresh Windows with only VS's private git). ThatExecisContinueOnError=trueandupdate-assemblyinfo.ps1has a no-git fallback, so it is a cosmetic warning only.This PR was authored by an AI agent (Claude Code) operating under the account owner's direction.