• Projects
  • Service
  • About
  • branding.bz
  • Podcast
  • Tips
  • FAQ
  • Recruit
  • Download
  • Contact
  • branding.bz(ブランド構築SaaS)
  • DESIGN NOW(デザインメディア)
  • X
  • LinkedIn
  • Spotify
  • Facebook

213-0011 神奈川県川崎市高津区久本3-6-7-303

© 2026 ID INC. All rights reserved

claude-skills/スキル
SKILLOfficialdevelopment

platform-destructive-deploy

プラグイン
salesforce-development
ソース
GitHub で見る ↗
説明

Salesforce(CRM・顧客管理システム)の組織に対して、destructiveChanges.xml(削除指示リスト)による削除・デプロイワークフロー(デプロイ:システムへの配置)を実行します。 **次のような場合に使用:** - ユーザーがカスタムオブジェクト、フィールド、Apexクラス、フロー、またはその他のメタデータコンポーネント(システム構成情報)を組織から削除・削除したいと要望する場合 - リリース(公開)の一部として「破壊的デプロイ」(既存のコンポーネント削除を伴うデプロイ)や削除を実行する場合 実行前にバリデーション(検証)を行い、本番環境への作用を明示的な確認で制限します。 **使用しない場合:** - ローカルファイルの削除(Bashを使用) - 新規コンポーネントのデプロイ(platform-metadata-deployを使用)

原文を表示

Execute the destructiveChanges.xml delete-and-deploy workflow against a Salesforce org. TRIGGER when the user asks to delete/remove a custom object, field, Apex class, flow, or any metadata component FROM an org, or to perform a 'destructive deploy' / removal as part of a release. Validates first and gates production with explicit confirmation. DO NOT TRIGGER for local file deletion (use Bash), or for net-new deploys (use platform-metadata-deploy).

ユースケース
  • Salesforceから不要なメタデータを削除するとき
  • 破壊的デプロイを実行するとき
  • リリースの一部として削除作業を行うとき
  • 削除実行前に検証を行いたいとき
本文(日本語訳)

破壊的な変更の処理

Salesforce組織に対するメタデータ削除を、destructiveChanges(削除指定)マニフェストを通じて実行します。3段階のプロセス(範囲決定 → 検証 → 実行)で進め、本番環境にはより厳密なチェックを適用します。

フェーズ1:削除の範囲を決定する

ステップ1a:削除対象のコンポーネントを集める

ユーザーに確認するか、文脈から判断して、どのコンポーネントを削除するかを決めます。各コンポーネントについて以下を記録します:

  • メタデータ種別(例: CustomObject、CustomField、ApexClass、Flow、PermissionSet)
  • API名(例: Project__c、Account.Status__c、MyController)

ステップ1b:ローカル依存関係スキャン(ベストエフォート)

マニフェストを生成する前に、ローカルプロジェクト内で各コンポーネントへの参照を検索します。force-app/ ディレクトリに対してGrepコマンドを使用:

grep -rn "<componentApiName>" force-app/ --include='*.cls' --include='*.trigger' --include='*.xml' --include='*.js' --include='*.html'

参照が見つかった場合:

  • ユーザーにリストアップして表示
  • その参照を先に更新するか、同じ削除デプロイで一緒に削除することを提案
  • 黙って進めない — 依存関係のリスクを必ず伝える

ステップ1c:destructiveChanges.xml を生成する

manifest/destructiveChangesPre.xml(デプロイ前の削除用)または manifest/destructiveChangesPost.xml(デプロイ後の削除用)に書き込みます。Salesforceの標準的なメタデータ形式を使用:

<?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>

sfdx-project.json の sourceApiVersion からAPIバージョンを取得します。

コンポーネントをメタデータ種別ごとにグループ化(種別ごとに1つの <types> ブロック)します。ネームスペース付きのフィールドは Object.Field という記法を使用します。

フェーズ2:検証

削除デプロイを実行する前に、必ず 検証を行います:

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.xml が存在しない場合、その横に空のファイルを作成します(削除のみのデプロイにもパッケージ記述子が必要):

<?xml version="1.0" encoding="UTF-8"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <version>62.0</version>
</Package>

検証が失敗した場合、エラーを表示して 中止 します。よくある失敗パターン:

  • 「Cannot delete: referenced by Apex/Flow/Layout」→ コンポーネントがまだ参照されている
  • 「Cannot delete: required for license」→ マネージドパッケージまたはライセンス依存
  • 「Insufficient access」→ ユーザーに削除権限がない

フェーズ3:実行

本番環境の場合

削除を実行する前に、対象が本番環境かどうかを確認します。確実な判定方法は、デプロイフック(本番|サンドボックス|スクラッチ|試用|不明 を返す)と同じ分類器を使うことです:

"${CLAUDE_PLUGIN_ROOT}/scripts/sf-deploy-gate" bucket <alias>

unknown は組織の種別を確認できなかった場合です(通常、組織レコードが不完全)。ユーザーに明確に伝えます:デプロイゲートは削除を許可し、保存時の自動デプロイはその組織ではオフのままであり、sf org login web で再認証すれば分類が通常復旧します。

分類器が production を返した場合:

  1. 削除確認バナーを表示(platform-quick-deploy に倣う)
  2. 削除されるコンポーネント すべて をリストアップ
  3. 「本番環境から削除する、これで確定」という明示的な確認を要求
  4. ユーザーが明確に入力しない限り、--purge-on-delete を拒否

PreToolUseフック(sf-deploy-gate destructive)は既に本番環境への削除コマンドをブロック — その拒否をユーザーに伝え、回避策を使わないこと。

サンドボックス・スクラッチ環境の場合

sf project deploy start \
  --pre-destructive-changes manifest/destructiveChangesPre.xml \
  --manifest manifest/package.xml \
  --target-org <alias> \
  --json \
  --wait 30

--purge-on-delete はユーザーが明確に完全削除を指示した場合にのみ追加します(ごみ箱をスキップ)。

フェーズ4:削除後のクリーンアップ

削除デプロイが成功した後:

  • sf project retrieve start --metadata <Type>:<Name> の使用を勧めない(コンポーネントはもう存在しない) — 代わりに、ローカルソースをクリーンアップすることを提案:
    # 削除済みのローカルファイルを削除して、ソースの追跡を正確に保つ
    rm -rf force-app/main/default/<path-to-component>
    
  • カスタムフィールド削除時にデータが存在する場合、データが削除されている(またはごみ箱にある)ことを思い出させる
  • テストを実行して、実行時の問題がないことを確認することを勧める

ルール

  • 検証は 必ず 実行する。フェーズ2を省略しない
  • ローカル参照スキャンは 必ず 実行する。闇雲に削除しない
  • 本番環境の削除は 必ず ユーザーの明示的な確認でゲートする
  • ユーザーが明確に要求しない限り --purge-on-delete を追加しない
  • 削除デプロイで --ignore-errors を使わない
  • sfdx-project.json のAPIバージョンを使用する。ハードコード値を使わない
  • ユーザーが required="true" 属性のフィールド、または RecordType ピックリスト値で使用されているフィールドを削除する場合、連鎖削除の影響を実行前に伝える
原文(English)を表示

Handling 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.

Phase 1 — Scope the deletion

Step 1a — Gather the components to remove

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)

Step 1b — Local dependency scan (best-effort)

Before generating the manifest, scan the local project for references to each component. Use Grep over force-app/:

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

Step 1c — Generate destructiveChanges.xml

Write to manifest/destructiveChangesPre.xml (for pre-deploy deletion) or manifest/destructiveChangesPost.xml (for post-deploy deletion). Use the standard Salesforce metadata format:

<?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 sfdx-project.json's sourceApiVersion.

Group components by metadata type (one <types> block per type). For namespaced fields, use Object.Field notation.

Phase 2 — Validate

ALWAYS validate before executing a destructive deploy:

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-changes.)

If package.xml doesn't exist, create an empty one alongside (deletion-only deploy needs a package descriptor):

<?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

Phase 3 — Execute

Production path

Confirm whether the target is production before executing. The reliable check is the gate's classifier, which resolves the org the same way the deploy hook does (returns production|sandbox|scratch|trial|unknown):

"${CLAUDE_PLUGIN_ROOT}/scripts/sf-deploy-gate" bucket <alias>

unknown means the org type could not be confirmed (usually an incomplete org record). Say so plainly: the deploy gate still allows the deploy, auto-deploy on save stays off for that org, and re-authenticating with sf org login web usually restores the classification.

If the classifier returns production:

  1. Display destructive confirmation banner (mirroring platform-quick-deploy)
  2. List EVERY component that will be deleted
  3. Require explicit "yes, delete from PRODUCTION" confirmation
  4. Reject --purge-on-delete unless the user types it explicitly

The PreToolUse hook (sf-deploy-gate destructive) will already block bare destructive commands against prod — surface that denial to the user, do not work around it.

Sandbox / Scratch path

sf project deploy start \
  --pre-destructive-changes manifest/destructiveChangesPre.xml \
  --manifest manifest/package.xml \
  --target-org <alias> \
  --json \
  --wait 30

Add --purge-on-delete only if the user explicitly asked to permanently delete (skip the recycle bin).

Phase 4 — Post-delete cleanup

After a successful destructive deploy:

  • Recommend a sf project retrieve start --metadata <Type>:<Name> is NOT useful (component is gone) — instead suggest cleaning up the local source:
    # 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

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 --purge-on-delete without explicit user request
  • NEVER use --ignore-errors on a destructive deploy
  • ALWAYS use the API version from sfdx-project.json, not a hardcoded value
  • If the user is deleting a field with required="true" or that's used in RecordType picklist values, surface the cascade impact before proceeding

原文・著作権は Anthropic および各プラグイン作者に帰属します。日本語訳は Claude API による自動翻訳です。