Oubliez ce que vous pensez savoir sur semver

26-08-2022

Il existe une diversité de systèmes de numérotation des logiciels, du plus simple (n+1) au plus exotique (suivant les décimales de Pi). Dans le lot, semver décrit une numérotation en trinôme M.m.p où M représente des changements non rétro-compatibles, m représente des changements rétrocompatibles et p représente des correctifs. Puisque chaque système vise à bien communiquer aux consommateurs, semver semble la solution parfaite.

Semble seulement, car en fait cet idéal de communication parfaite n’est pas atteint ; le problème est la nature d’un changement rétro-incompatible. Dans la théorie, une rupture de compatibilité est simple : il s’agit d’une possibilité enlevée au consommateur.

workflow xkcd

Alors soyons clair, j’adore semver parce que les informations qu’il transmet sont les plus utiles dans une relation « fournisseur -> consommateur », mais je crois que les consommateurs que nous sommes ne pouvons pas plus faire confiance à ce système de numérotation qu’à n’importe quel autre.

Pourquoi ? Parce que la pratique peut être largement éloignée de la théorie pour plusieurs raisons possibles :

  • le fournisseur a mal compris la nature des définitions théoriques impliquant M, m ou p ;
  • un cas d’usage est passé au travers des mailles du filet du fournisseur et un changement s’avère incompatible ;
  • le fournisseur pense qu’il n’a pas d’autre choix.

NB: Ce dernier cas peut paraître absurde, il est pourtant arrivé aux images Docker MySQL 8.0 et 5.7 en juillet 2022. Sur une même version, les mainteneurs ont changé le système socle de Debian vers Oracle, créant de fait une rupture de compatibilité dans toutes les images filles.

Ce qui s’est passé ici est symptomatique de l’absence de norme de numérotation autour de la nouvelle sémantique de l’application : désormais dockerisée, que numérote-t-on ? Juste l’application ? L’ensemble application / infra ?

diff mysql docker

Ces trois situations le montrent, la prise de décision humaine est sujette à erreur et cette erreur fait perdre à semver la force de son système du numérotation sur tous les autres.

Les gestionnaires de dépendances

Aujourd’hui, nous utilisons massivement des gestionnaires de dépendances dédiés pour nos applications : composer, npm, gem, pub, etc. D’une certaine façon, ces gestionnaires de dépendances sont un peu responsables de la popularité de semver… et de son mésusage.

En effet, tous supportent l’opérateur de plage « ^ », permettant les mises à jour satisfaisant : >= M.m.p && < (M+1). Pire, composer et npm vont jusqu’à le recommander.

Ce positionnement fait semblant d’ignorer les écueils que nous avons vus plus tôt et c’est un vrai problème.

Il y a deux faits importants :

  1. vous ignorez ce que font les fournisseurs de dépendances et quelles pratiques logicielles ils suivent,
  2. si un défaut arrive dans votre application, c’est vous qui êtes en première ligne. Aucun de vos utilisateurs ne comprendra que vous ayez perdu le contrôle en faisant confiance à la mauvaise personne.

Des solutions pour avoir le meilleur des deux mondes

Pour éviter que les dangers se propagent comme une boule de neige, vous devez gérer le cycle de vie de vos dépendances comme vous géreriez votre propre code : chaque mise à jour doit faire l’objet de test pour éviter les régressions.

En tout premier lieu, il est donc nécessaire d’épingler le plus précisément possible les versions de dépendances. Les patches étant mieux compris que les différences rétro-compatibles / rétro-incompatibles, l’opérateur pessimiste « ~ » peut être un bon compromis (équivalent à >= M.m.p && < M.(m+1)).

Ensuite, puisque vous devez également prévenir l’excès inverse consistant à ne plus mettre à jour les dépendances, vous pouvez vous appuyer sur des outils surveillant vos dépendances ; les plus évolués vont jusqu’à créer des PRs / MRs pour vous :


Sources :


    Ce billet vous a plu ? Inscrivez-vous à notre newsletter pour ne manquer aucun article (Si vous ne voyez pas le formulaire, désactivez temporairement uBlock).