Les liens de la semaine – Édition #31

Développement

Web

Technologie

Science et autres

Versionnage sémantique

Il y a un comportement que je considère comme pratiquement universel chez les développeurs. Lorsqu’on se donne la peine d’y porter attention, il devient clair et limpide que nous le faisons à peu près tous. Cela fait comme partie du processus de développement logiciel. Un peu comme si cela était implicite. Un peu comme la règle non écrite que tous se doivent de suivre.

Vous vous doutez bien de ce que je veux introduire. Nous donnons des numéros de version à tout ce que nous produisons.

Parfois ce sera une version Alpha ou Beta. Une autre fois ce sera une version 0.1. Toutefois, le moment tant attendu sera celui de la version 1.0. Celui de la sortie officielle, loin d’être finale.

Il peut être amusant de donner à brûle-pourpoint des numéros de version. Dans la très grande majorité des cas, ce numéro de version sera sans incidence. On s’en branle un peu non? Le code compile. C’est tout ce qui nous préoccupe.

La nécessité d’avoir une logistique de versionnage plus rigoureuse s’impose lorsqu’il vient le temps de maintenir un bout de code qui sera utilisé en dépendance pour d’autres logiciels. La question devient soudainement différente. Comment je vais communiquer l’importance de mes changements et ainsi que le risque associé à la mise à jour à une version en particulier?

La sémantique

Le versionnage sémantique vise à imposer une structure aux numéros de version qui seront donnés à votre logiciel. Chacun des éléments qui composeront un numéro de version a un but particulier ayant pour but de communiquer l’intention de cette version.

Le document initial a douze règles régissant la mise en oeuvre des numéros de versions. Je vous fais part d’une traduction libre, tirée d’un fork GitHub de la part de DudePascalou.

Les mots clés “DOIT”, “NE DOIT PAS”, “OBLIGATOIRE”, “DEVRAIT”, “NE DEVRAIT PAS”, “RECOMMANDÉ”, “PEUT”, et “OPTIONNEL” dans ce document doivent être interprétés comme décrit dans la RFC 2119.

  1. Tout logiciel utilisant le Versionnement Sémantique DOIT déclarer une API publique. Cette API peut être déclarée dans le code lui-même ou dans un document. Dans tous les cas, elle doit être précise et claire.
  2. Un numéro de version standard DOIT prendre la forme X.Y.Z où X, Y et Z sont des entiers non négatifs. X est la version majeure, Y est la version mineure, et Z est la version de patch. Chaque élément DOIT augmenter numériquement par incréments d’une unité. Par exemple : 1.9.0 -> 1.10.0 -> 1.11.0.
  3. Quand un numéro de version majeur est incrémenté, la version mineure et la version patch DOIVENT être remises à zéro. Quand un numéro de version mineur est incrémenté, la version patch DOIT être remise à zéro. Par exemple: 1.1.3 -> 2.0.0 et 2.1.7 -> 2.2.0.
  4. Une fois qu’une version d’un composant est publiée, le contenu de cette version NE DOIT PAS être modifié. Toute modification doit être publiée comme une nouvelle version.
  5. La version majeure zéro (0.y.z) sert au développement initial. Tout peut changer à tout moment. L’API publique ne devrait pas être considérée comme stable.
  6. La version 1.0.0 définit l’API publique. La façon dont le numéro de version est incrémenté après la publication est dépendante de cette API publique.
  7. La version de patch Z (x.y.Z | x > 0) DOIT être incrémentée si des corrections d’anomalies rétro-compatibles sont effectuées. Une correction d’anomalie est définie comme un changement interne qui corrige un comportement incorrect.
  8. La version mineure Y (x.Y.z | x > 0) DOIT être incrémentée si une nouvelle fonctionnalité rétro-compatible est introduite dans l’API publique. Elle DOIT être incrémentée si une fonctionnalité de l’API publique est marquée comme obsolète. Elle PEUT être incrémentée si une nouvelle fonctionnalité ou amélioration est introduite dans le code privé. Elle PEUT inclure des changements de niveau de patch. La version de patch DOIT être remise à 0 lorsque la version mineure est incrémentée.
  9. La version majeure X (X.y.z | X > 0) DOIT être incrémentée si des changements rétro-incompatibles sont introduits à l’API publique. Elle PEUT inclure des changements mineurs et de patch. Les numéros de version de patch et mineurs DOIVENT être remis à 0 lorsque la version majeure est incrémentée.
  10. Une version admissible (de l’anglais pre-release) PEUT être notée par l’ajout d’un tiret et une série d’identifiants séparés par des points suivant immédiatement la version de patch. Les identifiants DOIVENT être composés uniquement de caractères alphanumériques ASCII et de tirets [0-9A-Za-z-]. Des versions admissibles sont utilisables et précèdent la version normale associée (version admissible < version normale). Exemples : 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7, 1.0.0-x.7.z.92.
  11. Une version de construction PEUT être représentée par l’ajout d’un signe “plus” et d’une série d’identifiants séparés par des points suivant immédiatement la version de patch ou admissible. Les identifiants DOIVENT être composés uniquement de caractères alphanumériques ASCII et de tirets [0-9A-Za-z-]. Les versions de construction sont utilisables et suivent la version normale associée (version de construction > version normale). Exemples: 1.0.0+build.1, 1.3.7+build.11.e0f985a.
  12. La priorité DOIT être calculée en séparant les numéros de version, dans l’ordre, en identifiants majeur, mineur, patch, de admissible et de construction. Les numéros de version majeur, mineur, et de patch sont toujours comparés numériquement. Pour les versions admissible et de construction, la priorité DOIT être déterminée en comparant chaque identifiant séparé par un point comme suit : les identifiants composés de chiffres seulement sont comparés numériquement et les identifiants composés de lettres ou de tirets sont comparés dans l’ordre de tri ASCII. Les identifiants numériques précèdent les identifiants non numériques (identifiants numériques < identifiants non-numériques). Exemple : 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-RC.1 < 1.0.0-RC.1+build.1 < 1.0.0 < 1.0.0+0.3.7 < 1.3.7+build < 1.3.7+build.2.b8f12d7 < 1.3.7+build.11.e0f985a.

Dans le vrai monde

Le versionnage sémantique n’est pas la seule façon de donner une identité à une version de votre logiciel. La page dédiée au versionnage logiciel répertorie une multitude de façons d’arriver à cette fin sans utiliser cette façon de faire.

La façon de versionner son logiciel doit être une question débattue au sein de l’équipe de développement. Un bel exemple de ce débat est celui tenu par l’équipe de développement Drupal. La question a été lancée en juin 2012 et il y a eu des échanges jusqu’en février sur ce sujet.

Il est difficile de répertorier les projets utilisant le versionnage sémantique. Toutefois, la façon de nommer les versions n’est pas à prendre à la légère et a beaucoup d’implication pour les contributeurs et utilisateurs.

Après tout, est-ce que de donner un numéro de version qui s’incrémente d’une façon prévisible et logique à travers le temps serait une façon de démontrer qu’un développeur se soucie réellement de ses utilisateurs? Moi, je crois que oui.

Les liens de la semaine – Édition #30

Développement

Web

.NET

Technologie

Autres

Intégration de la révision SVN à son projet Visual Studio 2012

Vous connaissez la pyramide des besoins de Maslow? Comme le dit Wikipédia, il s’agit de la représentation, sous la forme d’une pyramide, de la hiérarchie des besoins. Selon la théorie, vous devez satisfaire les besoins des paliers du bas afin de pouvoir penser au niveau suivant.

Il est important de pouvoir combler ses besoins primaires afin de progresser. L’analogie de la pyramide a permis de définir beaucoup d’aspects de la psychologie de l’humain. Dans beaucoup de cas, vu que l’acte du développement logiciel est aussi fait par des humains, je crois que la même analogie s’applique pour le développement.

Confiance

Le lien de confiance entre un programmeur et son gestionnaire de code source est primordial.

Elle doit faire foi de tout.

Êtes-vous déjà retrouvé dans une situation où vous devez mettre à jour une application en production et de réaliser que ce qui est en ligne n’est pas à jour avec vos changements? Ou même que vous l’avez appris une fois vos changements en production, car votre application est maintenant hors d’usage? Douloureux, n’est-ce pas?

C’est à ce moment que vous devez retourner en arrière et tenter de deviner ce qui s’est passé.

Laisser un indice

Lorsque vous êtes un développeur ASP.NET, comme moi, il n’y a pas beaucoup de mécanismes naturels vous permettant de déterminer la version de votre application. Tout ce que vous avez à portée de main est la taille du fichier DLL principal de votre application web et la date de mise à jour de celle-ci.

Ces données ne vont pas très bien lorsque vous n’êtes pas le seul programmeur sur un projet. Il est très difficile de déterminer ce que contient votre application et qui l’a mis à jour.

C’est à cet instant précis que doit intervenir votre gestionnaire de code source, car il est possible d’extraire la version associée aux changements que vous avez en main, de les incruster à votre projet et de les consulter à partir de votre application.

Dans ce cas-ci, le sujet sera abordé en utilisant SVN. Toutefois, sachez qu’il est possible de le faire avec n’importe quel gestionnaire de code source.

La recette

Premièrement, si vous êtes du type visuel, le projet que j’ai utilisé afin de préparer cet article est accessible ici : https://github.com/pparadis/FrenchCoding.SVNVersionLogger/. La magie va s’opérer uniquement lorsque la solution sera intégrée à un repository Subversion.

Ce que je désire accomplir est de pouvoir enregistrer la révision SVN du moment au moment où le projet sera compilé. Cela sera possible en tirant profit de l’événement précompilation mis à notre disposition. La solution que j’ai trouvée à mon goût assume que vous avez déjà à portée de main une installation de TortoiseSVN. Que vous l’utilisiez ou non, il y a un seul exécutable (SubWCRev.exe) et cinq librairies qui vous seront nécessaires.

SubWCRev.exe permet l’analyse d’un repository SVN et de permettre d’y inscrire certaines informations dans un fichier texte en se basant sur un gabarit qui lui sera fourni. Par exemple, dans le cas qui nous intéresse, nous allons utiliser la valeur $WCREV$ afin de récupérer la révision du jeu de changements que nous avons en main.

Pour arriver à faire cela, voici les étapes :

  1. Copier les fichiers nécessaires pour le fonctionnement de SubWCRev.exe dans votre solution. Moi j’ai utilisé le répertoire /lib/tortoisesvn.
  2. Accéder au panneau de configuration des Build Events et inscrire la ligne suivante dans la boîte de texte Pre-Build event command line$(ProjectDir)lib\tortoise\SubWCRev.exe $(SolutionDir) $(ProjectDir)version.tmpl $(ProjectDir)version.txt.
  3. Compilez votre projet.

Note : L’étape #2 assume que, dans votre projet, il y a un fichier nommé version.tmpl qui contiendra le fichier gabarit pour générer le fichier final.

Au final

Lorsque le projet sera compilé, un fichier version.txt sera créé et mis à jour. Le contenu du fichier sera le suivant : 0-1.0.16-2013/05/05 14:54:37 .

Les informations, qui sont séparées par un trait d’union, permettent de déterminer les informations suivantes :

  1. Est-ce qu’il y avait des informations qui n’avaient pas été soumises au serveur (1 ou 0)
  2. Le numéro de la révision en vigueur lorsque la compilation a eu lieu. Dans ce cas-ci, dans le numéro de version 1.0.16, le 16 est le numéro de révision SVN.
  3. La date de la compilation.

Notez que ces informations ont été inscrites dans un fichier texte brut afin d’être en mesure d’y accéder même lorsque l’application web est hors-ligne. Il est possible d’en générer un fichier AssemblyInfo.cs pour que votre DLL y contienne le numéro de version, par exemple.

Les liens de la semaine – Édition #29

Web

Développement

.NET

Technologie

Science et autres

Suivre

Get every new post delivered to your Inbox.

Join 469 other followers