platform-destructive-deploy
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHandling Destructive Changes
处理破坏性变更
Coordinate metadata deletion against a Salesforce org via the destructiveChanges manifest. Runs in three phases: scope → validate → execute, with stricter guardrails for production.
通过destructiveChanges清单协调针对Salesforce组织的元数据删除操作。分为三个阶段:范围确定→验证→执行,针对生产环境有更严格的防护措施。
Phase 1 — Scope the deletion
阶段1 — 确定删除范围
Step 1a — Gather the components to remove
步骤1a — 收集要移除的组件
Ask the user (or infer from context) which components to delete. For each, capture:
- Metadata type (e.g. ,
CustomObject,CustomField,ApexClass,Flow)PermissionSet - API name (e.g. ,
Project__c,Account.Status__c)MyController
询问用户(或从上下文推断)要删除哪些组件。对于每个组件,需记录:
- 元数据类型(例如 、
CustomObject、CustomField、ApexClass、Flow)PermissionSet - API名称(例如 、
Project__c、Account.Status__c)MyController
Step 1b — Local dependency scan (best-effort)
步骤1b — 本地依赖扫描(尽力而为)
Before generating the manifest, scan the local project for references to each component. Use Grep over :
force-app/bash
grep -rn "<componentApiName>" force-app/ --include='*.cls' --include='*.trigger' --include='*.xml' --include='*.js' --include='*.html'If references are found:
- List them to the user
- Recommend either updating those references first OR removing them in the same destructive deploy
- Do NOT proceed silently — surface the dependency risk
生成清单前,扫描本地项目中对每个组件的引用。使用Grep遍历目录:
force-app/bash
grep -rn "<componentApiName>" force-app/ --include='*.cls' --include='*.trigger' --include='*.xml' --include='*.js' --include='*.html'如果发现引用:
- 向用户列出这些引用
- 建议先更新这些引用,或者在同一次破坏性部署中一并移除
- 切勿静默继续——必须告知用户依赖风险
Step 1c — Generate destructiveChanges.xml
destructiveChanges.xml步骤1c — 生成destructiveChanges.xml
destructiveChanges.xmlWrite to (for pre-deploy deletion) or (for post-deploy deletion). Use the standard Salesforce metadata format:
manifest/destructiveChangesPre.xmlmanifest/destructiveChangesPost.xmlxml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>Project__c</members>
<members>OldThing__c</members>
<name>CustomObject</name>
</types>
<types>
<members>Account.Status__c</members>
<name>CustomField</name>
</types>
<version>62.0</version>
</Package>Use the API version from 's .
sfdx-project.jsonsourceApiVersionGroup components by metadata type (one block per type). For namespaced fields, use notation.
<types>Object.Field写入(用于部署前删除)或(用于部署后删除)。采用Salesforce标准元数据格式:
manifest/destructiveChangesPre.xmlmanifest/destructiveChangesPost.xmlxml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<types>
<members>Project__c</members>
<members>OldThing__c</members>
<name>CustomObject</name>
</types>
<types>
<members>Account.Status__c</members>
<name>CustomField</name>
</types>
<version>62.0</version>
</Package>使用中指定的API版本。
sfdx-project.jsonsourceApiVersion按元数据类型对组件进行分组(每种类型对应一个块)。对于带命名空间的字段,使用格式。
<types>Object.FieldPhase 2 — Validate
阶段2 — 验证
ALWAYS validate before executing a destructive deploy:
bash
sf project deploy validate \
--pre-destructive-changes manifest/destructiveChangesPre.xml \
--manifest manifest/package.xml \
--target-org <alias> \
--test-level RunLocalTests \
--json(For post-destructive: use .)
--post-destructive-changesIf doesn't exist, create an empty one alongside (deletion-only deploy needs a package descriptor):
package.xmlxml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<version>62.0</version>
</Package>If validation fails, surface errors and STOP. Common failure modes:
- "Cannot delete: referenced by Apex/Flow/Layout" → component still has references
- "Cannot delete: required for license" → managed-package or license dependency
- "Insufficient access" → user lacks delete permission
执行破坏性部署前必须先验证:
bash
sf project deploy validate \
--pre-destructive-changes manifest/destructiveChangesPre.xml \
--manifest manifest/package.xml \
--target-org <alias> \
--test-level RunLocalTests \
--json(针对部署后删除:使用参数。)
--post-destructive-changes如果不存在,需在旁边创建一个空文件(仅删除的部署需要包描述符):
package.xmlxml
<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
<version>62.0</version>
</Package>如果验证失败,需显示错误并终止操作。常见失败原因:
- "无法删除:被Apex/Flow/Layout引用" → 组件仍存在引用
- "无法删除:许可证必需" → 托管包或许可证依赖
- "权限不足" → 用户缺少删除权限
Phase 3 — Execute
阶段3 — 执行
Production path
生产环境流程
Confirm whether the target is production before executing. The reliable check is the gate's classifier (returns ):
production|sandbox|scratch|trial|devhub|unknownbash
sf org display --target-org <alias> --json | "${CLAUDE_PLUGIN_ROOT}/scripts/sf-deploy-gate" classifyIf the classifier returns :
production- Display destructive confirmation banner (mirroring )
platform-quick-deploy - List EVERY component that will be deleted
- Require explicit "yes, delete from PRODUCTION" confirmation
- Reject unless the user types it explicitly
--purge-on-delete
The PreToolUse hook () will already block bare destructive commands against prod — surface that denial to the user, do not work around it.
sf-deploy-gate destructive执行前确认目标是否为生产环境。可靠的检查方式是使用gate分类器(返回):
production|sandbox|scratch|trial|devhub|unknownbash
sf org display --target-org <alias> --json | "${CLAUDE_PLUGIN_ROOT}/scripts/sf-deploy-gate" classify如果分类器返回:
production- 显示破坏性确认横幅(与一致)
platform-quick-deploy - 列出所有将被删除的组件
- 要求用户明确确认“yes, delete from PRODUCTION”
- 除非用户明确输入,否则拒绝使用参数
--purge-on-delete
PreToolUse钩子()已会阻止针对生产环境的裸破坏性命令——需向用户说明该限制,切勿绕过。
sf-deploy-gate destructiveSandbox / Scratch path
沙盒/临时组织流程
bash
sf project deploy start \
--pre-destructive-changes manifest/destructiveChangesPre.xml \
--manifest manifest/package.xml \
--target-org <alias> \
--json \
--wait 30Add only if the user explicitly asked to permanently delete (skip the recycle bin).
--purge-on-deletebash
sf project deploy start \
--pre-destructive-changes manifest/destructiveChangesPre.xml \
--manifest manifest/package.xml \
--target-org <alias> \
--json \
--wait 30仅当用户明确要求永久删除(跳过回收站)时,才添加参数。
--purge-on-deletePhase 4 — Post-delete cleanup
阶段4 — 删除后清理
After a successful destructive deploy:
- Recommend a is NOT useful (component is gone) — instead suggest cleaning up the local source:
sf project retrieve start --metadata <Type>:<Name>bash# Remove the now-deleted local files to keep source tracking accurate rm -rf force-app/main/default/<path-to-component> - If deleting a custom field with data, remind the user that data is gone (or in the recycle bin until purged)
- Recommend running tests to confirm no runtime regressions
破坏性部署成功后:
- 建议无需执行(组件已不存在)——而是建议清理本地源代码:
sf project retrieve start --metadata <Type>:<Name>bash# 删除已删除的本地文件,保持源代码跟踪准确 rm -rf force-app/main/default/<path-to-component> - 如果删除的是带有数据的自定义字段,提醒用户数据已丢失(或在回收站中,直到被彻底清除)
- 建议运行测试以确认无运行时回归问题
Rules
规则
- ALWAYS validate first; NEVER skip Phase 2
- ALWAYS scan for local references; NEVER delete blindly
- ALWAYS gate production with explicit user confirmation
- NEVER add without explicit user request
--purge-on-delete - NEVER use on a destructive deploy
--ignore-errors - ALWAYS use the API version from , not a hardcoded value
sfdx-project.json - If the user is deleting a field with or that's used in
required="true"picklist values, surface the cascade impact before proceedingRecordType
- 必须先验证;切勿跳过阶段2
- 必须扫描本地引用;切勿盲目删除
- 必须通过用户明确确认来保护生产环境
- 除非用户明确要求,否则切勿添加参数
--purge-on-delete - 切勿在破坏性部署中使用参数
--ignore-errors - 必须使用中的API版本,而非硬编码值
sfdx-project.json - 如果用户要删除的字段或用于
required="true"选择列表值的字段,需在继续前告知用户连锁影响RecordType