Andrew Hanna

Andrew Hanna

Gérer les suppressions sans risque dans un déploiement Salesforce

Gérer les suppressions sans risque dans un déploiement Salesforce

On supprime des métadonnées Salesforce avec un manifeste destructiveChanges.xml déployé aux côtés d'un package.xml, en choisissant si les suppressions s'exécutent avant ou après la partie additive du déploiement. Le danger n'est pas la syntaxe. C'est qu'une suppression réussie n'est pas annulable par un rollback de déploiement, et que les composants les plus susceptibles de casser sont ceux que personne n'a dans le contrôle de source.

Qu'est-ce qu'un manifeste destructiveChanges?

Un manifeste destructiveChanges utilise le même format que package.xml, avec une différence majeure: les jokers ne sont pas pris en charge. Chaque composant à supprimer doit être nommé.

Une entrée minimale ressemble à <types><members>Account.Legacy_Score__c</members><name>CustomField</name></types>.

Deux règles qui piègent à la première tentative:

  • Un package.xml doit toujours être présent, dans le même répertoire. Pour un déploiement de suppression seule, il porte la version d'API et ne liste aucun composant.
  • Les tentatives de suppression se poursuivent même si certains composants listés n'existent pas sur la cible. C'est pratique, et cela signifie aussi qu'une faute de frappe échoue en silence.

Les suppressions doivent-elles s'exécuter avant ou après le déploiement?

La CLI Salesforce offre les deux, via deux manifestes distincts: --pre-destructive-changes supprime avant le déploiement, --post-destructive-changes après.

Par défaut, choisissez post-destructive. Le paquet additif arrive d'abord, donc tout ce qui référence encore le composant condamné peut être réorienté dans le même déploiement avant sa disparition.

Choisissez pré-destructive quand l'ancien et le nouveau entrent en collision. Les cas les plus nets:

  • Vous réutilisez un nom d'API pour un autre composant.
  • Vous changez le type d'un champ en le supprimant puis en le recréant.
  • Une règle de validation ou un champ obligatoire bloquerait le changement de données ou de configuration que vous déployez.

Inverser l'ordre produit les deux échecs classiques: une suppression qui échoue parce qu'un élément référence encore le composant, ou un ajout qui échoue parce que le nom est pris.

Que emporte réellement une suppression?

Autant être direct. Supprimer un champ supprime ses données. Les composants supprimés vont à la corbeille sauf si le déploiement active purgeOnDelete, qui les rend immédiatement éligibles à la suppression. Les champs de récapitulation contournent la corbeille quel que soit ce réglage.

Et rollbackOnError, obligatoire pour les déploiements en production, annule les changements d'un déploiement échoué. Ce n'est pas un bouton d'annulation pour une suppression réussie. S'il faut récupérer les données après une purge réussie, vous êtes dans une conversation de restauration, pas de déploiement.

Il existe aussi une catégorie de casse qui n'apparaît jamais dans votre dépôt: rapports, vues de liste et tableaux de bord référençant le champ. C'est de la configuration construite par un utilisateur métier, rarement dans Git, et le déploiement ne vous en avertira pas.

Quels contrôles préalables évitent une suppression de champ ratée?

  1. Lancez le contrôle de dépendances dans Setup. Salesforce signalera champs de formule, règles de validation, mises en page et autres références déclaratives. Nécessaire, pas suffisant.
  2. Cherchez les métadonnées par nom d'API. Passez le dépôt au grep. Flows, Apex, modèles d'e-mail et ensembles d'autorisations référencent les champs sous forme de chaînes, et ces références n'apparaissent pas dans toutes les vues de dépendances.
  3. Vérifiez rapports et vues de liste séparément. Rien dans votre pipeline ne les connaît. Quelqu'un doit regarder.
  4. Exportez d'abord les données. Un CSV de la colonne avec les identifiants d'enregistrement. Dix minutes, et c'est le seul vrai filet.
  5. Lancez les tests locaux. Pour les classes et déclencheurs Apex, la recommandation de Salesforce est d'exécuter tous les tests locaux: c'est ainsi qu'on trouve le code référençant encore l'élément supprimé.
  6. Vérifiez l'absence de page Lightning active. Un composant associé à une page Lightning active ne peut pas être supprimé. Désactivez d'abord la substitution d'action dans Lightning App Builder.
  7. Validez contre la production. Un déploiement checkOnly, ou --dry-run depuis la CLI, valide et exécute les tests sans rien enregistrer.

Comment étaler une suppression sur deux versions?

Le motif sur n'est pas un meilleur manifeste. C'est de scinder la suppression en deux versions.

  1. Version N, deprecation. Retirez toutes les références: mises en page, formules, flows, Apex, ensembles d'autorisations, rapports. Marquez le champ comme déprécié dans sa description pour la personne suivante. Cessez d'y écrire. Ne déployez rien de destructif.
  2. Laissez reposer. Laissez passer un cycle de reporting. C'est là que remonte le rapport dont personne n'avait parlé, et il remonte comme une question, pas comme un incident.
  3. Version N+1, suppression. Exportez les données, puis déployez le manifeste destructiveChanges seul, sans rien d'autre.

Livrer une suppression seule compte. Mélangée à vingt autres changements, en cas de problème vous n'isolez pas vite la cause, et le rollback emporte les bons changements.

La même discipline vaut pour les renommages, que Git enregistre comme une suppression plus un ajout. Traitez chaque renommage comme une deprecation sur deux versions, sauf si vous pouvez prouver que rien ne référence l'ancien nom. D'autres playbooks de livraison sont dans notre bibliothèque SF Guides.

FAQ

Puis-je utiliser un joker dans destructiveChanges.xml?

Non. Les jokers ne sont pas pris en charge. Chaque composant à supprimer doit être nommé explicitement.

Ai-je encore besoin d'un package.xml si je ne fais que supprimer?

Oui. Il doit se trouver dans le même répertoire, porter la version d'API et ne lister aucun composant.

Puis-je récupérer un champ supprimé par un déploiement?

Il va à la corbeille sauf si purgeOnDelete était actif, et les champs de récapitulation contournent la corbeille dans tous les cas. Considérez l'export de données comme le vrai plan de reprise.

Pourquoi mon déploiement destructif a-t-il réussi sans rien supprimer?

Les tentatives de suppression se poursuivent quand un composant listé est absent de la cible: un mauvais nom d'API donne donc un déploiement vert et aucun changement. Comparez la cible avant et après.

Quand supprimer avant le déploiement plutôt qu'après?

Quand ancien et nouveau composants entrent en conflit: réutilisation d'un nom d'API, recréation d'un champ avec un autre type, ou retrait d'une règle qui bloquerait le reste du déploiement.

Articles similaires

Curieux de livrer plus vite avant de vous lancer ? Parlons-en

Sans engagement.