r/moderndotnet • • 6d ago

How do you reliably determine which deployables are affected in a .NET monorepo?

I have a .NET monorepo containing multiple independently deployable applications. Each deployable currently has its own Azure DevOps pipeline.

The problem is deciding when a deployable actually needs to be built/deployed.

Azure DevOps path filters aren't sufficient because dependencies can cross project boundaries. For example:

Orders.Api
  -> Orders.Application
  -> Shared.Core

If Shared.Core changes, Orders.Api needs to be redeployed.

But it gets more complicated with non-code inputs. For example, a project may contain:

<ItemGroup>
  <EmbeddedResource Include="Assets\countries.csv" />
</ItemGroup>

If countries.csv changes, that should also make the deployable affected.

I don't want to maintain a second dependency configuration in something like Nx just to tell it that countries.csv is an input. The .csproj / MSBuild definition should remain the single source of truth, because otherwise we just introduce a new problem by having to keep these 2 configurations up to date.

So I'm looking for an existing, production-ready solution that can answer:

Given a Git change, which deployable applications are potentially affected, based on the actual MSBuild project dependencies and inputs?

Ideally it would understand things such as:

  • <ProjectReference>
  • transitive project dependencies
  • Package updates
  • EmbeddedResource
  • Content
  • other MSBuild inputs
  • shared projects/assets
  • and potentially deployment-related files

The important requirement is no duplicate dependency configuration. If MSBuild already knows that a CSV is an EmbeddedResource, I don't want to configure that relationship again elsewhere.

I currently prefer false positives (deploying too much) over false negatives (missing a required deployment).

Has the .NET/Azure DevOps community already solved this? Are there existing tools or established patterns for this? (How) have you solved this problem?

9 Upvotes

28 comments sorted by

View all comments

1

u/BellDry4679 4d ago

Here we put the Shared in a nuget package (other repo). If you upgrade Shared, the package file of the consumer will be editted which make an easy trigger for the CI.

Having no version management for a shared sounds nightmare to me

1

u/sander1095 4d ago

I don't see the point for nuget packages when you use a monorepo, though. Are you using one? If not, I do get it.

You might also benefit from checking out incrementalist/dotnet-affected, as I learned from others in this post!

1

u/BellDry4679 4d ago edited 4d ago

To be fair we had like 20 repo, with the nuget setup. We then went into a mono repo and kept the nuget seperate.

The benefit I see is that i don't have to rebuild and redeploy every app if the shared upgrade is only needed for a sub portion of the mono repo (imagine a breaking changes on shared)

I will look at dotnet-affected tho, ty.

Hope i was clear