关于 convert-to-cpm
用于将明确范围内的项目转换为 NuGet Central Package Management(CPM)的技能。它会审查包版本和项目结构,保留相关条件,并通过构建及包解析证据验证转换。
主要功能
- 01确定项目和 CPM 管理范围
- 02检查 packages.config 与现有 CPM
- 03审查包版本及引用
- 04在 Directory.Packages.props 中集中版本
- 05保留条件和元数据
- 06比较包解析结果与构建
适用场景
- 01将指定范围的项目转换为 CPM
- 02识别包版本冲突
- 03保留有条件的包引用
- 04验证转换后的包版本
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ dotnet/ skills --skill convert-to-cpm安装后在 Claude Code 中输入/convert-to-cpm确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/audit-complexities.mdbaseline-comparison.mddirectory-packages-props.mdmsbuild-property-handling.mdreport-template.mdvalidation-and-errors.md详细介绍
转换为 Central Package Management
在保留项目行为的同时,将包版本集中到 Directory.Packages.props 中,并生成便于审查的转换前后对比证据。
先选择模式
请在运行构建或更改文件之前完成此步骤。
- 防护模式——如果范围内的任何项目使用
packages.config,请停止。说明 CPM 要求使用PackageReference,并建议先迁移。不要创建或修改文件。 - 包维护模式——更新、对齐、升级或同步包的请求,仅授权修改这些包,不授权转换为 CPM。审查指定范围,确定所需版本,更新现有项目或共享版本声明,并从用于确定适用
global.json的目录还原/构建每个受影响的 CLI 目标。仅在版本或对齐策略不明确时询问。不要创建或修改Directory.Packages.props,不要为 CPM 移除版本,也不要生成转换产物。完成包维护后,再建议将 CPM 作为长期方案。 - 转换模式——仅当用户明确要求采用、启用或转换为 CPM 时使用。请遵循以下工作流。
如果范围不明确,请先询问一次。
默认执行计划
- 防护模式:执行最小范围的检测,然后回复并停止。
- 包维护模式:进行简要审查,仅在现有位置修改所请求的包版本,验证受影响的目标,然后建议采用 CPM。不要阅读转换参考资料,也不要进入转换工作流。
- 转换模式:将预检、基线、审查/修改、最终验证和报告工作合并处理,以避免多余轮次。仅当新的 CPM 专属证据要求有针对性的后续处理时,才重新执行某个阶段。
此计划是提高效率的默认做法,并非硬性限制。切勿为了节省轮次而遗漏范围内的项目、导入的 .props/.targets 文件、检测到的复杂情况、必要的验证或交付物。实际可行时,应合并完整工作。
输入
| 输入 | 必填 | 规则 |
|---|---|---|
| 范围 | 是 | 要检查或转换的项目、解决方案,或包含这些项目的目录 |
| 冲突策略 | 在包维护或存在冲突的转换中必填 | 如果用户已提供“使用最高版本”等策略,直接应用,无需再次询问,并记录其影响。否则,审查后停止,并在编辑前询问。 |
仅在需要时阅读参考资料
切勿预先加载所有参考资料。
| 条件 | 阅读 |
|---|---|
| 开始转换基线或生成包差异时 | baseline-comparison.md |
检测到冲突、条件引用、共享导入、安全问题或 VersionOverride 时 | audit-complexities.md |
放置方式不明确,或需要有条件的 PackageVersion/VersionOverride 时 | directory-packages-props.md |
| 包版本使用 MSBuild 属性时 | msbuild-property-handling.md |
| 转换后还原或构建失败时 | validation-and-errors.md |
| 编写最终报告时 | report-template.md |
转换工作流
1. 范围与前置检查
- 确定项目/解决方案范围。对于解决方案,列出其中的项目。对于目录,仅搜索该目录下的内容,并创建覆盖完整范围的明确目标集:使用每个适用的
.sln/.slnx,然后添加未被解决方案覆盖的每个项目。验证范围内的每个项目都已纳入,并避免对出现在多个目标中的项目重复操作。只有当目标重叠或存储库边界导致预期覆盖范围不明确时才提问;如果要求用户只选一个目标会遗漏范围内的项目,则绝不要这样提问。 - 将 CPM 管理范围与 CLI 目标分别确定。将共用一套中央版本策略的项目分组,并在每组的第一个共同祖先目录中放置一个
Directory.Packages.props,同时遵守现有最近文件边界。多个 CLI 目标可以共用一个 CPM 文件;独立的项目组可能需要单独的文件。 - 检查是否存在
packages.config;如果存在,则切换到 Guard 模式并停止。 - 检查范围及其祖先目录中的
Directory.Packages.props。如果 CPM 已完全启用,报告后停止。如果存在部分配置文件,则保留该文件,并且仅在其预期范围不明确时提问。 - 在已确定的范围内选择一个共同的制品目录,通常为各目标的第一个共同祖先目录。所有 binlog、包快照和报告都使用指向该目录的明确路径。
- 从解决方案/项目目录或其他能确定其适用
global.json的目录运行每个目标的 .NET 命令,不要从无关的父级工作区运行。 - 用户提供了范围时,不要检查无关项目或主机工具配置。
2. 捕获基线
阅读 baseline-comparison.md。对于每个目标,从该目标的命令目录确定一次当前使用的 SDK,并选择该版本对应的文档命令语法。如果 SDK 解析失败,或 SDK 无法处理所请求的解决方案格式,则停止并报告前置条件;除非用户要求,否则不要更改主机 SDK 或存储库的 SDK 策略。
然后使用一个命令批次执行以下操作:
- 清理、还原并生成每个明确目标。单个目标使用
baseline.binlog;多个目标则分别使用唯一的baseline-<target-key>.binlog。 - 为每个目标写入已解析的包,不要再次还原。单个目标使用
baseline-packages.json;多个目标则分别使用对应的baseline-packages-<target-key>.json。 - 保持常规命令输出简洁。必要时将完整输出保存到制品中;失败时只检查错误,绝不要将 binlog 当作文本读取。
编辑前完成所有基线构建。如果任何基线构建失败,则停止且不要修改文件,并保留已生成的所有制品。
3. 使用有针对性的检查清单进行审计
使用所有基线快照,并对范围内的项目、.props 和 .targets 文件进行一次有针对性的扫描。识别:
- 包 ID、解析后的版本和使用这些包的项目
- 版本冲突
- 基于 MSBuild 属性的版本及其定义
- 有条件的
PackageReference项 - 包含包引用的导入文件
- 现有的
VersionOverride用法
对于复杂范围,请在所有项目和导入文件中完成上述所有适用事项;不要在发现第一个冲突后就停止。
默认不要运行范围过大的 --outdated 或 --deprecated 扫描。编辑前,如果用户要求提供安全信息、必须核实已知公告,或冲突解决会使项目跨越某个主版本的包版本,请尝试运行限定范围的 --vulnerable --include-transitive 查询。记录简要发现、“未发现安全公告”,或无法运行检查的原因。如果因身份验证、包源或离线限制而无法进行高风险检查,请明确说明不确定性,并确认用户的处理策略,不要默默将其视为安全。作为 CPM 转换的一部分,不要升级到超出范围内现有最高版本的版本。
说明冲突及其影响。将主版本对齐明确归类为高风险,将次版本或补丁版本对齐归类为中等风险,无需额外进行在线扫描。如果用户已提供冲突处理策略,则继续操作。否则,询问尚未解决的决策,并在编辑前停止。
4. 创建 CPM 文件并更新引用
- 在计算出的管理范围内创建或更新每个必需的
Directory.Packages.props,并将ManagePackageVersionsCentrally设为true。 - 为每个包添加一个按字母顺序排序的
PackageVersion,并保留所需的目标框架条件。 - 仅从项目和导入文件中受管理的
PackageReference项移除Version。 - 保留条件、空白以及所有其他元数据,例如
PrivateAssets、IncludeAssets、ExcludeAssets、GeneratePathProperty和Aliases。 - 仅在所选策略要求时使用
VersionOverride。
对于 MSBuild 版本属性,请遵循 msbuild-property-handling.md。当用户要求内联时,请在同一修改批次中同时包含字面量 PackageVersion,并移除已废弃的属性定义。在最终验证前,分别确认:
- 范围内的项目、
.props或.targets文件中不再存在任何$(PropertyName)引用。 - 对于每个选定要移除的属性,不再存在
<PropertyName>...</PropertyName>定义。
不要依赖 $() 引用扫描来证明 XML 属性定义已被移除。
5. 验证并比较
使用 baseline-comparison.md,验证完成所有项目、共享文件和属性编辑后的最终磁盘状态。使用一批命令执行以下操作:
- 完成所有 CPM 编辑后,对每个显式目标执行清理、还原和生成。单个目标使用
after-cpm.binlog;多个目标则分别使用对应的after-cpm-<target-key>.binlog。 - 为每个目标写入已解析的包列表,不再还原。单个目标使用
after-cpm-packages.json;多个目标则分别使用对应的after-cpm-packages-<target-key>.json。 - 按项目生成简洁的变更/未变更对比,不要打印或重新读取完整 JSON 文件。
- 如果已解析的版本发生变化,且仓库提供了适用于受影响项目的常规、限定范围的测试命令,则使用
--no-build --no-restore运行并记录结果。如果测试需要大量设置、广泛的基础设施或用户批准,则建议提供准确的限定范围命令。仅转换而不改变版本时,无需自动运行测试。
如果还原或生成因 CPM 相关错误而失败,请阅读 validation-and-errors.md,只检查相关错误行,进行针对性修正,然后重新执行受影响的验证。如果是 SDK、身份验证、包源、文件锁、测试宿主或其他环境问题导致失败,请报告阻碍,不要更改机器配置或扩大调查范围。
如果生成成功后测试运行失败,只检查足以判断是否由 CPM 包解析导致失败的输出。只有证据明确表明是 CPM 缺陷时,才进行针对性修正;否则,记录失败和建议用户采取的操作,不要扩大调查范围去调试测试宿主、SDK、输出目录或依赖项复制问题。
6. 编写报告
现在阅读 report-template.md,不要提前阅读。在其他产物旁创建 convert-to-cpm.md。报告必须包含六个必需部分、每个显式目标和 CPM 管理范围、具体的冲突影响、整体包对比、风险级别、后续事项、产物用途,以及检查或修改过的每个共享 .props/.targets 文件的名称。最终回复中提及这些共享文件、风险级别,以及如何保留条件引用和目标框架。除非验证发现遗漏或证据不正确,否则验证后不要重写报告。
必需的转换产物
保留报告和每个目标的四个证据文件;它们不是临时文件。单个目标时,五项交付物为:
baseline.binlogafter-cpm.binlogbaseline-packages.jsonafter-cpm-packages.jsonconvert-to-cpm.md
多个目标时,将四个固定证据文件名替换为带唯一目标键的文件对,例如 baseline-api.binlog、after-cpm-api.binlog、baseline-packages-api.json 和 after-cpm-packages-api.json。保留一个汇总的 convert-to-cpm.md。
效率规则
- 在支持的情况下,批量执行相互独立的读取和编辑操作。
- 不要将完整生成日志和包 JSON 输出到对话中;仅返回简洁摘要和产物路径。
- 不要重复执行成功的命令,也不要重新读取成功的输出。
- 在转换模式下,不要执行包升级、广泛的过时/弃用扫描、重复测试或无关的仓库探索。上述单次条件性漏洞查询和测试运行属于高风险转换完整验证的一部分。包维护任务可以执行所要求的升级,以及解决升级问题所需的一次限定范围版本发现查询。
- 不要安装或移除 SDK、创建临时 SDK 选择器、更改 roll-forward 策略、调用 SDK 内部程序集、终止无关进程,或清理主机工具/临时基础设施。报告环境前置条件并停止。
验证
- 每个显式目标的基线构建和转换后构建均已成功,且所有目标的 binlog 均存在
- 每个受管理的
PackageReference均未设置Version,或有意使用VersionOverride - 每个受管理的包均具有正确的中央
PackageVersion - 条件和非版本元数据均已保留
- 转换前后的包对比中没有无法解释的变更
- 内联的版本属性均不再包含
$()引用,也没有过时的 XML 定义 - 报告以及每个目标的基线和转换后产物均存在