Skip to content

Fix LibLCM .NET 8 CI builds - #394

Merged
johnml1135 merged 1 commit into
sillsdev:masterfrom
johnml1135:fix/pin-dotnet8-ci
Aug 13, 2026
Merged

Fix LibLCM .NET 8 CI builds#394
johnml1135 merged 1 commit into
sillsdev:masterfrom
johnml1135:fix/pin-dotnet8-ci

Conversation

@johnml1135

@johnml1135 johnml1135 commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Pin SDK selection to .NET 8 until the planned .NET 10 migration.
  • Remove the redundant project-level OutDir override so multi-target inner builds use the per-framework OutputPath from Directory.Build.props.

Why

The hosted Windows runner selected .NET 10 because global.json allowed latestMajor. Pinning the SDK exposed an existing multi-target output collision on both Windows and Ubuntu: a net8.0 SIL.LCModel.Core.dll could be written to artifacts/Release/netstandard2.0, causing CS1705 when the netstandard SIL.LCModel target consumed it.

The project-level OutDir duplicated the repository-wide OutputPath and allowed a parent target's output directory to leak into referenced inner builds. Letting the SDK derive OutDir from the central OutputPath keeps netstandard2.0, net462, and net8.0 outputs separate.

Validation

  • dotnet --version: 8.0.424
  • dotnet build LCM.sln --configuration Release: passed with 0 errors
  • Full test stage: 5,638 passed, 40 skipped, 0 failed
  • dotnet pack LCM.sln --include-symbols --no-restore --no-build -p:SymbolPackageFormat=snupkg --configuration Release: all packages created

This change is Reviewable

Pin SDK selection to .NET 8 and rely on the central per-framework OutputPath instead of overriding OutDir in SIL.LCModel. This prevents net8 artifacts from contaminating netstandard output on hosted runners.
@johnml1135 johnml1135 changed the title Pin LibLCM builds to .NET 8 Fix LibLCM .NET 8 CI builds Aug 13, 2026
@johnml1135
johnml1135 requested review from hahn-kev and jasonleenaylor and removed request for hahn-kev and jasonleenaylor August 13, 2026 08:26
@johnml1135
johnml1135 merged commit 6e97da6 into sillsdev:master Aug 13, 2026
3 checks passed
thejambi pushed a commit that referenced this pull request Aug 14, 2026
Pin SDK selection to .NET 8 and rely on the central per-framework OutputPath instead of overriding OutDir in SIL.LCModel. This prevents net8 artifacts from contaminating netstandard output on hosted runners.
thejambi added a commit that referenced this pull request Aug 14, 2026
* Fix Windows CI by scoping IntermediateOutputPath per framework

Directory.Build.props sets AppendTargetFrameworkToOutputPath=false so that
OutputPath can place output under artifacts/$(Configuration)/$(TargetFramework)
itself. That flag also strips $(TargetFramework) from IntermediateOutputPath,
so all three target frameworks of a multi-targeted project shared a single obj
folder - including the reference assembly under obj/ref. Whichever framework
built last owned it.

ProjectReference resolution reads that reference assembly, so the
netstandard2.0 compile of SIL.LCModel could be handed the net8.0 build of
SIL.LCModel.Core:

  CSC : error CS1705: Assembly 'SIL.LCModel.Core' ... uses
  'System.Drawing.Primitives, Version=8.0.0.0' which has a higher version than
  referenced assembly 'System.Drawing.Primitives, Version=4.0.2.0'
  [SIL.LCModel.csproj::TargetFramework=netstandard2.0]

Build ordering decided whether this hit, which is why Windows failed while
Linux stayed green. #394 removed the OutDir override in SIL.LCModel and fixed
the bin side of the same problem; the intermediate side kept sharing one path.

Set IntermediateOutputPath to obj/$(Configuration)/$(TargetFramework)/ in
Directory.Build.props, and drop the obj/x86/$(Configuration)/ override in
SIL.LCModel.Core.csproj that predates multi-targeting and now conflicts with
it - Platform is Any CPU repo-wide, so the x86 segment bought nothing.
OutputPath and the artifacts layout are unchanged.

* Remove comments

Co-Authored-By: Zachary Burnham <zachary_burnham@sil.org>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
thejambi added a commit that referenced this pull request Aug 14, 2026
* Fix Windows CI by scoping IntermediateOutputPath per framework

Directory.Build.props sets AppendTargetFrameworkToOutputPath=false so that
OutputPath can place output under artifacts/$(Configuration)/$(TargetFramework)
itself. That flag also strips $(TargetFramework) from IntermediateOutputPath,
so all three target frameworks of a multi-targeted project shared a single obj
folder - including the reference assembly under obj/ref. Whichever framework
built last owned it.

ProjectReference resolution reads that reference assembly, so the
netstandard2.0 compile of SIL.LCModel could be handed the net8.0 build of
SIL.LCModel.Core:

  CSC : error CS1705: Assembly 'SIL.LCModel.Core' ... uses
  'System.Drawing.Primitives, Version=8.0.0.0' which has a higher version than
  referenced assembly 'System.Drawing.Primitives, Version=4.0.2.0'
  [SIL.LCModel.csproj::TargetFramework=netstandard2.0]

Build ordering decided whether this hit, which is why Windows failed while
Linux stayed green. #394 removed the OutDir override in SIL.LCModel and fixed
the bin side of the same problem; the intermediate side kept sharing one path.

Set IntermediateOutputPath to obj/$(Configuration)/$(TargetFramework)/ in
Directory.Build.props, and drop the obj/x86/$(Configuration)/ override in
SIL.LCModel.Core.csproj that predates multi-targeting and now conflicts with
it - Platform is Any CPU repo-wide, so the x86 segment bought nothing.
OutputPath and the artifacts layout are unchanged.

* Remove comments

Co-Authored-By: Zachary Burnham <zachary_burnham@sil.org>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.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.

2 participants