Skip to content

.NET: Foundry.Hosting IT - avoid MSB3026 in publish step - #5689

Merged
Roger Barreto (rogerbarreto) merged 3 commits into
mainfrom
features/foundry-hosting-it-msb3026-fix
May 7, 2026
Merged

.NET: Foundry.Hosting IT - avoid MSB3026 in publish step#5689
Roger Barreto (rogerbarreto) merged 3 commits into
mainfrom
features/foundry-hosting-it-msb3026-fix

Conversation

@rogerbarreto

@rogerbarretoRoger Barreto (rogerbarreto) commented May 7, 2026

Copy link
Copy Markdown
Member

Problem

CI run https://github.com/microsoft/agent-framework/actions/runs/25446865848/job/74653338378 failed in the dotnet-foundry-hosted-it job with:

error MSB3026: Could not copy "obj/Release/net10.0/Microsoft.Agents.AI.Abstractions.dll"
to "bin/Release/net10.0/Microsoft.Agents.AI.Abstractions.dll".
The process cannot access the file ... because it is being used by another process.

Root cause

Job run two MSBuild back to back on same tree:

  1. Build Foundry hosted IT (and its deps) fill dotnet/src/<lib>/bin/Release/net10.0/*.dll. Helper process (VBCSCompiler) keep file handle open.
  2. it-build-image.ps1 run dotnet publish for linux-musl-x64. Publish rebuild same lib DLL into same path. First build still hold handle. Boom: MSB3026.

Fix

In it-build-image.ps1 add explicit opt-in switch -UsePrebuiltProjectReferences. CI pass switch -> publish skip ProjectReference rebuild, eat prebuilt DLL in place. No file lock fight, no extra rebuild.

Local default = no switch = publish rebuild as normal. If user have stale obj/Release/net10.0 from old build, preflight throw clear error: tell user to pass switch OR delete old obj. No silent stale image.

CI keep prebuild step. Test --no-build need it too.

Bonus: fix flaky UT

Same PR run hit flaky test AgentFrameworkResponseHandlerTelemetryTests.CreateAsync_AlreadyInstrumentedAgent_EmitsSingleSpanPerRunAsync:

System.InvalidOperationException : Collection was modified; enumeration operation may not execute.

Test use plain List<Activity> for OTel AddInMemoryExporter. Exporter write from background Activity stop callback. Parallel test on same global ActivitySource feed every listener. Add race with assertion enumerate. Boom.

Fix: tiny ConcurrentActivityList : ICollection<Activity> wrapper. Lock add/enumerate. Test call Snapshot() for assertion (lock + copy). All 4 telemetry test use it.

Verification

Local repro on Windows, three path:

PathSetupSwitchResult
Aclean checkoutnonepublish + docker build OK
Bprebuild done-UsePrebuiltProjectReferencesskip rebuild, Abstractions.dll ticks unchanged before/after
Cprebuild donenonepreflight throw with recovery instructions

Telemetry UT: 30 isolated runs + 5 full assembly runs (216 test each), 0 fail.

CopilotAI 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

Addresses intermittent dotnet publish failures (MSB3026 file-in-use) in the Foundry.Hosting integration-test container build by avoiding a second rebuild of referenced libraries when they were already built by the job’s prebuild step.

Changes:

  • Updated it-build-image.ps1 to detect prebuilt library outputs and conditionally add -p:BuildProjectReferences=false to dotnet publish.
  • Added workflow documentation explaining why the prebuild step exists and why publish is configured to avoid rebuilding project references.

Reviewed changes

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

FileDescription
dotnet/tests/Foundry.Hosting.IntegrationTests/scripts/it-build-image.ps1Adds conditional logic to skip ProjectReference rebuild during publish when prebuilt outputs exist.
.github/workflows/dotnet-build-and-test.ymlDocuments the CI rationale for the publish behavior to prevent MSB3026 collisions.

Comment threaddotnet/tests/Foundry.Hosting.IntegrationTests/scripts/it-build-image.ps1 Outdated
@rogerbarreto
Roger Barreto (rogerbarreto)force-pushed the features/foundry-hosting-it-msb3026-fix branch from 247b632 to 0bf21e4CompareMay 7, 2026 09:43

@github-actionsgithub-actionsBot 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.

Automated Code Review

Reviewers: 4 | Confidence: 93% | Result: All clear

Reviewed: Correctness, Security Reliability, Test Coverage, Design Approach


Automated review by rogerbarreto's agents

…flake
CI publish step: gate the BuildProjectReferences=false fast-path on an explicit -UsePrebuiltProjectReferences switch (passed by the workflow) instead of marker detection. Adds a preflight error when stale obj/Release/net10.0 outputs would cause CS0579, with actionable recovery instructions.
Telemetry UT flake: AgentFrameworkResponseHandlerTelemetryTests was using a plain List<Activity> for OTel's InMemoryExporter. The exporter writes from background Activity completion callbacks while parallel tests on the same global ActivitySource feed every listener, racing against the assertion's enumeration and throwing 'Collection was modified'. Replaced with a small thread-safe ConcurrentActivityList that locks add/enumerate and returns a snapshot for assertions.
@github-merge-queue
github-merge-queueBot removed this pull request from the merge queue due to failed status checks May 7, 2026
@github-merge-queue
github-merge-queueBot removed this pull request from the merge queue due to failed status checks May 7, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NETUsage: [Issues, PRs], Target: .Net

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

5 participants

@rogerbarreto@lokitoth@SergeyMenshykh@moonbox3