Skip to content

Enable Central Package Management with transitive pinning - #20084

Merged
T-Gro merged 27 commits into
mainfrom
t-gro-enable-cpm-transitive-pinning
Aug 4, 2026
Merged

Enable Central Package Management with transitive pinning#20084
T-Gro merged 27 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 ·

@github-project-automation github-project-automation Bot moved this from New to In Progress in F# Compiler and Tooling Jul 28, 2026
@T-Gro
T-Gro enabled auto-merge (squash) August 3, 2026 18:34
T-Gro and others added 3 commits August 3, 2026 20:52
Resolved eng/Versions.props: kept the diet's CentralVersion/floor machinery and
restructured tool-version block; took main's MicrosoftTestPlatformVersion bump
17.14.1 -> 18.0.1 and its net472 facade override properties (SystemNetHttp /
SystemTextRegularExpressions). fsproj/props union-merged (built-in git union
driver restored — a stale global merge.union.driver had been silently dropping
main's additions).

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
PR #20058 added per-project package overrides to work around the LACK of
Central Package Management. Now that CPM + transitive pinning is enabled here,
those overrides are redundant AND invalid (a PackageReference under CPM cannot
carry Version=, so they trip NU1008). This removes/consolidates them:

- fsc/fsi/FSharp.Build.UnitTests: drop the 3 identical netcore-only
  System.Security.Cryptography.Xml overrides. It is centrally pinned
  (10.0.10) and transitive pinning now raises the Microsoft.Build.Tasks.Core
  transitive on netcore automatically (verified via restore); net472 is
  untouched (crypto.xml not in its graph -> no ValueTuple conflict).
- LanguageServer: drop the per-project MessagePack 2.5.302 override; pin it
  centrally instead so transitive pinning patches it wherever StreamJsonRpc is
  used (LanguageServer AND the CLASP.Framework.Proxy), not just one project.
- Test.Utilities: keep the net472-only System.Net.Http/System.Text.RegularExpressions
  facade overrides but as local VersionOverride (no global eng/Versions.props
  properties), keeping the deviation minimal and scoped.

Also resolves union-merge duplicate PackageReference blocks introduced by the
merge from main in Microsoft.FSharp.Compiler, LanguageServer, and Test.Utilities.

Verified by clean bootstrap ./build.sh -c Debug (0 warnings, 0 errors) and by
inspecting restored versions: crypto.xml 10.0.10 (fsc), MessagePack 2.5.302
(LanguageServer + Proxy), StreamJsonRpc 2.26.5.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Resolve union-merge duplicates in vsintegration fsprojs and
Directory.Build.targets by keeping CPM-style refs (no inline Version)
and renaming the ExternalAccess package/property to
Microsoft.VisualStudio.LanguageServices.ExternalAccess
(MicrosoftVisualStudioLanguageServicesExternalAccessVersion).
Central pin in eng/Packages.props renamed accordingly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@T-Gro
T-Gro merged commit 36ce348 into main Aug 4, 2026
49 checks passed
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
…30-4e71-bcc3-2d3f59911b20

Resolve conflict from Central Package Management migration (#20084): keep the single CPM-compliant Microsoft.DotNet.NuGetRepack.Tasks PackageReference (no Version, PrivateAssets=all) and retain the Arcade 10 NuGetRepack UsingTask workaround needed by the downgraded Arcade SDK.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
…#19993) into darc-main-bd030f95

Resolve eng/Versions.props conflict by adopting origin/main's Central Package Management structure (VS package versions live in eng/Packages.props). Bump the four VS pins Roslyn 5.11.0 requires higher than main's 5.10.0 baseline: Microsoft.VisualStudio.Threading 18.7.23, Microsoft.VisualStudio.RpcContracts 18.9.918, Microsoft.ServiceHub.Framework 4.10.147, StreamJsonRpc 2.26.10, and raise the shared editor pin VisualStudioEditorPackagesVersion to 18.9.179 (Roslyn 5.11.0 pulls the VS editor packages transitively at 18.9.179 -> NU1109 otherwise). Take origin/main's CPM form of Framework.Proxy.csproj (drop redundant Version-bearing PackageReferences superseded by central pins).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
The merge of the arcade update with the Central Package Management PR (#20084)
left duplicated PackageReference entries in the runtime-dependencies ItemGroup,
including an unterminated <PackageReference> tag that caused MSB4025
(project could not be loaded), failing every CI build job. Remove the stale
versioned entries, keeping only the versionless CPM-style references.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
T-Gro pushed a commit that referenced this pull request Aug 4, 2026
…M merge

The merge that pulled the Central Package Management change (#20084) into this
release/dev18.0-based branch left, in 12 project files, a duplicated block of the
old versioned PackageReference entries above the new versionless CPM entries.
NuGet restore failed with NU1504 (Duplicate 'PackageReference' items) across
FSharp.Test.Utilities and the vsintegration projects, breaking every CI job.
FSharpSuite.Tests.fsproj additionally had a duplicate <OutputType>.

Restore all affected project files to their origin/main (CPM baseline) state,
which drops exactly the leftover duplicates and nothing else.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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

Archived in project

Development

Successfully merging this pull request may close these issues.

2 participants