--- name: package-management description: Manage NuGet packages using Central Package Management (CPM) and dotnet CLI commands. Never edit XML directly - use dotnet add/remove/list commands. Use shared version variables for related packages. invocable: false --- # NuGet Package Management ## When to Use This Skill Use this skill when: - Adding, removing, or updating NuGet packages - Setting up Central Package Management (CPM) for a solution - Managing package versions across multiple projects - Troubleshooting package conflicts or restore issues --- ## Golden Rule: Never Edit XML Directly **Always use `dotnet` CLI commands to manage packages.** Never manually edit `.csproj` or `Directory.Packages.props` files. ```bash # DO: Use CLI commands dotnet add package Newtonsoft.Json dotnet remove package Newtonsoft.Json dotnet list package --outdated # DON'T: Edit XML directly # ``` **Why:** - CLI validates package exists and resolves correct version - Handles transitive dependencies correctly - Updates lock files if present - Avoids typos and malformed XML - Works correctly with CPM --- ## Central Package Management (CPM) CPM centralizes all package versions in one file, eliminating version conflicts across projects. ### Enable CPM Create `Directory.Packages.props` in solution root: ```xml true ``` ### Project Files with CPM Projects reference packages **without versions**: ```xml ``` ### Adding Packages with CPM ```bash # Adds to Directory.Packages.props AND project file dotnet add package Serilog.Sinks.Console # Result in Directory.Packages.props: # # Result in project file: # ``` --- ## Shared Version Variables Group related packages with shared version variables: ```xml true 1.5.59 1.5.59 9.0.0 1.11.0 2.9.2 ``` **Benefits:** - Update all Akka packages by changing one variable - Clear organization with labeled ItemGroups - Prevents version mismatches in related packages --- ## When NOT to Use CPM Central Package Management isn't always the right choice: ### Legacy Projects Migrating an existing large solution to CPM can introduce issues: - Existing version conflicts become visible all at once - Some packages may have intentional version differences - Migration requires touching many files simultaneously **Recommendation**: For legacy projects, migrate incrementally or stick with per-project versioning if it's working. ### Version Ranges CPM requires exact versions - it doesn't support version ranges: ```xml ``` If you need version ranges (rare, but some library scenarios require it), CPM won't work. ### Older .NET Versions CPM requires: - **.NET SDK 6.0.300+** or later - **NuGet 6.2+** or later - **Visual Studio 2022 17.2+** or later If you're targeting older SDK versions or have team members on older tooling, CPM may cause build failures. ### Multi-Repo Solutions If your solution spans multiple repositories that are built independently, CPM's single `Directory.Packages.props` won't help - each repo needs its own. --- ## CLI Command Reference ### Adding Packages ```bash # Add latest stable version dotnet add package Serilog # Add specific version dotnet add package Serilog --version 4.0.0 # Add prerelease dotnet add package Serilog --prerelease # Add to specific project dotnet add src/MyApp/MyApp.csproj package Serilog ``` ### Removing Packages ```bash # Remove from current project dotnet remove package Serilog # Remove from specific project dotnet remove src/MyApp/MyApp.csproj package Serilog ``` ### Listing Packages ```bash # List all packages in solution dotnet list package # Show outdated packages dotnet list package --outdated # Include transitive dependencies dotnet list package --include-transitive # Show vulnerable packages dotnet list package --vulnerable # Show deprecated packages dotnet list package --deprecated ``` ### Updating Packages ```bash # With CPM: Edit the version in Directory.Packages.props # Then restore to apply dotnet restore # Without CPM: Remove and add with new version dotnet remove package Serilog dotnet add package Serilog --version 4.1.0 # Or use dotnet-outdated tool (recommended) dotnet tool install --global dotnet-outdated-tool dotnet outdated --upgrade ``` ### Restore and Clean ```bash # Restore packages dotnet restore # Clear local cache (troubleshooting) dotnet nuget locals all --clear # Force restore (ignore cache) dotnet restore --force ``` --- ## Package Sources ### List Sources ```bash dotnet nuget list source ``` ### Add Private Feed ```bash # Add authenticated feed dotnet nuget add source https://pkgs.dev.azure.com/myorg/_packaging/myfeed/nuget/v3/index.json \ --name MyFeed \ --username az \ --password $PAT \ --store-password-in-clear-text ``` ### NuGet.config For solution-specific sources, create `NuGet.config`: ```xml ``` --- ## Common Patterns ### Development-Only Packages ```xml ``` ### Conditional Packages ```xml ``` ### Version Override (Escape Hatch) When you must override CPM for one project (rare): ```xml ``` **Warning**: This is detected by Slopwatch (see `dotnet/slopwatch` skill) as potential slop. --- ## Troubleshooting ### Version Conflicts ```bash # See full dependency tree dotnet list package --include-transitive # Find what's pulling in a specific package dotnet list package --include-transitive | grep -i "PackageName" ``` ### Restore Failures ```bash # Clear all caches dotnet nuget locals all --clear # Restore with detailed logging dotnet restore --verbosity detailed # Check for locked packages cat packages.lock.json ``` ### Lock Files For reproducible builds, use package lock files: ```xml true ``` Then commit `packages.lock.json` files. --- ## Anti-Patterns ### Don't: Edit XML Directly ```xml ``` ### Don't: Inline Versions with CPM ```xml ``` ### Don't: Mix Version Management ```xml ``` ### Don't: Forget Shared Variables ```xml ``` --- ## Quick Reference | Task | Command | |------|---------| | Add package | `dotnet add package ` | | Add specific version | `dotnet add package --version ` | | Remove package | `dotnet remove package ` | | List packages | `dotnet list package` | | Show outdated | `dotnet list package --outdated` | | Show vulnerable | `dotnet list package --vulnerable` | | Restore | `dotnet restore` | | Clear cache | `dotnet nuget locals all --clear` | --- ## Resources - **Central Package Management**: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management - **dotnet CLI Reference**: https://learn.microsoft.com/en-us/dotnet/core/tools/ - **NuGet.config Reference**: https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file