关于 platform-manifest-generate
用于从本地源文件、Salesforce 组织或指定组件清单生成 Salesforce 元数据清单的技能,面向准备部署或删除操作的开发者。它生成 package.xml 或破坏性变更清单,并将后续部署交给其他技能处理。
主要功能
- 01从本地源目录生成清单
- 02根据指定组件生成清单
- 03通过组织元数据生成清单
- 04生成破坏性变更清单
- 05支持 package.xml 与删除清单组合
适用场景
- 01为本地元数据准备 package.xml
- 02列出指定组件以供部署
- 03从组织中提取元数据清单
- 04为元数据删除准备破坏性变更文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ forcedotcom/ sf-skills --skill platform-manifest-generate安装后在 Claude Code 中输入/platform-manifest-generate确认已加载。
附带文件references/wildcard-allowlist.md
详细介绍
platform-manifest-generate
根据本地源、组织或明确的组件列表生成 Salesforce 元数据清单——package.xml(或其中一种 destructive 变体)。此技能仅用于编写清单文件。文件生成后,交由 platform-metadata-deploy 或 platform-destructive-deploy 处理。
工具限制
只能使用 Bash 工具运行 sf project generate manifest,手动编写的后备路径则使用 Write 工具。不要使用 MCP 工具。
此技能负责的任务
在工作涉及以下任一情况时,使用 platform-manifest-generate:
- 从源目录(例如
force-app/main/default/classes/)生成package.xml - 根据明确的组件列表生成清单(例如
AccountService、ContactSelector、Account) - 使用
--from-org通过检查组织来生成清单 - 为删除操作生成
destructiveChanges.xml、destructiveChangesPre.xml或destructiveChangesPost.xml - 一次操作同时生成
package.xml和 destructive 清单
以下情况应交由其他技能处理:
- 执行部署本身 →
platform-metadata-deploy - 在生产发布前进行验证 →
platform-deploy-validate - 执行 destructive 部署 →
platform-destructive-deploy(该技能使用此技能生成的清单) - 将元数据检索到本地 →
platform-metadata-retrieve
两种生成路径
路径 A — 由 CLI 驱动(推荐)
封装 sf project generate manifest。始终优先使用此路径;它了解所有元数据类型,并会生成规范的 XML,而且绝不会输出 *,从而完全避开通配符风险。
CLI 提供三种输入模式(互斥):
| 输入 | 标志 | 适用场景 |
|---|---|---|
| 源目录 | --source-dir (-p) | 用户指定了一个包含已存储在磁盘上的元数据的文件夹 |
| 组件列表 | --metadata (-m) | 用户指定了特定组件,例如 ApexClass:AccountService CustomObject:Account |
| 组织检查 | --from-org | 用户需要组织中当前的所有组件(或经过筛选的子集) |
可以指定 --source-dir 或 --metadata 其中之一,不能同时指定。--from-org 可以与 --metadata(筛选要包含的类型)或 --excluded-metadata(筛除类型)组合使用。
已验证的标志(不要臆造标志——如有疑问,请通过 sf project generate manifest --help 验证):
| 标志 | 用途 |
|---|---|
--source-dir、-p | 要扫描的本地源路径 |
--metadata、-m | 要包含的组件名称(例如 ApexClass:AccountService) |
--from-org | 要检查的组织的用户名或别名 |
--name、-n | 自定义输出文件名(与 --type 互斥) |
--type、-t | 预定义清单类型:package | pre | post | destroy |
--output-dir、-d | 写入清单的目录 |
--api-version | 覆盖请求的 API 版本 |
--include-packages、-c | 使用 --from-org 时,包含 managed 和/或 unlocked 软件包元数据 |
--excluded-metadata | 使用 --from-org 时要排除的类型 |
--json | 机器可读输出 |
按 --type 确定清单文件名:
--type | 输出文件 |
|---|---|
package(默认) | package.xml |
pre | destructiveChangesPre.xml |
post | destructiveChangesPost.xml |
destroy | destructiveChanges.xml |
可以指定 --type 或 --name 其中之一,不能同时指定。
规范的 CLI 示例
# Build package.xml from a source dir
sf project generate manifest \
--source-dir force-app/main/default \
--name package.xml \
--output-dir manifest \
--json
# Build package.xml from an explicit component list
sf project generate manifest \
--metadata ApexClass:AccountService \
--metadata ApexClass:ContactSelector \
--metadata CustomObject:Account \
--name package.xml \
--output-dir manifest \
--json
# Build destructiveChanges.xml from a component list
sf project generate manifest \
--metadata CustomField:Account.OldField__c \
--metadata CustomField:Account.OldStatus__c \
--type destroy \
--output-dir manifest \
--json
# Build a manifest by introspecting an org (filtered)
sf project generate manifest \
--from-org <alias> \
--metadata ApexClass,CustomObject,CustomLabels \
--output-dir manifest \
--json
如果同时需要 package.xml 和 destructive 清单,请运行 CLI 两次——一次使用 --type package(或使用默认值),另一次使用 --type destroy/pre/post。
路径 B — 手动编写备用方案
仅当 CLI 无法表达用户意图时使用此方案,例如用户想要“仅包含我今天修改的 Apex 类”,而变更集来自 git diff,而不是一个干净的目录或组件列表。在这种情况下:
- 自行解析组件(例如,解析
git diff --name-only并将路径映射回元数据类型)。 - 按元数据类型分组。
- 使用下方的架构内联生成 XML。
- 始终运行
sf project deploy start --manifest <file> --dry-run进行交叉验证(交由platform-metadata-deploy处理)。
Manifest XML 架构
根元素是元数据命名空间中的 <Package>。每种元数据类型对应一个 <types> 块,其中每个组件各有一个 <members>,并且只有一个 <name>。末尾的 <version> 声明 manifest 的 API 版本。
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>AccountService</members>
<members>ContactSelector</members>
<name>ApexClass</name>
</types>
<types>
<members>Account</members>
<name>CustomObject</name>
</types>
<types>
<members>Account.Status__c</members>
<name>CustomField</name>
</types>
<version>62.0</version>
</Package>
注意:
- 对于
CustomField、BusinessProcess、RecordType、Layout、ListView、ValidationRule、WebLink等与组件绑定的类型,成员使用Object.Name表示法。 destructiveChanges.xml、destructiveChangesPre.xml和destructiveChangesPost.xml使用相同的 XML 结构,只有文件名和用途不同。- 空 manifest(没有
<types>块)是合法的,有时会与破坏性变更 manifest 配合使用:
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<version>62.0</version>
</Package>
API 版本处理
每个 manifest 底部的 <version> 元素必须反映项目的 API 版本。
解析顺序:
- 从项目根目录下的
sfdx-project.json中读取sourceApiVersion。 - 如果用户传入了
--api-version,则改用该值。 - 如果两者都不可用,则使用
sf --version报告的值(CLI 捆绑的 API 版本)作为回退值,但必须警告用户,并建议他们在sfdx-project.json中设置sourceApiVersion,以确保可复现性。 - 切勿在未说明来源的情况下,将某个值(例如
62.0)静默写死在输出中。
# Quick read of sourceApiVersion
jq -r '.sourceApiVersion' sfdx-project.json
使用 CLI 路径时,除非用户明确指定覆盖值,否则省略 --api-version——CLI 已经会读取 sourceApiVersion。
通配符成员(<members>*</members>)
通配符成员会匹配该元数据类型的所有组件。**并非所有类型都允许使用通配符。**对不允许使用通配符的类型使用 *,会导致部署/检索错误,例如 Wildcards are not supported for this metadata type。
不允许使用通配符(必须逐一列出)
这些类型要求显式列出成员名称。常见示例:Profile、PermissionSet、PermissionSetGroup、CustomLabels、CustomObjectTranslation、Layout、Workflow(在某些 package 配置中)、SharingRules、StandardValueSet、ManagedTopics,以及大多数内容与对象绑定的“容器”类型(CustomField、RecordType、BusinessProcess、ListView、ValidationRule、WebLink、CompactLayout)。
对于这些类型,请逐一列出:
<types>
<members>Admin</members>
<members>Standard User</members>
<name>Profile</name>
</types>
通常允许使用通配符
大多数“独立”组件类型都接受 *。示例:ApexClass、ApexTrigger、ApexComponent、ApexPage、AuraDefinitionBundle、LightningComponentBundle、CustomApplication、CustomTab、StaticResource、EmailTemplate、Report、Dashboard、Flow、FlexiPage、CustomMetadata。完整列表及边缘情况请参阅 references/wildcard-allowlist.md。
经验法则:如果不确定,请明确列出组件。CLI 路径(--source-dir / --metadata)可以绕过此问题,因为它从不生成 *。
示例
示例 1 — 从目录生成 package.xml
“从
force-app/main/default/classes/生成 package.xml”
sf project generate manifest \
--source-dir force-app/main/default/classes \
--name package.xml \
--output-dir manifest \
--json
结果:manifest/package.xml,列出该文件夹中的所有 Apex 类。
示例 2 — 生成涵盖指定组件的 manifest
“生成一个涵盖 AccountService、ContactSelector 和 Account 自定义对象的 manifest”
sf project generate manifest \
--metadata ApexClass:AccountService \
--metadata ApexClass:ContactSelector \
--metadata CustomObject:Account \
--name package.xml \
--output-dir manifest \
--json
结果:manifest/package.xml,仅包含这三个组件。
示例 3 — 为删除操作同时生成 package.xml 和 destructiveChanges.xml
“为以下删除项创建 package.xml 和 destructiveChanges.xml:
Account.OldField__c、Account.OldStatus__c”
# Empty/minimal package.xml (deletion-only deploy still needs a package descriptor)
sf project generate manifest \
--metadata CustomLabels \
--name package.xml \
--output-dir manifest \
--json
# destructiveChanges.xml
sf project generate manifest \
--metadata CustomField:Account.OldField__c \
--metadata CustomField:Account.OldStatus__c \
--type destroy \
--output-dir manifest \
--json
生成后,交给 platform-destructive-deploy 验证并执行删除操作。
失败模式
| 症状 | 可能原因 | 恢复方法 |
|---|---|---|
Path does not exist: <dir> | --source-dir 指向不存在的文件夹 | 确认路径;使用 ls 验证;如果用户描述不明确,则默认使用 force-app/main/default |
| 生成的清单为空 | 源目录中没有可识别的元数据,或所有文件都被忽略 | 检查 .forceignore;确认路径中确实包含元数据文件(*.cls、*-meta.xml 等) |
部署时出现 Wildcards are not supported for this metadata type | 手动编写的清单对不允许使用通配符的类型使用了 * | 查看上方的通配符允许列表;明确列出各个组件 |
缺少 <version> 或版本不匹配 | sfdx-project.json 缺少 sourceApiVersion | 将 sourceApiVersion 添加到 sfdx-project.json,或向 CLI 传入 --api-version |
You can specify either --type or --name, but not both | CLI 调用同时传入了两个标志 | 删除其中一个;对于预定义名称,使用 --type;对于自定义名称,使用 --name |
You can specify either --source-dir or --metadata, but not both | CLI 调用同时传入了两个标志 | 选择一种输入模式 |
--from-org 输出中缺少组件 | Org 检查的批次过大,或该类型属于托管包 | 调低 SF_LIST_METADATA_BATCH_SIZE;如果需要包含托管包,则添加 --include-packages managed |
跨技能集成
| 需求 | 委派给 | 原因 |
|---|---|---|
| 使用生成的清单运行部署 | platform-metadata-deploy | 此技能仅负责生成文件 |
| 在生产版本发布前进行验证 | platform-deploy-validate | 针对生产环境进行预检 |
| 实际删除破坏性变更清单中的组件 | platform-destructive-deploy | 该技能会验证并执行破坏性部署 |
| 检索清单中列出的元数据 | platform-metadata-retrieve | 将 Org 元数据拉取到本地 |
| 编写清单中列出的元数据 | 其他 platform-* 生成器(例如 platform-custom-object-generate) | 清单只会列出磁盘上已存在的内容 |
完成格式
Manifest goal: <package | pre | post | destroy>
Input mode: <source-dir | metadata list | from-org | hand-built>
Output: <path/to/manifest.xml>
API version: <value> (source: sfdx-project.json | --api-version | CLI default)
Component count: <N> across <M> metadata types
Next step: <platform-metadata-deploy | platform-deploy-validate | platform-destructive-deploy>