@nx/dotnet: expose structured evaluated MSBuild metadata and framework/RID-specific target variants
#36676
Replies: 2 comments 2 replies
|
I have opened the proposed work as small draft contributions for design review:
The first four are independent against |
|
Hey @Redth, thanks for putting this together, and for splitting it up the way you did. Five scoped PRs with the design written out separately made this genuinely reviewable, which is not what usually happens with a change this size. We want all of it. Three are close. The variant work is the right idea, and we've settled the open design questions on our side so you're not left guessing. Verdicts
Discrete feedback is on each PR. One correction to the framing: there's more precedent here than your writeup assumes. Variants: your first instinct was right
What we settled:
Sequencing, and an offer#36680 needs Also worth saying plainly: this is more rework than you signed up for, particularly on #36680. If you'd rather not carry it, we're happy to take those two on ourselves with you credited. The design is yours either way. Whichever you prefer is fine by us. On host and environment requirements
Our posture is Nx Cloud plus agents, with assignment rules routing targets to the right resource class by target name or glob. Docs: https://nx.dev/docs/kb/assignment-rules That answer only works because of #36680 and #36681. Assignment rules match on target name, so without per-TFM targets there's nothing to route. The variants aren't just a caching improvement for us, they're the prerequisite for the routing story. And a heads up: if this is for MAUI or another OSS project, we offer Nx Cloud free for qualifying open source projects. Worth pursuing. |
Uh oh!
There was an error while loading. Please reload this page.
Description
Would the Nx team be open to extending the existing
@nx/dotnetMSBuild analyzer so it exposes more of the evaluated project-system model and can represent framework/RID-specific task variants?The current analyzer already has the right architecture: a thin Nx plugin invokes a C# analyzer that constructs an MSBuild
ProjectGraph, evaluates project properties and items, and generates Nx targets with commands, inputs, outputs, caching, and dependencies.I've have been prototyping an additive metadata layer in
Redth/Maui.BuildHelpers/DotnetNx. That work started from cross-platform .NET and MAUI CI needs, but the useful concepts are general .NET project-system concepts rather than MAUI-specific behavior.After comparing the prototype with Nx core and first-party inferred-task plugins, I think the upstream opportunity is narrower and more Nx-aligned than upstreaming the CLI wrapper, companion plugin, or Actions.
Proposed capabilities
1. Structured evaluated .NET metadata
Expose a stable, namespaced metadata model from the existing MSBuild evaluation, potentially under
metadata.dotnet.At project scope:
projectTypewhen the analyzer can confidently distinguish an executable application from a library..NET, project language, and detected SDK technologies.Per evaluated target framework:
The intent is not to mirror every MSBuild property. It is to expose a small model that affects how projects and tasks are understood by Nx.
This must come from evaluated MSBuild state rather than XML parsing so SDK defaults, imports,
Directory.Build.props, conditions, and inner builds are handled correctly.2. Keep capabilities aligned with Nx targets
Facts such as “testable,” “packable,” “publishable,” and “runnable” are overlapping capabilities rather than mutually exclusive project types.
The generated targets should remain authoritative:
testtarget represents testability.packtarget represents packaging.publishtarget represents publication/deployment preparation.runtarget represents executability.Structured metadata can make those evaluated facts inspectable, while
projectTyperemains limited to Nx’s nativeapplication/librarydistinction.Note: I am not proposing automatically generating broad
type:*tags for these facts.3. Framework- and RID-specific target configurations
Multi-targeted projects expose a correctness issue that project-level metadata alone cannot solve.
For example, a project targeting both iOS and Windows may have no host capable of running an unqualified
dotnet buildacross every target framework. Treating it as independently “macOS-compatible” and “Windows-compatible” at project scope is misleading.Where command semantics are known,
@nx/dotnetcould represent framework/RID variants as Nx target configurations or generated target variants:The exact naming is open for discussion. The important part is that each variant has correct:
Debug/Release should continue to use normal Nx target configurations rather than tags.
4. Explicit tags from evaluated MSBuild
Some repositories intentionally keep project taxonomy in
Directory.Build.propsand project files. It may be useful for the analyzer to support explicit Nx tags supplied through evaluated MSBuild properties/items:A conditioned value should remain associated with that framework configuration. It should only be promoted to a project-wide tag when it applies to every evaluated configuration.
This keeps tags developer-authored and suitable for architecture/boundary rules.
5. Optional selector projection
Nx project selection can filter arbitrary dimensions through tags, while custom metadata is primarily inspectable. There may therefore be value in an opt-in projection of a small allow-list of metadata dimensions into namespaced selector tags:
I wouldn't enable this by default, and would avoid high-cardinality projections such as package IDs or every evaluated property.
This portion may be better left to a companion plugin if inferred tags do not fit first-party plugin conventions. The structured metadata is independently useful.
Host and environment requirements
Cross-platform repositories also need to route tasks to compatible agents, but a target framework alone cannot prove that a task is runnable in an environment.
Host requirements vary by target:
Because of this, I would not propose a project-wide “buildable on OS” flag inferred solely from TFMs, since there's just too many factors to make the right inference from.
A future model could expose explicit target/configuration requirements or executor constraints. Until Nx has such a concept, this information can remain namespaced target metadata consumed by CI tooling. Inference should be clearly advisory and retain its provenance.
Motivation
Cross-platform .NET repositories repeatedly need to answer:
These facts already exist in evaluated MSBuild state. Exposing them through
@nx/dotnetavoids parallel XML parsing and lets Nx model task variants more accurately..NET MAUI is one example because a single workspace commonly contains Android, Apple, Windows, test, tool, package, and platform-neutral projects. The proposal is not MAUI-specific and should not special-case MAUI.
Non-goals
This proposal does not ask Nx to adopt:
nxdnCLI wrapper.@redth/dotnet-nxcompanion plugin.Prior implementation and lessons
The current prototype demonstrates:
It also helped identify approaches I no longer recommend:
This could be split into smaller contributions against the existing analyzer. If you're all open to this, I could split it into:
projectType/technology improvementsAll reactions