Skip to content

Fix patch build broken by StructureMap.dll leaving the output - #1092

Merged
jasonleenaylor merged 1 commit into
mainfrom
fix/patch-rescue-structuremap
Aug 20, 2026
Merged

Fix patch build broken by StructureMap.dll leaving the output#1092
jasonleenaylor merged 1 commit into
mainfrom
fix/patch-rescue-structuremap

Conversation

@jasonleenaylor

@jasonleenaylor jasonleenaylor commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Every patch build on main is failing. The last three runs of patch-installer-cd died the same way:

PYRO0305: Removing component 'cmpB2DE1D8180FB99B316E93ABBD53CB92B' from feature 'Complete'
         is not supported.
PYRO0305: The File 'StructureMap.dll' was removed in the patch.

Why it broke

liblcm swapped its IoC container from StructureMap to Microsoft.Extensions.DependencyInjection in SIL.LCModel 11.0.0-beta0176. Nothing copies StructureMap.dll into Output/Release any more, but the base build (9.3.10.1) still ships it. pyro will not let a patch drop a component from a feature, so the patch build fails outright.

The fix

RescuePatching in Build/Installer.legacy.targets already exists for exactly this case: it writes a zero-byte stand-in for a file the base ships that the build no longer emits, which keeps the component present so the patch is buildable without cutting a new base. StructureMap.dll is now listed there. That is the whole change -- one item and its comment.

StructureMap.dll is the only file to stand in for:

  • Its net45 dependency (System.Reflection.Emit.Lightweight) resolved from the framework and was never shipped -- it does not appear in the base MSI's file list.
  • The replacement assemblies are additions, which a patch handles. The base already shipped Microsoft.Extensions.DependencyInjection.Abstractions.dll and Microsoft.Bcl.AsyncInterfaces.dll; only Microsoft.Extensions.DependencyInjection.dll is new.
  • StructureMap.xml was never shipped either -- the base lists only the .dll.

The existing BuildProductBaseMsi warning ("RemovedSinceLastBase should be cleared out before making a new base build") already covers the follow-up: whoever cuts the next base build gets told to clear this entry. Verified it still fires with the item populated, since BuildProductMain and BuildProductBaseMsi run in the same nested MSBuild invocation and the target-scoped item survives across them.

Verification

dir-outputBase is assigned inside the Setup target rather than a static PropertyGroup, and nothing in the installer target chain names Setup in its DependsOnTargets, so I checked that it is actually populated by the time RescuePatching runs instead of assuming it. Running the target directly:

PROBE dir-outputBase=[...\Output\Release] Configuration=[Release] config=[release]

That is the same directory CopyFilesToInstall harvests ($(fwrt)\Output\$(Configuration)), and RescuePatching runs before it in BuildProductMain, so the placeholder is picked up into the install image.

Running Build/InstallerBuild.proj /t:RescuePatching writes Output/Release/StructureMap.dll at 0 bytes. Running /t:RescuePatching;BuildProductBaseMsi additionally emits the existing base-build reminder:

Installer.legacy.targets(672,3): warning : RemovedSinceLastBase should be cleared out
                                           before making a new base build.

Not verified locally: a full -BuildPatch, which needs a Release build plus the base MSI and the WiX toolchain. CI on this PR is the real test.

What this does not do

This keeps patching alive without a new base build, which is the documented purpose of RescuePatching. It does not remove the component for real -- that needs a new base build, at which point this RemovedSinceLastBase entry should be deleted.

A zero-byte unversioned StructureMap.dll replacing a versioned one is subject to MSI's file-versioning rules, so an installed copy may well be left on disk untouched. That is harmless: nothing loads it any more.

🤖 Generated with Claude Code


This change is Reviewable

@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown

Comment hygiene (advisory)

3 comment-style violation(s) in the lines this branch adds since origin/main.
Advisory only -- no check fails on these, and the same violations appear as inline warnings on the Files changed tab.

File Category Comment
Build/Installer.legacy.targets:116 comment-line-too-long 111 columns (max 98): liblcm swapped its IoC container from StructureMap to Microsoft.Exte...
Build/Installer.legacy.targets:117 comment-line-too-long 110 columns (max 98): in SIL.LCModel 11.0.0-beta0176, so nothing copies StructureMap.dll t...
Build/Installer.legacy.targets:115 comment-too-long 288 chars (budget 200): <RemovedSinceLastBase Include="$(dir-outputBase)/Helps/WW-Conceptu...

Fix them per .claude/skills/fieldworks-code-commenting/SKILL.md.
Running .\build.ps1 -CommentHygiene (or .\test.ps1 -CommentHygiene) enforces them locally, and
re-wraps over-wide lines and repairs non-ASCII punctuation as it goes.

liblcm swapped its IoC container from StructureMap to
Microsoft.Extensions.DependencyInjection in SIL.LCModel 11.0.0-beta0176, so
nothing copies StructureMap.dll into Output/Release any more. The base build
still ships it, and pyro refuses to drop a component from a patch, so every
patch build fails with PYRO0305.

RescuePatching already exists for this: it writes a zero-byte stand-in for a
file the base ships that the build no longer emits, which keeps the component
present. StructureMap.dll is now listed there. Its transitive dependencies were
resolved from the framework and never shipped, and the replacement DI
assemblies are additions, which a patch handles, so this is the only file to
stand in for.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jasonleenaylor
jasonleenaylor force-pushed the fix/patch-rescue-structuremap branch from 09c5570 to 39eced0 Compare August 20, 2026 05:37
@jasonleenaylor
jasonleenaylor merged commit caeeeb1 into main Aug 20, 2026
6 checks passed
@jasonleenaylor
jasonleenaylor deleted the fix/patch-rescue-structuremap branch August 20, 2026 05:39
@codecov-commenter

codecov-commenter commented Aug 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 38.31%. Comparing base (11a2396) to head (39eced0).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1092      +/-   ##
==========================================
- Coverage   38.31%   38.31%   -0.01%     
==========================================
  Files        1507     1507              
  Lines      350524   350524              
  Branches    40288    40288              
==========================================
- Hits       134315   134311       -4     
- Misses     186978   186981       +3     
- Partials    29231    29232       +1     

see 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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.

2 participants