Skip to content

Enable Central Package Management with transitive pinning#20084

Open
T-Gro wants to merge 24 commits into
mainfrom
t-gro-enable-cpm-transitive-pinning
Open

Enable Central Package Management with transitive pinning#20084
T-Gro wants to merge 24 commits into
mainfrom
t-gro-enable-cpm-transitive-pinning

Conversation

@T-Gro

@T-Gro T-Gro commented Jul 24, 2026

Copy link
Copy Markdown
Member

Turn on NuGet Central Package Management with transitive pinning across the
repo: package versions now come from a single central list (eng/Packages.props),
and vulnerable transitive dependencies such as System.Security.Cryptography.Xml
are pinned repo-wide.

This unblocks removing the -warnNotAsErrors NuGet Audit workaround for fsharp
in the dotnet/dotnet VMR.

T-Gro and others added 19 commits July 22, 2026 21:25
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Uses ImportDirectoryPackagesProps=false (reliable subtree opt-out; a
Directory.Build.props-level ManagePackageVersionsCentrally=false is
overridden by the later root Directory.Packages.props import).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@(MIBCPackage) carries Version metadata (used by CopyMIBC); an item
->'%(Identity)' transform does NOT drop metadata, so list the five
packages explicitly without a version. Versions come from the central
eng/Packages.props entries.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Excludes opt-out subtrees, eng/common (Arcade-managed, not under CPM),
and src/FSharp.Build/Microsoft.FSharp.NetSdk.props (ships to user projects).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
These LSP/VS-integration projects pin older VS 17.x versions than the
central 18.x baseline; VersionOverride preserves their exact versions.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
MSBuild 18.10 pulls System.Security.Cryptography.Xml >= 10.0.9 transitively and
OpenTelemetry pulls Microsoft.Extensions.DependencyInjection >= 10.0.0; raise the
central pins to those floors so transitive pinning does not downgrade them.
Source-build keeps the live S.S.C.Xml via a non-source-build-gated override, and
FSharp.Compiler.LanguageServer (net8) keeps DI 8.0.0 via VersionOverride.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ion.Metadata

MSBuild 18.10 also pulls these dotnet/runtime packages >= 10.0.9 transitively; raise
their central pins to the same 10.0.9 floor (non-source-build only, source-build keeps
the live versions).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
VisualFSharp.slnx surfaced two more CPM issues:
- MIBC packages (added to every project by Directory.Build.targets) lacked a
  version in CPM-opt-out subtrees (setup/Swix) -> NU1015. Split the ItemGroup so
  opt-out projects carry @(MIBCPackage) Version metadata while CPM projects stay
  identity-only.
- The VS SDK (18.9.496, via Microsoft.CodeAnalysis.ExternalAccess.FSharp) pulls
  several VS packages higher than the declared 18.0.x pins; under transitive
  pinning these downgraded. Raised the editor group to 18.9.123 and pinned
  Shell.Design/Package.LanguageService.15.0 (18.9.493), Designer.Interfaces
  (18.9.438), Nullable (1.3.1) and LanguageServer.Protocol (17.13.9) to the
  versions already resolved transitively.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
NoWarn set in Directory.Packages.props is discarded by projects that reset NoWarn
in their body (e.g. tests set <NoWarn>3186</NoWarn>). Move the NU1507 suppression to
Directory.Build.targets, which is imported after project bodies, so it applies to
every CPM project.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The MSBuild 18.10 toolchain (fsc/fsi and FSharp.Build.UnitTests) pulls
System.Collections.Immutable / System.Reflection.Metadata / System.Security.Cryptography.Xml
transitively at >= 10.0.9, so the CPM transitive pin must meet that floor. Introduce
dedicated System*CentralVersion properties for the central list instead of overriding the
darc-flowed System*Version properties, which must stay authoritative for source-build and for
FSharp.Compiler.Service's shipped nuspec dependency metadata (FCS does not pull MSBuild). The
floor only raises when darc is below 10.0.9; once darc flows a higher version, darc wins.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…t subtrees

EndToEndBuildTests and other subtrees set ImportDirectoryPackagesProps=false and are not under
CPM, so the central list does not apply and the versionless test PackageReferences would restore
nothing silently. Add an inline-versioned Update ItemGroup guarded on ImportDirectoryPackagesProps=false,
sourced from the same XunitVersion/etc. properties those subtrees already define.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- Remove three now-dead 'PackageReference Update=Microsoft.VSSDK.BuildTools' lines whose only
  purpose was the Version metadata the CPM strip removed; transitive pinning supplies the version.
- Restore the Version attributes on the commented-out OpenTelemetry block the strip wrongly touched.
- Drop trailing whitespace left on a stripped PackageReference in FSharp.Editor.fsproj.
- Document why the LanguageServer.Protocol central pin is 17.13.9 and why MIBC identities are listed
  literally under CPM.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
- eng/Versions.props: group the two shell properties still on the package-group version above the
  'pinned to 18.9.x' comment so that comment sits only over the three literally pinned properties
  (value-preserving reorder).
- tests/AheadOfTime/Directory.Build.props: fold the opt-out property into the adjacent PropertyGroup
  to match every other opt-out file.
- FSharp.Compiler.LanguageServer.fsproj: note why the DI VersionOverride stays on 8.0.0.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
FSCoreProductVersion, MicrosoftVisualStudioInteropVersion,
MicrosoftVisualStudioImagingInterop140DesignTimeVersion, and the three
MicroBuild* setup versions had zero references repo-wide (grep-verified).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Manually-pinned, single-use package versions previously defined as
properties in eng/Versions.props solely to be referenced once by a
<PackageVersion> in eng/Packages.props are now inlined as literals at the
pin, removing the Versions.props<->Packages.props duality. Load-bearing
rationale comments move with them. Genuinely shared version groups
(VisualStudioEditorPackagesVersion, the System.* central floors, Xunit/
TestPlatform, FSharpCore*), darc/Maestro-flowed versions, and the
Arcade-read MicrosoftVSSDKBuildToolsVersion stay as properties.

Also drops the dead Dotnet.ProjInfo central pin (no remaining consumer).
Net: eng/Versions.props shrinks 202 -> 138 lines. Restore/build unchanged
(inlined values are byte-identical to MSBuild's prior resolution).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
With CentralPackageTransitivePinningEnabled, packages consumed only
transitively no longer need direct <PackageReference>s:
- FSharp.Build: System.Security.Cryptography.Xml (dead historic override),
  System.Memory, System.Runtime.CompilerServices.Unsafe
- FSharp.DependencyManager.Nuget: System.Reflection.Emit/Metadata/Unsafe
  (the ns2.0 plugin uses host-side System.Reflection, never emits IL)
- fsc.targets: net472 System.Memory/Unsafe ItemGroup
- FSharp.Compiler.Service.Tests: Newtonsoft.Json (redundant; transitive via
  FSharp.Test.Utilities and centrally pinned)

System.Security.Cryptography.Xml now has zero direct references repo-wide;
its central pin alone holds the secure version transitively.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…omment, extract test predicate

Round-1 of the cross-model compaction vote (unanimous 3/3 on each):
- Single-source the 10.0.9 dotnet/runtime transitive floor into
  $(SystemRuntimeCentralFloorVersion) (was 6 literal occurrences).
- Bind Microsoft.VisualStudio.Platform.VSEditor to the existing
  $(VisualStudioEditorPackagesVersion) group (removes a magic 18.9.123 literal).
- De-duplicate the NU1109 editor-pin rationale comment (keep it in eng/Packages.props).
- Extract the 4x-repeated test-runner name condition into $(_IsTestRunnerProject).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…policy comment

Round-2 of the cross-model compaction vote:
- Delete the dead `UnitTestType == 'xunit'` ItemGroup in Directory.Build.targets:
  nothing ever sets UnitTestType to 'xunit' (only 'none'), and xunit.v3.mtp-v2 is
  already added to every test-runner project by tests/Directory.Build.props. (3/3)
- Trim the inline-vs-property policy parenthetical in eng/Versions.props; the canonical
  statement already lives in the eng/Packages.props header. (2/3)

Contested proposals that FAILED the vote (kept as-is): folding XunitRunnerConsoleVersion
(genuine 3x use, coincidental value), removing per-file CPM opt-out comments, removing the
pre-existing commented OpenTelemetry block, removing the EndToEnd version fallbacks (proven
load-bearing in Arcade builds), hoisting VersionPrefix in the product-version block.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The xunit.v3.* family (assert/common/extensibility.core/mtp-v2/runner.console)
ships in lockstep; runner.console had a separate $(XunitRunnerConsoleVersion)
property duplicating $(XunitVersion) (both 3.2.2) with no active deviation.
Point the runner.console pin (and the EndToEnd opt-out override) at
$(XunitVersion) and delete the redundant property + its EndToEnd fallback.
Resolved version unchanged (3.2.2); restore + ./build.sh -c Release clean.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro
T-Gro requested a review from a team as a code owner July 24, 2026 09:21
@T-Gro T-Gro added the NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes label Jul 24, 2026
@T-Gro
T-Gro requested a review from abonie July 24, 2026 09:21
@github-actions

github-actions Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

⚠️ Release notes required, but author opted out

Warning

Author opted out of release notes, check is disabled for this pull request.
cc @dotnet/fsharp-team-msft

Source-build also builds live Microsoft.Build.Tasks.Core 18.10, which
pulls System.Security.Cryptography.Xml transitively at >= 10.0.9. The
floor was gated to non-source-build, so the central pin stayed at the
darc 10.0.8 and CPM transitive pinning raised NU1109 (downgrade
10.0.9 -> 10.0.8) in the Source-Build (Managed) jobs. Drop the gate so
the max(darc, 10.0.9) floor applies in every build mode. The darc-flowed
$(System*Version) properties are untouched, so FCS's shipped nuspec
metadata still uses the darc version.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed label Jul 24, 2026
T-Gro and others added 3 commits July 24, 2026 12:13
tests/FSharp.Test.Utilities/TestFramework.fs parses eng/Versions.props by
property name at module-init to locate csc/vbc/ilasm/ildasm in the NuGet
cache. The version-literal diet had inlined these into eng/Packages.props
and deleted the MicrosoftNetCompilersVersion / MicrosoftNETCoreILAsmVersion
/ MicrosoftNETCoreILDAsmVersion properties, so the assembly fixture threw
'Property not found in Versions.props' in its constructor and every test in
the assembly failed at 0ms (Linux/macOS test jobs). Keep them as properties
and have eng/Packages.props reference them, so there is still a single
source and no duplicate literal.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Arcade's VisualStudio.targets injects Microsoft.VSSDK.BuildTools as an
implicit PackageReference (IsImplicitlyDefined=true,
Version=$(MicrosoftVSSDKBuildToolsVersion)) into VSIX/pkgdef projects. Under
CPM an implicitly-defined reference must carry its own version and cannot
have a central PackageVersion, so the central entry raised NU1009 across
every Windows job that builds vsintegration (VisualFSharp.slnx). Remove the
central PackageVersion; Arcade versions it from the property we keep.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Fixes CS0433 (ambiguous S/IComponentModel) in FSharp.Editor.IntegrationTests.
Under transitive pinning it pulled Shell.Framework 18.x while ComponentModelHost
stayed at 17.x; the 17.x/18.x split made the type-forward ambiguous. Pin it to
the VS SDK 18.9.496 set so the types resolve to a single assembly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…rver

Fixes MSB3277 (StreamJsonRpc 2.25 vs 2.26 conflict). The override held 2.25.29
while the transitively-pinned Proxy used central 2.26.5; the two disagreed. Both
now use central 2.26.5 (identical Threading.Only >= 17.14.15 floor, so no NU1109).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added ⚠️ Affects-Build-Infra Tooling check: PR touches build infrastructure ⚠️ Affects-Restore Tooling check: PR touches NuGet packages or feeds labels Jul 26, 2026
@github-actions

Copy link
Copy Markdown
Contributor

🔍 Tooling Safety Check — Affects-Build-Infra, Affects-Restore
Affects-Build-Infra: adds Directory.Packages.props, Directory.Build.targets, modifies eng/Packages.props and multiple .fsproj files
Affects-Restore: introduces Central Package Management changing how all packages resolve

Generated by PR Tooling Safety Check · opus46 11.6M ·

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

Labels

⚠️ Affects-Build-Infra Tooling check: PR touches build infrastructure ⚠️ Affects-Restore Tooling check: PR touches NuGet packages or feeds AI-Tooling-Check-Bypassed Tooling check: non-fork PR, not diff-analyzed NO_RELEASE_NOTES Label for pull requests which signals, that user opted-out of providing release notes

Projects

Status: New

Development

Successfully merging this pull request may close these issues.

1 participant