La mayoría de los proyectos dependen de un un número amplio de librerías externas en las que apoyan su desarrollo, incluso es posible modular los proyectos en diferentes librerías para que el mantenimiento de las partes sea independiente o utilizable por otros proyectos. Así que en todo momento la información de las actualizaciones o cambios sobre estos fuentes deberá ser lo mas precisa posible. Como primera referencia se suele utilizar el número de versión, prácticamente todo el software tiene su número versión, en la forma v1.0.0, 2.3.1, v0.4.2, etc… este número de versión se suele desgranar en tres partes X.Y.Z . A través de estos índices podemos saber que ha cambiado en el software del que depende nuestro proyecto, y saber si nos va a traer problemas, o no, su actualización. Para ello se propone seguir las reglas especificadas en semver.org

Versionado

Se propone un sistema de reglas y requisitos para controlar y comprender como crece el número de versión en cada actualización, este sistema depende de tener una API publica, una documentación bien redactada o a través del propio código como podría ser con PHPDoc. El número de versión en su forma más común se suele desgranar en tres partes X.Y.Z .

  • X Versión Mayor (Mayor version)
  • Y Versión Menor (Minor version)
  • Z Versión Parche (Patch version)

En este contexto se define que la corrección de un Bug que no afecta a dicha API es un incremento de la Patch version (Versión parche), si es un cambio evolutivo que no afecta de ninguna manera a la API previa existente (es compatible), lo declararemos como un incremento de la version menor. Y, finalmente, todos los cambios que implican un cambio de la API pública previa implican un incremento de la versión mayor.

En semver.org se escribe una especificación para entender y seguir el versionado semántico, me permito resumirla un poco aquí en castellano:

  1. El software que utiliza versionado semántico debe tener declarar una API pública, en forma de documentación estricta o descrita en los propios fuentes.

  2. Un número de versión debe tomar la forma X.Y.Z donde X, Y y Z deben ser números enteros positivos sin ceros precedentes. X es la versión mayor, Y es la versión menor y Z se considera la versión parche. Cada número se incrementará aritméticamente.

  3. Una vez generado el paquete correspondiente a una versión, este no deberá modificarse jamás, para ello se creará una nueva versión que corrija la anterior.

  4. La versión mayor 0.Y.Z se reserva para el desarrollo inicial. Puede cambiar cualquier cosa en cualquier momento, la API no debe considerarse estable.

  5. La versión 1.0.0 requiere la documentación de la API. La forma en que evoluciona el número de versión dependerá de la API pública y de como esta evoluciona.

  6. Una vez pasada la primera versión mayor, X > 0, la versión parche Z solo será incrementada en caso de corregirse comportamientos incorrectos de forma compatible con la API existente, “Bug fix”.

  7. Una vez pasada la primera versión mayor, X > 0, la versión menor será obligatoriamente incrementada al añadir nuevas funcionalidades que no rompen la compatibilidad con la API existente, también incrementará al pasar cualquier funcionalidad ya existente a deprecated. Debería ser incrementado al añadir modificaciones sustanciales en la parte privada del código. Deberá incluir los cambios de los parches previos. El índice de versión parche será seteado a 0 cada vez que se incrementa el índice de versión menor.

  8. Una vez pasada la primera versión mayor, X > 0, se incrementará la versión mayor cuando se introduzcan cambios que afectan a la compatibilidad con la API existente. Deberá incluir los cambios de las versiones menores y parche anteriores. Al cambiar la versión mayor tanto la versión menor como la versión parche deberán ser reseteadas a 0.

  9. Una pre-release deberá ser indicada añadiendo un guión a la versión parche y especificando un identificador pre-release mediante caracteres alfanuméricos (o guiones) separados por puntos. Los identificadores no deben estar vacíos y en caso de ser numéricos no deberán tener ceros iniciales. Estas versiones son consideradas inestables ya que pueden no cumplir la especificación esperada de la API, así que se tratan como versiones precedentes a la versión que define el número de versión de la etiqueta pre-release. Así la versión 1.0.0-alfa es precedente a la 1.0.0 y se asume que puede no cumplir la especificación de la versión 1.0.0 . Ejemplos: 1.0.0-alpha, 1.0.0-alpha.1, 1.0.0-0.3.7

  10. Las variaciones en los metadatos del build del proyecto pueden ser denotados en la versión añadiendo un símbolo más (+) y una serie de caracteres ( alfanuméricos y guión ), tanto a una versión como a una pre-release. Los identificadores no deben estar vacíos. Esta información de los metadatos del build no debe ser considerada a la hora de calcular la precedencia. Dos versiones con distinta información de metadatos de build tienen la misma precedencia. Ejemplos: 1.0.0-alpha+001, 1.0.0+20130313144700

  11. La precedencia se refiere a como se comparan las versiones cuando son ordenadas. Para realizar el cálculo la versión debe ser separada por sus partes, mayor, menor, parche y pre-release en este orden (Los metadatos del build no influyen en este cálculo) . La precedencia se determina comparando las versiones numéricamente de izquierda a derecha y en caso de haber una pre-release su precedencia sera más baja. Por ejemplo 1.0.0-alpha < 1.0.0 < 2.0.0 < 2.1.0 < 2.1.1. La parte de la versión de la etiqueta pre-release será comparada de la misma manera, se leen los identificadores separados por puntos de izquierda a derecha, los índices numéricos se comparan aritméticamente y los alfanuméricos según su orden dentro de la clasificación ASCII, los números van antes que las letras y los identificadores de pre-release mas largos (en caso de coincidir enteramente con la parte inicial de otro) tendrán un orden de precedencia mas alto que los mas cortos. Ejemplo 1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0-rc.1 < 1.0.0

Seguir el standard nos evitará problemas a la hora de mantener las librerías requeridas por nuestros proyectos, de esta manera evitaremos entrar en el infierno de las dependencias. Mantener una buena documentación, empezando por el propio código, nos ayudará a llevar una buena progresión de versiones, entendible por todos aquellos que estén utilizando nuestros paquetes. Os animo a echar un ojo al documento completo, semver.org .