Skip to content

Implement Central Package Management with Directory.Packages.props and Transitive Pinning - #1084

Merged
glennawatson merged 5 commits into
mainfrom
copilot/fix-1083
Sep 4, 2025
Merged

glennawatson merged 5 commits into
mainfrom
copilot/fix-1083

Conversation

Copilot AI commented Sep 4, 2025

Copy link
Copy Markdown
Contributor

This PR implements NuGet's Central Package Management (CPM) feature for the Akavache repository, centralizing all package version management in a single Directory.Packages.props file located in the /src folder.

What Changed

Created src/Directory.Packages.props with:

  • Required <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> property to enable CPM
  • NEW: <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled> for predictable builds by locking transitive dependency versions
  • Smart package organization using version group properties for related packages:
    • MicrosoftExtensionsVersion (9.0.8): System.Text.Json, Microsoft.Extensions.* packages
    • SqlitePclRawVersion (2.1.11): All SQLitePCLRaw.* packages
    • SqliteNetVersion (1.9.172): sqlite-net packages
    • SplatVersion (16.1.1): Splat packages
    • ReactiveUIVersion (20.4.1): ReactiveUI packages

Updated 15 project files to remove Version attributes from all <PackageReference> elements, as versions are now resolved centrally.

Preserved all existing conditional logic including:

  • Test-specific packages (using IsTestProject conditions)
  • SourceLink packages (using SourceLinkEnabled conditions)
  • Windows-specific packages (using TargetFramework conditions for MAUI)

Benefits

  • Single source of truth for all package versions across 32+ unique packages
  • Eliminates version conflicts - impossible to have different versions of the same package
  • Predictable builds - transitive pinning prevents surprise dependency updates that could break builds
  • Easier maintenance - update package versions in one centralized location
  • Package grouping - related packages managed together with shared version properties
  • Better security - easier to audit and update packages for security fixes
  • No breaking changes - all existing build processes and conditional logic preserved

Technical Notes

  • Replaced floating version NUnit3TestAdapter "5.*" with explicit "5.1.0" as CPM doesn't support floating versions
  • All package references now show "versionCentrallyManaged": true in project.assets.json
  • Transitive dependencies are now pinned to specific versions for completely deterministic builds
  • Tested successfully across core libraries, test projects, benchmark projects, and sample applications
  • MSBuild property substitution working correctly for version groups

Fixes #1083.

Central Package Management (CPM) Explained

What is Central Package Management?
Central Package Management is a NuGet feature that allows you to manage all package versions across your entire solution from a single file (Directory.Packages.props) instead of scattered across individual project files. Think of it like having one master list of software dependencies instead of each project maintaining its own separate list.

Key Properties in Directory.Packages.props

Core CPM Settings

<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>

This enables CPM for the entire solution. When true, all projects must get their package versions from this central file instead of specifying versions in individual project files.

<CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled>

NEW: This enables "transitive pinning" - it locks down the versions of indirect dependencies (packages that your direct dependencies depend on). Without this, NuGet might automatically upgrade transitive dependencies, potentially causing unexpected issues. With pinning enabled, you get completely predictable builds.

Version Groups (Smart Organization)

<MicrosoftExtensionsVersion>9.0.8</MicrosoftExtensionsVersion>
<SqlitePclRawVersion>2.1.11</SqlitePclRawVersion>

These create reusable version variables for related packages. Instead of repeating "9.0.8" for every Microsoft.Extensions.* package, we define it once and reference it as $(MicrosoftExtensionsVersion). This ensures related packages always stay in sync.

Package Definitions

<PackageVersion Include="System.Text.Json" Version="$(MicrosoftExtensionsVersion)" />

This defines that any project referencing "System.Text.Json" will get version 9.0.8 (via the variable). Projects just specify <PackageReference Include="System.Text.Json" /> without a version.

Conditional Groups

<ItemGroup Condition="'$(IsTestProject)' == 'true'">

These apply packages only to specific types of projects (test projects, Windows-only, etc.), keeping dependencies organized and preventing unnecessary packages in production code.

Benefits for Akavache

  • No version conflicts: Impossible to accidentally use different versions of the same package across projects
  • Single source of truth: Update a package version once, it applies everywhere
  • Predictable builds: Transitive pinning prevents surprise dependency updates
  • Easier maintenance: Clear organization of 32+ packages in logical groups
  • Better security: Easier to audit and update packages for security fixes

Co-authored-by: glennawatson <5834289+glennawatson@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement Central Package Management in the Repository Implement Central Package Management with Directory.Packages.props Sep 4, 2025
Copilot AI requested a review from glennawatson September 4, 2025 15:44
@glennawatson

Copy link
Copy Markdown
Contributor

@copilot reanalyse the commit with my update, explain to a non-experienced user what the different properties in Directory.Packages.props is (including the now added transitive pinning) and what central package management is, so people looking at this PR can understand it.

Copilot AI changed the title Implement Central Package Management with Directory.Packages.props Implement Central Package Management with Directory.Packages.props and Transitive Pinning Sep 4, 2025
@reactiveui reactiveui deleted a comment from Copilot AI Sep 4, 2025
@glennawatson
glennawatson marked this pull request as ready for review September 4, 2025 16:11
@glennawatson
glennawatson merged commit de62c67 into main Sep 4, 2025
1 check passed
@glennawatson
glennawatson deleted the copilot/fix-1083 branch September 4, 2025 16:25
@github-actions

Copy link
Copy Markdown

This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Sep 19, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Central Package Management in the Repository

2 participants