Skip to content

Comments

build: Fix parallel build race on Analyzers.Common deps file#37

Merged
DrBarnabus merged 1 commit intomainfrom
fix/analyzers-common-parallel-build-race
Feb 15, 2026
Merged

build: Fix parallel build race on Analyzers.Common deps file#37
DrBarnabus merged 1 commit intomainfrom
fix/analyzers-common-parallel-build-race

Conversation

@DrBarnabus
Copy link
Owner

@DrBarnabus DrBarnabus commented Feb 15, 2026

Add GlobalPropertiesToRemove="TargetFramework" to ProjectReference items for CompositeKey.Analyzers.Common in multi-targeted projects.

Without this, each parent TFM passes its own TargetFramework as a global property, causing MSBuild to treat them as separate build requests that can run concurrently—all writing to the same netstandard2.0 output directory and racing on the .deps.json file.

Summary by CodeRabbit

Release Notes

  • Chores
    • Updated internal build configuration to optimise project reference handling across the codebase.

Add GlobalPropertiesToRemove="TargetFramework" to ProjectReference
items for CompositeKey.Analyzers.Common in multi-targeted projects.
Without this, each parent TFM passes its own TargetFramework as a
global property, causing MSBuild to treat them as separate build
requests that can run concurrently—all writing to the same
netstandard2.0 output directory and racing on the .deps.json file.
@coderabbitai
Copy link

coderabbitai bot commented Feb 15, 2026

Walkthrough

Four C# project files are modified to add a GlobalPropertiesToRemove="TargetFramework" attribute to their ProjectReference entries for CompositeKey.Analyzers.Common.csproj. This MSBuild adjustment removes the TargetFramework global property from the referenced project during evaluation, affecting cross-project property inheritance without altering functional code.

Changes

Cohort / File(s) Summary
MSBuild ProjectReference Configuration
src/CompositeKey.Analyzers.Common.UnitTests/CompositeKey.Analyzers.Common.UnitTests.csproj, src/CompositeKey.Analyzers.UnitTests/CompositeKey.Analyzers.UnitTests.csproj, src/CompositeKey.Analyzers/CompositeKey.Analyzers.csproj, src/CompositeKey.SourceGeneration/CompositeKey.SourceGeneration.csproj
Added GlobalPropertiesToRemove="TargetFramework" attribute to ProjectReference for CompositeKey.Analyzers.Common.csproj in each file, standardising cross-project property handling across the analyser and source generation components.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~4 minutes

Possibly related PRs

Poem

🐰 ✨ A hop, skip and jump through four files we go,
Global properties removed, like frost on the snow,
TargetFramework whisked away with care,
Cross-project unity—now they all share! 🌟

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding GlobalPropertiesToRemove to fix a parallel build race condition affecting the Analyzers.Common project's dependencies file.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Merge Conflict Detection ✅ Passed ✅ No merge conflicts detected when merging into main

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/analyzers-common-parallel-build-race

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Feb 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.66%. Comparing base (7675481) to head (22ce2b8).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #37   +/-   ##
=======================================
  Coverage   87.66%   87.66%           
=======================================
  Files          35       35           
  Lines        2099     2099           
  Branches      344      344           
=======================================
  Hits         1840     1840           
  Misses        157      157           
  Partials      102      102           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@DrBarnabus DrBarnabus merged commit 42da9b2 into main Feb 15, 2026
4 checks passed
@DrBarnabus DrBarnabus deleted the fix/analyzers-common-parallel-build-race branch February 15, 2026 11:53
DrBarnabus added a commit that referenced this pull request Feb 22, 2026
The previous fix (#37) added GlobalPropertiesToRemove="TargetFramework"
to all direct references to Analyzers.Common, but transient CI failures
persisted. Investigation revealed two root causes:

1. Missing fix on Analyzers.UnitTests -> Analyzers reference: The
   3-TFM test project (net10.0/net9.0/net8.0) passed its own
   TargetFramework to the multi-targeted Analyzers project without
   SetTargetFramework, creating 3 parallel build configurations that
   all converged on Analyzers.Common simultaneously.

2. Inconsistent ProjectReference strategies across consuming projects:
   FunctionalTests used SetTargetFramework="TargetFramework=netstandard2.0"
   on its Analyzers.Common reference while all other projects used
   GlobalPropertiesToRemove="TargetFramework". These produce different
   MSBuild global property sets ({TargetFramework=netstandard2.0} vs {})
   for the same single-targeted project, creating two distinct build
   configurations both writing to the same output directory — the actual
   source of the race condition.

The correct strategy depends on whether the referenced project is
single-targeted or multi-targeted:

- Single-targeted (Analyzers.Common): Use GlobalPropertiesToRemove to
  strip TargetFramework. This produces a config matching the solution's
  natural build, so MSBuild deduplicates correctly.

- Multi-targeted (Analyzers, SourceGeneration): Use SetTargetFramework
  to pin to netstandard2.0. This matches one of the inner builds
  dispatched by the solution's outer multi-target build.

Additionally, --graph is added to the CI build command as
defense-in-depth. Graph builds evaluate the full project dependency
graph upfront and ensure each project+config is built exactly once in
topological order.
DrBarnabus added a commit that referenced this pull request Feb 22, 2026
The previous fix (#37) added GlobalPropertiesToRemove="TargetFramework"
to all direct references to Analyzers.Common, but transient CI failures
persisted. Investigation revealed two root causes:

1. Missing fix on Analyzers.UnitTests -> Analyzers reference: The
   3-TFM test project (net10.0/net9.0/net8.0) passed its own
   TargetFramework to the multi-targeted Analyzers project without
   SetTargetFramework, creating 3 parallel build configurations that
   all converged on Analyzers.Common simultaneously.

2. Inconsistent ProjectReference strategies across consuming projects:
   FunctionalTests used SetTargetFramework="TargetFramework=netstandard2.0"
   on its Analyzers.Common reference while all other projects used
   GlobalPropertiesToRemove="TargetFramework". These produce different
   MSBuild global property sets ({TargetFramework=netstandard2.0} vs {})
   for the same single-targeted project, creating two distinct build
   configurations both writing to the same output directory — the actual
   source of the race condition.

The correct strategy depends on whether the referenced project is
single-targeted or multi-targeted:

- Single-targeted (Analyzers.Common): Use GlobalPropertiesToRemove to
  strip TargetFramework. This produces a config matching the solution's
  natural build, so MSBuild deduplicates correctly.

- Multi-targeted (Analyzers, SourceGeneration): Use SetTargetFramework
  to pin to netstandard2.0. This matches one of the inner builds
  dispatched by the solution's outer multi-target build.

Additionally, --graph is added to the CI build command as
defense-in-depth. Graph builds evaluate the full project dependency
graph upfront and ensure each project+config is built exactly once in
topological order.
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.

1 participant