Start free
Andrew Hanna

Andrew Hanna

Résoudre les conflits de métadonnées Salesforce sans perdre le travail de personne

Résoudre les conflits de métadonnées Salesforce sans perdre le travail de personne

Réponse courte : la plupart des conflits de merge Salesforce ne sont pas de vrais désaccords. Ce sont deux personnes qui ajoutent des choses sans rapport au même fichier XML surdimensionné, ou les mêmes éléments qui reviennent dans un ordre différent. Pour les métadonnées additives comme les profils, permission sets, layouts et labels, combinez les deux côtés, et ne fusionnez jamais à la main du XML généré comme les Flows : choisissez une version et rejouez l'autre modification dans Flow Builder.

Pourquoi les conflits Salesforce diffèrent-ils des conflits de code habituels ?

Quatre particularités de la plateforme expliquent presque tout.

  • L'ordre des éléments n'est pas garanti. La Metadata API peut renvoyer le même fichier avec ses éléments dans un autre ordre : Git signale alors un conflit alors que rien n'a changé. Ce sont des faux conflits.
  • Certains types tiennent dans un seul fichier géant. Un profil porte les permissions d'objets, de champs, de classes Apex et de pages dans un seul document. Deux personnes sur des fonctionnalités sans rapport écrivent sur les mêmes lignes.
  • Une partie du XML est générée par la machine. Une définition de Flow contient des coordonnées de canevas et des noms d'éléments générés. Elle n'est pas faite pour être éditée à la main, ni pour être fusionnée à la main.
  • Git résout du texte, Salesforce valide du sens. Un merge textuellement propre peut produire un fichier refusé au déploiement, ou un fichier valide dont la permission de quelqu'un a discrètement disparu.

Quels types de métadonnées entrent le plus en conflit, et que faire pour chacun ?

Profils et permission sets

Les pires, et presque toujours additifs. Deux branches ajoutent chacune un bloc objectPermissions ou fieldPermissions, et les ajouts se retrouvent côte à côte. Prenez les deux côtés, puis dédoublonnez sur l'élément clé (field, object, apexClass) et retriez. Ne résolvez jamais un profil en acceptant un côté en bloc.

À savoir : Salesforce a annulé la retraite des permissions dans les profils (article Salesforce Help 003834041), donc les profils ne disparaîtront pas à une date fixe et le problème ne se réglera pas tout seul. Salesforce recommande toujours un modèle de moindre privilège fondé sur les permission sets, et sortir les permissions des profils réduit réellement la surface de conflit, car les permission sets sont de petits fichiers par fonctionnalité.

Flows

Ne les fusionnez pas à la main. Le XML contient des noms d'éléments générés et des coordonnées de canevas : une fusion ligne à ligne produit quelque chose de plausible et faux. Choisissez une version gagnante et rejouez l'autre modification dans Flow Builder.

Page layouts et pages Lightning

Le XML d'un layout liste chaque élément dans l'ordre des positions : deux personnes qui ajoutent des champs à des sections différentes se percutent quand même si ces sections sont voisines. Combinez les deux côtés, puis vérifiez que chaque layoutItem des deux parents a survécu. Si un conflit sur une page Lightning dépasse quelques lignes, refaites-la dans le Lightning App Builder au lieu de la fusionner.

Objets et champs personnalisés

Si votre dépôt stocke un objet dans un seul fichier, chaque changement de champ y touche. Le format source décomposé donne un fichier par champ et supprime la plupart de ces conflits avant qu'ils n'existent.

Classes Apex et triggers

Traitez-les comme des conflits de code ordinaires, parce que c'en sont. Résolvez la logique, relancez les tests, puis vérifiez que la classe est toujours accordée dans les profils et permission sets qui la référencent.

Labels personnalisés et traductions

Fichiers uniques et alphabétiques, purement additifs. Prenez les deux côtés et retriez.

Comment lire un diff de métadonnées avant de résoudre ?

  1. Identifiez quel côté est lequel. Dans un merge, "ours" est la branche cible et "theirs" l'entrante. Dans un rebase, c'est l'inverse. Se tromper là-dessus est la façon la plus courante de perdre du travail.
  2. Écartez les différences d'ordre pur. Si les deux côtés contiennent les mêmes éléments dans un ordre différent, personne n'a rien changé.
  3. Cherchez les suppressions, pas les ajouts. Les ajouts se combinent en général sans risque. Un bloc présent d'un seul côté est le changement qui coûte une journée à quelqu'un.
  4. Comparez aussi avec l'org cible, pas seulement avec la branche. Quelqu'un a peut-être modifié l'org directement depuis la création de la branche.
  5. Validez avant de fusionner la pull request. Un XML qui fusionne proprement peut quand même échouer à la validation de déploiement.

Comment résoudre un conflit de profil sans supprimer la permission d'un collègue ?

  1. Listez les blocs en conflit par leur élément clé plutôt que par numéro de ligne.
  2. Conservez les deux côtés de tout bloc présent d'un seul côté.
  3. Quand la même clé apparaît des deux côtés avec des valeurs différentes, tranchez permission par permission et notez le raisonnement dans la pull request.
  4. Retirez les marqueurs de conflit et retriez le fichier pour que le prochain diff reste petit.
  5. Validez le fichier fusionné contre l'org cible.
  6. Demandez aux deux auteurs de confirmer que leur permission existe toujours après la fusion. Une minute, et cela rattrape ce que la revue laisse passer.

Comment résoudre un conflit de Flow sans risque ?

  1. Prenez comme base la version déjà présente sur la branche cible et écartez l'autre côté dans Git.
  2. Ouvrez une sandbox contenant cette version de base et rejouez la modification du second auteur dans Flow Builder.
  3. Récupérez le flow et committez le fichier récupéré comme résolution.
  4. Vérifiez quelle version est active dans l'org cible avant de déployer, car déployer un flow ajoute une version au lieu d'en remplacer une.

Comment éviter le prochain conflit ?

  • Des branches de courte durée, fusionnées la semaine même où elles sont créées.
  • Une fonctionnalité par pull request.
  • Des permissions dans des permission sets par fonctionnalité plutôt que dans des profils partagés.
  • Des objets stockés en format source décomposé.
  • Rapatriez la branche cible dans la vôtre avant d'ouvrir la PR, pour résoudre à votre rythme, votre propre changement encore en tête.

Ce guide fait partie de nos guides DevOps Salesforce.

FAQ

Git peut-il résoudre seul les conflits de métadonnées Salesforce ?

Seulement au niveau du texte. Git ne peut pas savoir que deux blocs de profil sont indépendants ni qu'un fichier réordonné est inchangé : il lève de faux conflits et accepte volontiers une fusion sémantiquement fausse.

Qu'est-ce qu'un faux conflit ?

Un conflit où les deux côtés contiennent les mêmes métadonnées dans un ordre différent. La Metadata API ne garantit pas l'ordre des éléments : deux récupérations peuvent différer sans changement réel.

Faut-il parfois éditer le XML d'un Flow à la main pour résoudre un conflit ?

Non. Choisissez une version, rejouez l'autre modification dans Flow Builder, puis committez ce que vous récupérez.

Pourquoi les profils entrent-ils en conflit alors que nous travaillions sur des sujets différents ?

Un profil est un fichier unique couvrant les permissions de chaque objet, champ et classe de l'org : des fonctionnalités sans rapport finissent sur des lignes voisines.

Comment vérifier que la fusion n'a rien perdu ?

Comparez le fichier fusionné aux deux versions parentes, confirmez que chaque élément clé des deux côtés a survécu, et validez le déploiement contre l'org cible avant de fusionner.

Articles similaires

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

Sans engagement.