Skip to content

Audit cross-platform coverage of template dependency manifests #20626

Description

Is there an existing issue for this?

  • I have searched the existing issues

Is your feature request related to a problem? Please describe the problem.

Follow-up to #20574 and #20451. The new template dependency manifest generator evaluates dependency-affecting template options and target frameworks, restores independent graphs, and emits a cgmanifest.json for Component Governance. Restore runs on the host executing the build; it does not explicitly enumerate every supported target RID or union results from every host OS.

The observed Windows and Linux inventories differed only in .NET apphost/reference packs:

  • Windows contained Microsoft.NETCore.App.Host.win-x64 where Linux contained Microsoft.NETCore.App.Host.linux-x64.
  • Windows additionally contained Microsoft.WindowsDesktop.App.Ref.
  • These differences occurred for the .NET 8, 9, and 10 targeting inputs. No other package-identity differences were found in that comparison. macOS and the full RID space have not been audited.

This is a small, bounded follow-up based on the evidence so far—not a demonstrated omission of ordinary template library dependencies. Do not block #20574 or expand its implementation to address this now.

Describe the solution you'd like

Audit and document the intended cross-platform coverage of template dependency discovery, then add only the work needed to meet that scope:

  1. Decide whether the inventory should cover normal template development configurations, all supported deployment RIDs, SDK/reference/tooling packages, or a documented subset.
  2. Compare representative Windows, Linux, and macOS restores and relevant RID-specific restores. Identify concrete package/version differences and their causes.
  3. Distinguish target-RID selection from host-dependent MSBuild evaluation. Restoring a target RID does not change $(OS), IsOSPlatform(...), or NETCoreSdkRuntimeIdentifier, so enumerating RIDs alone is not a general substitute for host-OS coverage.
  4. If additional coverage is warranted, deduplicate equivalent graphs and union the resulting inventories efficiently, with focused regression tests for the discovered boundaries.
  5. Record intentional exclusions and validate any expanded manifest through the actual CG scan.

The npm path already reads all lockfile entries, including optional platform packages, rather than installing only packages applicable to the current OS. Do not add an npm installation matrix without evidence that it is needed.

Preserve the performance goal of #20451: avoid reintroducing full template application builds, execution, or the SDK/TFM behavioral test matrix merely for dependency discovery.

Additional context

#20574 replaces the expensive internal basic-template test step with generated dependency manifests. Current evidence supports shipping that improvement while tracking the remaining platform-scope question separately.

Useful regression boundaries include a package with genuinely RID-specific dependencies and an SDK/MSBuild target that introduces dependencies based on the host OS. These exercise different behaviors and should not be treated as interchangeable.

Activity

  1. joperezr commented on Sep 30, 2026

    @joperezr
    Member
    🤖 Aspire triage pass — 2026-09-30 22:43 UTC

    Area: area-engineering-systems
    Kind: feature-request
    Repro: partial — see lines 9–13 and 19–25 of the issue body
    Affected version(s): unreleased main after #20574 (latest: 13.6.0)
    Severity: S4 — cross-platform coverage needs definition and audit, but no ordinary template dependency omission is demonstrated

    Urgency: ⚪ backlog — no milestone
    Reason: bounded follow-up with incomplete platform evidence and no demonstrated released-product impact

    Suggested owner(s): Ankit Jain (@radical) (score 55)
    Evidence:

    Confidence: medium
    Needs human?: no

  2. DamianEdwards commented on Oct 1, 2026

    @DamianEdwards
    MemberAuthor

    Completed a restore-only audit on all seven supported native platforms: Windows x64/ARM64, Linux x64/ARM64, Linux musl x64, and macOS x64/ARM64.

    The dependency investigation is complete enough to implement broader coverage. The remaining risk is CI orchestration cost, not dependency discovery. This remains non-blocking: no ordinary template-library omission was found, and production generation/pipeline behavior is unchanged.

    Findings

    Using SDK 11.0.100-rc.1.26425.128, each host ran the existing development restore and a separate experiment with all seven RuntimeIdentifiers. No generated applications were built or run, and no npm installs were performed.

    Inventory NuGet npm Total
    Existing Windows native inventory 220 177 397
    Union of all seven native-development inventories 238 177 415
    Union of seven-RID restores across all seven hosts 309 177 486

    The native-development union adds only 18 apphost package/version pairs over Windows: Microsoft.NETCore.App.Host.<rid> versions 8.0.31, 9.0.20, and 10.0.12 for the other six supported RIDs. No other NuGet package/version differences were found across the native hosts; the npm inventories were identical.

    The blanket multi-RID approach adds 71 registrations beyond the native-development union: seven .NET 11 apphost packs and 64 runtime packs. It causes SDK runtime-pack prefetch even without enabling self-contained publishing, so it expands the inventory beyond normal development restores.

    Host evaluation still matters with the same target-RID list. Windows includes WindowsDesktop packs absent on other hosts, and an SDK's locally supplied apphost pack can be absent from its download registrations. Neither RuntimeIdentifier nor RuntimeIdentifiers changes $(OS), IsOSPlatform(...), or NETCoreSdkRuntimeIdentifier.

    Performance and validation

    On the Windows CI audit host, native generation took 66.52 seconds and the subsequent seven-RID generation took 149.89 seconds. These are generator wall times, not pipeline durations or controlled cold-cache benchmarks; the second run reused the first run's external extraction cache. The original approximately 42-second production step remains the baseline, not a timing we can promise an expanded workflow will retain.

    The actual internal Windows and macOS CG scans accepted the audit manifests completely: Windows had 397/397 native and 485/485 expanded registrations attributed to the respective manifests; macOS had 394/394 and 474/474. Each comparison had zero missing or extra registrations. This validates those manifests' ingestion, not an as-yet-unimplemented final seven-host merge stage.

    Audit evidence includes internal builds 3092268, 3092282, and 3092286, plus successful native Helix runs for Windows ARM64, Linux ARM64, and macOS x64. The first two internal runs had unrelated audit-setup failures on other legs; the relevant successful host results were collected individually, and the final Alpine-only run succeeded.

    The internal legs reused one same-build package artifact. Public Helix legs used the public package artifact from run 36766773701; Windows control runs with the public and internal inputs produced identical external manifests for both restore modes. Internal artifacts were not submitted to public queues.

    Recommended implementation

    For all-supported-platform development coverage, use native-host restores and union their manifests, rather than setting a blanket RuntimeIdentifiers list:

    1. Distribute identical SDK/package inputs and the already-built generator to actual supported hosts; run the existing deduplicated restore graphs in parallel.
    2. Require every expected host result and matching input/SDK versions. Fail rather than publish a partial inventory.
    3. Union normalized component identities into the existing artifacts/cg/templates/cgmanifest.json, preserving exact same-build exclusions and synthetic-workspace cleanup.
    4. Validate that final combined artifact through the actual CG scan and measure both generation time and the pipeline's critical path.

    The existing native-build RID matrix cannot simply be treated as native-host coverage: some ARM64/musl jobs cross-build on x64, and an osx-x64 target can run on an ARM64 agent. Scheduling real host execution and aggregating artifacts is the substantive implementation work, and queueing/SDK setup may dominate its cost.

    No full template build/run matrix, npm installation matrix, arbitrary .NET deployment-RID coverage, or installed SDK/workload inventory is proposed. The ItemGroup normalization work in #20629 remains separate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions