convert-to-cpm

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Convert to Central Package Management

转换为中央包管理

Migrate .NET projects from per-project package versioning to NuGet Central Package Management (CPM). CPM centralizes all package versions into a single
Directory.Packages.props
file, making version governance and upgrades easier across multi-project repositories.
将.NET项目从每个项目单独管理包版本的模式迁移到NuGet中央包管理(CPM)。CPM将所有包版本集中到单个
Directory.Packages.props
文件中,让多项目仓库的版本管控和升级操作更简便。

When to Use

适用场景

  • The user wants to adopt Central Package Management for a .NET repository, solution, or project
  • Package versions are scattered across many
    .csproj
    ,
    .fsproj
    , or
    .vbproj
    files and the user wants a single source of truth
  • The user mentions
    Directory.Packages.props
    , CPM, or centralizing NuGet versions
  • The user wants to update, bump, upgrade, align, or sync a NuGet package version across multiple projects -- CPM is the recommended approach for managing shared package versions, so suggest converting to CPM as part of the update if the projects use
    PackageReference
    and CPM is not already enabled
  • Package versions are out of sync, conflicting, or mismatched across projects and the user wants to resolve or unify them
  • 用户希望为.NET仓库、解决方案或项目采用中央包管理
  • 包版本分散在多个
    .csproj
    .fsproj
    .vbproj
    文件中,用户希望拥有单一的版本数据源
  • 用户提及
    Directory.Packages.props
    、CPM或集中管理NuGet版本
  • 用户想要在多个项目间更新、升级、统一或同步NuGet包版本——CPM是管理共享包版本的推荐方案,因此如果项目使用
    PackageReference
    且尚未启用CPM,建议在更新过程中转换为CPM
  • 跨项目的包版本不同步、存在冲突或不匹配,用户希望解决或统一这些问题

When Not to Use

不适用场景

  • The repository already has CPM fully enabled for all in-scope projects
  • The user is working with
    packages.config
    -based projects (must first migrate to
    PackageReference
    )
  • The user wants to manage versions via a custom MSBuild property file without using CPM
  • 仓库已针对所有相关项目完全启用CPM
  • 用户正在处理基于
    packages.config
    的项目(必须先迁移到
    PackageReference
  • 用户希望通过自定义MSBuild属性文件管理版本,而不使用CPM

Inputs

输入项

InputRequiredDescription
ScopeYesA project file, solution file, or directory containing .NET projects to convert
Version conflict strategyNoHow to resolve cases where the same package has different versions across projects. When conflicts are detected, do not assume a default strategy -- ask the user which strategy to use or explicitly confirm a proposed strategy before proceeding.
输入项是否必填描述
范围要转换的.NET项目文件、解决方案文件或包含项目的目录
版本冲突策略如何解决同一包在不同项目中版本不同的情况。检测到冲突时,不要默认采用某种策略——需询问用户使用哪种策略,或在执行前明确确认拟采用的策略。

Workflow

工作流程

Step 1: Determine scope

步骤1:确定范围

  • Single project: User specifies a
    .csproj
    ,
    .fsproj
    , or
    .vbproj
    .
  • Solution: User specifies a
    .sln
    or
    .slnx
    . List projects with
    dotnet sln list
    .
  • Repository/directory: No specific file given. Find all project files recursively from the first common ancestor directory of all .NET projects in scope.
If the scope is unclear, ask the user.
Guard: Check for packages.config projects. Before proceeding, check whether any project in scope uses
packages.config
instead of
PackageReference
. Look for
packages.config
files alongside project files. If any
packages.config
usage is detected, stop and do not proceed with the conversion. Inform the user that CPM requires projects with
PackageReference
format and that they must first migrate from
packages.config
to
PackageReference
(e.g., using Visual Studio's built-in migration or the
dotnet migrate
tooling). This skill cannot perform that migration.
  • 单个项目:用户指定
    .csproj
    .fsproj
    .vbproj
    文件。
  • 解决方案:用户指定
    .sln
    .slnx
    文件。使用
    dotnet sln list
    列出项目。
  • 仓库/目录:未指定具体文件。从所有相关.NET项目的第一个共同父目录开始,递归查找所有项目文件。
如果范围不明确,请询问用户。
防护检查:检测packages.config项目。在执行转换前,检查范围内是否有项目使用
packages.config
而非
PackageReference
。在项目文件旁查找
packages.config
文件。如果检测到任何
packages.config
的使用,立即停止转换操作。告知用户CPM要求项目使用
PackageReference
格式,必须先从
packages.config
迁移到
PackageReference
(例如使用Visual Studio内置的迁移工具或
dotnet migrate
工具)。本技能无法执行该迁移操作。

Step 2: Establish baseline build

步骤2:建立基线构建

Before making any changes, verify the scope builds successfully and capture a baseline binlog and package list. Run
dotnet clean
, then
dotnet build -bl:baseline.binlog
, then
dotnet package list --format json > baseline-packages.json
. Read baseline-comparison.md for the full procedure and fallback options. If the baseline build fails, stop and inform the user -- the scope must build cleanly before conversion. Do not delete
baseline.binlog
or
baseline-packages.json
-- they are needed for the post-conversion comparison and report.
在进行任何更改前,验证范围内的项目可成功构建,并捕获基线binlog和包列表。执行
dotnet clean
,然后执行
dotnet build -bl:baseline.binlog
,再执行
dotnet package list --format json > baseline-packages.json
。查阅baseline-comparison.md获取完整流程和备选方案。如果基线构建失败,停止操作并告知用户——转换前范围内的项目必须能正常构建。不要删除
baseline.binlog
baseline-packages.json
——它们用于转换后的对比和报告。

Step 3: Check for existing CPM

步骤3:检查现有CPM

Search for any existing
Directory.Packages.props
in scope or ancestor directories. If CPM is already fully enabled, inform the user and stop. If a
Directory.Packages.props
exists without CPM enabled, ask whether to add the property to the existing file or create a new one.
在范围或父目录中搜索是否存在
Directory.Packages.props
文件。如果已完全启用CPM,告知用户并停止操作。如果存在
Directory.Packages.props
但未启用CPM,询问用户是向现有文件添加属性还是创建新文件。

Step 4: Audit package references

步骤4:审计包引用

Run
dotnet package list --format json
to get the resolved package references across all in-scope projects. Also scan
<Import>
elements to discover shared
.props
/
.targets
files containing package references.
Check for complexities: version conflicts, MSBuild property-based versions, conditional references, security advisories, and existing
VersionOverride
usage. Read audit-complexities.md for the full checklist.
Present audit results to the user before proceeding, including:
  • A table of each package, its version(s), and which projects use it
  • Any version conflicts, security advisories, or complexities requiring decisions
When version conflicts exist, present each one individually with the affected projects, the distinct versions found, and the resolution options (align to highest, use
VersionOverride
, etc.) with their trade-offs. Do not upgrade any package beyond the highest version already in use across the scope -- this avoids introducing version incompatibilities or breaking changes that are unrelated to the CPM conversion itself. Note any known security advisories or other upgrade opportunities as follow-up items for the user to address after the conversion is complete. Ask the user to decide on each conflict before proceeding. Read audit-complexities.md - Same package with different versions for the resolution workflow and presentation format.
执行
dotnet package list --format json
获取所有相关项目中已解析的包引用。同时扫描
<Import>
元素,发现包含包引用的共享
.props
/
.targets
文件。
检查复杂情况:版本冲突、基于MSBuild属性的版本、条件引用、安全公告以及已有的
VersionOverride
使用情况。查阅audit-complexities.md获取完整检查清单。
在执行下一步前向用户展示审计结果,包括:
  • 每个包、其版本及使用该包的项目的表格
  • 任何需要决策的版本冲突、安全公告或复杂情况
当存在版本冲突时,逐个展示每个冲突,包括受影响的项目、发现的不同版本,以及解决方案(对齐到最高版本、使用
VersionOverride
等)及其利弊。不要将任何包升级到超出范围内已使用的最高版本——这可避免引入与CPM转换无关的版本不兼容或破坏性变更。将任何已知的安全公告或其他升级机会列为后续事项,供用户在转换完成后处理。请用户在执行下一步前决定每个冲突的解决方案。查阅audit-complexities.md - Same package with different versions获取解决流程和展示格式。

Step 5: Create or update Directory.Packages.props

步骤5:创建或更新Directory.Packages.props

Create the file with
dotnet new packagesprops
(.NET 8+) or manually. Add a
<PackageVersion>
entry for each unique package sorted alphabetically. For conditional versions or
VersionOverride
patterns, read directory-packages-props.md.
使用
dotnet new packagesprops
(.NET 8+)或手动创建文件。按字母顺序为每个唯一包添加
<PackageVersion>
条目。对于条件版本或
VersionOverride
模式,查阅directory-packages-props.md

Step 6: Update project files

步骤6:更新项目文件

Remove the
Version
attribute from every
<PackageReference>
that now has a corresponding
<PackageVersion>
. Also update any shared
.props
/
.targets
files identified in step 4.
  • Preserve all other attributes (
    PrivateAssets
    ,
    IncludeAssets
    ,
    ExcludeAssets
    ,
    GeneratePathProperty
    ,
    Aliases
    )
  • Preserve conditional
    <ItemGroup>
    elements -- only remove the
    Version
    attribute within them
  • Retain each file's existing indentation style (spaces vs. tabs, indentation depth) and blank lines -- do not reformat or reorganize unchanged lines
  • Use
    VersionOverride
    (with user confirmation) when a project needs a different version than the central one
从每个
<PackageReference>
中移除
Version
属性,前提是该包已在
Directory.Packages.props
中有对应的
<PackageVersion>
条目。同时更新步骤4中识别的共享
.props
/
.targets
文件。
  • 保留所有其他属性(
    PrivateAssets
    IncludeAssets
    ExcludeAssets
    GeneratePathProperty
    Aliases
  • 保留条件
    <ItemGroup>
    元素——仅移除其中的
    Version
    属性
  • 保留每个文件现有的缩进风格(空格或制表符、缩进深度)和空行——不要重新格式化或整理未更改的行
  • 当项目需要与中央版本不同的版本时,使用
    VersionOverride
    (需用户确认)

Step 7: Handle MSBuild version properties

步骤7:处理MSBuild版本属性

For
PackageReference
items that used MSBuild properties for versions, determine whether to inline the resolved value or keep the property reference in
Directory.Packages.props
. After validation succeeds in step 8, remove inlined version properties from
Directory.Build.props
or other files, verifying they have no remaining references. Read msbuild-property-handling.md for the decision workflow, import order requirements, and cleanup procedure.
对于使用MSBuild属性指定版本的
PackageReference
项,决定是内联已解析的值还是在
Directory.Packages.props
中保留属性引用。在步骤8验证成功后,从
Directory.Build.props
或其他文件中移除内联的版本属性,验证它们没有剩余引用。查阅msbuild-property-handling.md获取决策流程、导入顺序要求和清理步骤。

Step 8: Restore and validate

步骤8:还原与验证

Run a clean restore and build, capturing a post-conversion binlog and package list. Run
dotnet clean
, then
dotnet build -bl:after-cpm.binlog
, then
dotnet package list --format json > after-cpm-packages.json
. Read baseline-comparison.md for the full procedure. If errors occur, read validation-and-errors.md for NuGet error codes and multi-TFM guidance.
Do not delete or clean up any artifacts (
baseline.binlog
,
after-cpm.binlog
,
baseline-packages.json
,
after-cpm-packages.json
). These files must be preserved for the user to inspect after the conversion. They are deliverables, not temporary files.
执行清理还原和构建,捕获转换后的binlog和包列表。执行
dotnet clean
,然后执行
dotnet build -bl:after-cpm.binlog
,再执行
dotnet package list --format json > after-cpm-packages.json
。查阅baseline-comparison.md获取完整流程。如果出现错误,查阅validation-and-errors.md获取NuGet错误代码和多TFM指南。
不要删除或清理任何生成文件
baseline.binlog
after-cpm.binlog
baseline-packages.json
after-cpm-packages.json
)。这些文件必须保留,供用户在转换后检查。它们是交付成果,而非临时文件。

Step 9: Post-conversion report

步骤9:转换后报告

You must create a
convert-to-cpm.md
file
alongside the binlog and JSON artifacts. Do not skip this step or substitute inline chat output for the file -- the user needs a persistent, shareable document. This file should be self-contained and shareable -- suitable for a pull request description, a team review, or a record of what was done. Structure the report with the following sections:
必须创建
convert-to-cpm.md
文件
,与binlog和JSON文件放在一起。不要跳过此步骤或用即时聊天输出替代该文件——用户需要一个持久、可共享的文档。该文件应独立完整且可共享——适合用作拉取请求描述、团队评审文档或操作记录。报告应包含以下部分:

Section 1: Conversion overview

第1节:转换概述

Summarize what was converted: the scope (project, solution, or repository), number of projects converted, total packages centralized, any projects or packages that were skipped, and any MSBuild properties that were inlined or removed. This gives the reader immediate context.
总结转换内容:范围(项目、解决方案或仓库)、转换的项目数量、集中管理的包总数、任何跳过的项目或包,以及任何内联或移除的MSBuild属性。这能让读者快速了解背景信息。

Section 2: Version conflict resolutions

第2节:版本冲突解决方案

If any version conflicts were encountered, list each one with:
  • The package name and all versions that were found across projects
  • Which projects used each version
  • What the user decided (aligned to highest, used
    VersionOverride
    , etc.)
  • The practical impact: which projects now resolve a different version than before, and which are unchanged
If no conflicts were found, state that all packages had consistent versions across projects -- this is a positive signal worth noting.
如果遇到任何版本冲突,逐个列出每个冲突,包括:
  • 包名称及在各项目中发现的所有版本
  • 每个版本对应的使用项目
  • 用户的决策(对齐到最高版本、使用
    VersionOverride
    等)
  • 实际影响:哪些项目现在解析的版本与之前不同,哪些项目未变更
如果未发现冲突,说明所有项目的包版本一致——这是值得注意的积极信号。

Section 3: Package comparison -- baseline vs. result

第3节:包对比——基线与结果

Compare
baseline-packages.json
and
after-cpm-packages.json
per project. See baseline-comparison.md for the comparison procedure. Present two tables:
  • Changes table: Packages where the resolved version changed, a
    VersionOverride
    was introduced, or a package was added/removed. Include a status column explaining what changed and why (e.g., "VersionOverride -- project retains pinned version", "Aligned to highest version").
  • Unchanged table: All other packages, confirming they resolve identically to baseline.
If there are no changes at all, state that the conversion is fully version-neutral -- this is the ideal outcome and provides reassurance.
按项目对比
baseline-packages.json
after-cpm-packages.json
。查阅baseline-comparison.md获取对比流程。展示两个表格:
  • 变更表格:已解析版本变更、引入
    VersionOverride
    或包增删的情况。包含状态列说明变更内容及原因(例如:"VersionOverride——项目保留固定版本"、"对齐到最高版本")。
  • 未变更表格:所有其他包,确认它们的解析结果与基线一致。
如果完全没有变更,说明转换完全不影响版本——这是理想结果,能让用户放心。

Section 4: Risk assessment

第4节:风险评估

Provide a clear confidence statement:
  • [Low risk] -- Conversion is version-neutral; all packages resolve to the same versions as baseline. The build and restore succeeded. Recommend running
    dotnet test
    as a final check.
  • [Moderate risk] -- Some packages changed versions (e.g., minor/patch alignment). List the affected packages and projects. Recommend reviewing the changes table and running
    dotnet test
    to verify no regressions.
  • [High risk] -- Major version changes were applied, or packages were added/removed unexpectedly. Recommend careful review, running
    dotnet test
    , and comparing binlogs before merging.
Call out any specific warnings:
VersionOverride
usage that partially undermines centralization, or MSBuild property removal that could affect other build logic.
提供明确的信心声明:
  • [低风险]——转换不影响版本;所有包的解析版本与基线一致。构建和还原成功。建议执行
    dotnet test
    作为最终检查。
  • [中等风险]——部分包版本变更(例如:次要/补丁版本对齐)。列出受影响的包和项目。建议查看变更表格并执行
    dotnet test
    验证是否存在回归问题。
  • [高风险]——应用了主版本变更,或意外增删了包。建议仔细评审、执行
    dotnet test
    并对比binlog后再合并。
指出任何特定警告:
VersionOverride
的使用可能部分削弱集中管理,或MSBuild属性的移除可能影响其他构建逻辑。

Section 5: Follow-up items

第5节:后续事项

List any items identified during the conversion that the user should address separately after the CPM conversion is complete. These are intentionally out of scope for the conversion itself but important for the user to act on. Common follow-up items include:
  • Security advisories: If any package versions are known to have security vulnerabilities (detected via
    dotnet package list --vulnerable
    or noted during the audit), list each advisory with the package name, current version, affected projects, and the minimum patched version. These upgrades are out of scope for the CPM conversion to avoid introducing version incompatibilities or breaking changes.
  • Deprecated packages: If any packages are deprecated, note the recommended replacement.
  • Version alignment opportunities: If
    VersionOverride
    was used to preserve differing versions, note that the user may want to align these in the future once the affected projects can be validated against the central version.
  • Test validation: Recommend running
    dotnet test
    to validate runtime behavior beyond build success, especially if any version conflicts were resolved by aligning to the highest version.
Present follow-up items as a numbered checklist so the user can track them.
列出转换过程中发现的、用户应在CPM转换完成后单独处理的事项。这些事项不属于转换范围,但对用户很重要。常见后续事项包括:
  • 安全公告:如果任何包版本存在已知安全漏洞(通过
    dotnet package list --vulnerable
    检测或审计时发现),列出每个公告的包名称、当前版本、受影响项目及最低修复版本。这些升级不属于CPM转换范围,以避免引入版本不兼容或破坏性变更。
  • 已弃用包:如果任何包已弃用,注明推荐的替代包。
  • 版本对齐机会:如果使用
    VersionOverride
    保留了不同版本,注明用户未来可在受影响项目验证兼容中央版本后对齐这些版本。
  • 测试验证:建议执行
    dotnet test
    验证构建成功之外的运行时行为,尤其是通过对齐到最高版本解决版本冲突的情况。
将后续事项整理为编号清单,方便用户跟踪。

Section 6: Artifacts and how to use them

第6节:生成文件及使用方法

List the artifacts produced during conversion and explain how to use them:
  • baseline.binlog
    and
    after-cpm.binlog
    -- MSBuild binary logs captured before and after conversion. These are available for manual validation and troubleshooting if needed.
  • baseline-packages.json
    and
    after-cpm-packages.json
    -- Machine-readable snapshots of resolved package versions per project, used to produce the comparison tables above.
  • convert-to-cpm.md
    -- This report file, suitable for use as a pull request description or team review artifact.
Recommend the user run
dotnet test
to validate runtime behavior beyond build success. If any version conflicts were resolved by aligning to the highest version, recommend reviewing the release notes for the affected packages.
列出转换过程中生成的文件并说明使用方法:
  • baseline.binlog
    after-cpm.binlog
    ——转换前后捕获的MSBuild二进制日志。可用于手动验证和故障排查。
  • baseline-packages.json
    after-cpm-packages.json
    ——每个项目已解析包版本的机器可读快照,用于生成上述对比表格。
  • convert-to-cpm.md
    ——本报告文件,适合用作拉取请求描述或团队评审文档。
建议用户执行
dotnet test
验证构建成功之外的运行时行为。如果通过对齐到最高版本解决了版本冲突,建议查看受影响包的发行说明。

Validation

验证清单

  • Baseline build succeeded before any changes were made
  • Directory.Packages.props
    exists with
    ManagePackageVersionsCentrally
    set to
    true
  • Every in-scope
    PackageReference
    either has no
    Version
    attribute or uses
    VersionOverride
  • Every referenced package has a corresponding
    PackageVersion
    entry
  • dotnet restore
    and
    dotnet build
    complete without errors from a clean state
  • Package list comparison shows no unexpected version changes
  • No orphaned version properties remain (unless intentionally kept)
  • 基线构建在任何更改前已成功完成
  • 存在
    Directory.Packages.props
    ManagePackageVersionsCentrally
    设置为
    true
  • 所有相关的
    PackageReference
    要么没有
    Version
    属性,要么使用
    VersionOverride
  • 每个引用的包都有对应的
    PackageVersion
    条目
  • 从干净状态执行
    dotnet restore
    dotnet build
    无错误
  • 包列表对比显示无意外版本变更
  • 无孤立的版本属性残留(除非有意保留)

More Info

更多信息