fix(tasks): stop loading plugin assemblies with Assembly.LoadFrom - #112
Merged
Merged
Conversation
ApplyVersionNumber and ApplyPluginVersionNumberInSolution both run in-process inside the MSBuild worker node, which defaults to node reuse (/nodeReuse:true) and persists across separate dotnet build/ dotnet publish CLI invocations. Assembly.LoadFrom routes through AssemblyLoadContext.Default, so loading a same-identity plugin assembly a second time in a reused node throws "FileLoadException: Assembly with same name is already loaded" - intermittently, since it depends on which builds happen to share a live node. This showed up in the wild as a flaky MSB4018 failure building a Dataverse solution project that both directly and transitively (via another project's ProjectReference) contains a plugin assembly reference. Both tasks only ever need the assembly's name/version/public key token, never to execute it, so switch to AssemblyName.GetAssemblyName(path), which reads that identity straight from the PE headers without loading anything into any AssemblyLoadContext - eliminating the collision by construction.
There was a problem hiding this comment.
Pull request overview
Replaces plugin assembly loading with metadata-only identity reads, preventing assembly collisions in reused MSBuild workers.
Changes:
- Uses
AssemblyName.GetAssemblyNamein both versioning tasks. - Updates assembly identity/version access accordingly.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/Dataverse/Tasks/Tasks/ApplyVersionNumber.cs |
Reads plugin identities without loading assemblies. |
src/Dataverse/Tasks/Tasks/ApplyPluginVersionNumberInSolution.cs |
Reads plugin versions directly from PE metadata. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
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.
Summary
ApplyVersionNumberand its siblingApplyPluginVersionNumberInSolutionintermittently fail withMSB4018/System.IO.FileLoadException: ... Assembly with same name is already loaded, surfacing as a flaky failure building a Dataverse solution project that references a plugin assembly./nodeReuse:true, so a worker node persists across separatedotnet build/dotnet publishCLI invocations (~15 min idle timeout).Assembly.LoadFromroutes throughAssemblyLoadContext.Default, so if a same-identity plugin assembly gets loaded a second time in a reused node, the CLR throwsFileLoadException. Confirmed byte-identical in 1.8.2 and 1.8.3 — not something the 1.8.3 bump addressed. The sibling task has the identical pattern.Assembly.LoadFrom(path)withAssemblyName.GetAssemblyName(path), which reads that identity straight from the PE headers without loading anything into anyAssemblyLoadContext, eliminating the collision mechanism entirely (rather than working around a specific trigger condition).Testing
dotnet buildonTALXIS.DevKit.Build.Dataverse.Tasks.csproj: 0 errors.Assembly.LoadFromtwice in one process on the same assembly identity can throwFileLoadException/FileNotFoundExceptiondepending on file state; callingAssemblyName.GetAssemblyNametwice on the same path never touches anyAssemblyLoadContextand cannot hit this failure mode by construction.talxis.devkit.build.dataverse.tasks1.8.3, and ranTALXIS/alm-lab's fullLOCAL-DRY-RUN.mdflow (CP01→CP08, the exact sequence that originally reproduced the crash), plus 5 additional immediatedotnet buildrebuilds of the whole solution in the same shell session to maximize MSBuild node-reuse pressure. All builds succeeded with 0 errors.Generated by Claude Code