¿Es una buena práctica almacenar números de versión de software en VCS?

22

Una versión del producto, como v1.0.0.100, representa no solo una versión de producción única de software, sino que ayuda a identificar conjuntos de características y etapas de revisión para dicho producto. En este momento veo dos formas de mantener la versión final de paquete / compilación / binario de un producto:

  1. Control de versiones. Un archivo en alguna parte almacena el número de versión. El servidor de compilación de Integración continua (CI) tendrá un script para compilar el software que utiliza este número de versión registrado para aplicarlo a todas las áreas del software necesario (binarios, paquetes de instalación, páginas de ayuda, documentación, etc.).

  2. Entorno y / o parámetros de construcción. Estos se mantienen fuera del control de versión (es decir, no están vinculados a la instantánea / etiqueta / rama). Los scripts de compilación distribuyen y usan el número de la misma manera, sin embargo, solo obtienen el valor de manera diferente (se proporciona al script de compilación, en lugar de hacer que el script sepa dónde obtenerlo en relación con el árbol de origen).

El problema con el primer enfoque es que puede complicar las fusiones entre las ramas principales. Si aún mantiene 2 versiones paralelas del mismo software, resolverá conflictos al fusionar entre las dos líneas principales si la versión ha cambiado en ambas desde la última fusión.

El problema con el segundo enfoque es la reconciliación. Cuando regrese a un lanzamiento hace 1 año, dependerá únicamente de la información de la etiqueta para identificar su número de lanzamiento.

En ambos casos, puede haber ciertos aspectos del número de versión que no se conocen antes de la compilación de CI. Por ejemplo, una compilación de CI puede poner programáticamente un cuarto componente que es realmente el número de compilación automatizado (por ejemplo, la compilación 140 en la rama). También podría ser un número de revisión en VCS.

¿Cuál es la mejor manera de mantenerse al día con el número de versión de un software? ¿Deben las partes "conocidas" mantenerse siempre en VCS? Y si es así, ¿son un problema los conflictos entre las ramas principales?

En este momento mantenemos nuestro número de versión a través de parámetros especificados y mantenidos en el plan de compilación de CI (Atlassian Bamboo). Debemos tener cuidado antes de fusionarnos con nuestra mastersucursal para que los números de versión estén configurados correctamente antes de que comience la compilación de CI . Con respecto al flujo de trabajo de Gitflow, creo que si se rastrea el número de versión en el control de origen, podríamos garantizar que esté configurado correctamente cuando creamos nuestra releaserama en preparación del lanzamiento. El control de calidad llevaría a cabo la prueba final de integración / humo / regresión en esta rama y, al finalizar la sesión, se realizará una fusión masterque indica el compromiso de liberación.

void.pointer
fuente
3
¿Es un conflicto de fusión entre dos versiones de un archivo version.txtdonde una versión contiene una sola línea 1.0.7y la otra es 1.2.0realmente tan difícil de resolver? Si este es el único conflicto al fusionar dos ramas que se separaron, me consideraría muy afortunado. ¿Con qué frecuencia se presenta? Si ocurre, ¿no es bueno que te veas obligado a pensar qué número de versión debería tener la versión fusionada? (Perdón por el uso ambiguo de la palabra "versión".)
5gon12eder
1
@ 5gon12eder Las dificultades o sentimientos sobre la fusión en sí son irrelevantes. Es solo un aspecto negativo de la solución general.
void.pointer

Respuestas:

28

Personalmente, elijo la opción 3: mantener la información de versiones en metadatos de VCS , específicamente, etiquetas.

Git hace que sea muy fácil hacerlo, porque hay un comando git describe, que puede describir de manera única una confirmación basada en una etiqueta. Así es como funciona:

  • Si la confirmación actual está etiquetada, envíe el nombre de la etiqueta.
  • De lo contrario, caminar hacia atrás las historia hasta que encuentre una etiqueta de salida y luego una descripción en el siguiente formato: <tag>-<number of commits since the tag>-g<abbreviated commit hash>.
  • Si hay cambios no confirmados en el árbol de trabajo, agregue -dirty.

Por lo tanto, si está realizando una compilación de lanzamiento y tiene el compromiso etiquetado 1.2.3, se generará 1.2.3. Si actualmente está trabajando en 1.2.4 y realizó 4 confirmaciones desde 1.2.3, y tiene cambios no confirmados en el árbol, se generará 1.2.3-4-gdeadbee-dirty.

Está garantizado que será único y monótono, además de legible para los humanos, y por lo tanto puede usarse directamente como una cadena de versión. Lo único que debe asegurarse es una convención de nomenclatura adecuada para las etiquetas.

Jörg W Mittag
fuente
Realmente me encanta esta idea, pero parece difícil de manejar con JIRA + Bamboo. Bamboo solo funciona en ramas, no en etiquetas, por lo que debe asegurarse de que se inserte una etiqueta antes de generar una compilación. Esto es propenso a errores.
void.pointer
1
git describetambién funciona con ramas: " --todos - En lugar de usar solo las etiquetas anotadas, use cualquier referencia que se encuentre en el refs/espacio de nombres. Esta opción permite hacer coincidir cualquier rama conocida, rama de seguimiento remoto o etiqueta ligera". Sin embargo, no estoy seguro de cómo funciona esto con Bamboo. (Esto, por supuesto, requerirá nombrar cuidadosamente las ramas, tal como lo hace el modo normal con las etiquetas).
Jörg W Mittag
1
Conozco a algunas personas que hacen lanzamientos completamente automáticos de Git. La cadena de versión está construida por git describe, el ChangeLog se genera a partir de git shortlog(bueno, en realidad a partir de un script que analiza la salida de git log --pretty=tformat:<some custom format string>), y las notas de la versión se generan a partir de la descripción de la etiqueta y se git notesadjuntan a los compromisos importantes.
Jörg W Mittag
Mi punto es que la etiqueta debería crearse antes del lanzamiento para que se confirme después de que se versione correctamente con un número base. Esto va en contra del principio de etiquetado durante o en el momento del lanzamiento. Bamboo recoge las compilaciones automáticamente en función de las confirmaciones de master(desde develop, recuerda que estoy usando gitflow). ¿Qué pasa si alguien empuja una fusión mastersin una etiqueta? No usará la versión adecuada (de hecho, usaría la versión de la última versión)
void.pointer
Si usa un esquema como este, se está liberando el etiquetado . Ah, veo a lo que te refieres, creo. Entonces, actualmente, su servidor CI es el controlador de la versión, y con este cambio, el SCM es el controlador de la versión, pero ¿desea que siga siendo así?
Jörg W Mittag
8

Sí. Es una buena práctica mantener la mayor parte del número de versión en vcs. Si consideramos la versión semántica semver.org donde tenemos major.minor.patch.build, los tres primeros deben vivir en vcs. El último puede ser un número incremental de su servidor de compilación utilizado para dar marcha atrás al commit específico del que está hecho un binario.

Para facilitar esto en .NET, hemos creado un pequeño exe de línea cmd que está comprometido con git. Con un evento previo a la compilación, recoge el número de compilación que teamcity etiquetó durante la compilación. Esta herramienta de línea cmd genera automáticamente una clase con una constante que contiene el número de compilación. El resto del número de versión: major.minor.patch es solo una constante normal en otro archivo. Estos dos archivos compartidos se incluyen en cada ensamblaje en una solución como un enlace (alt + shift-drag).

Este enfoque es lo suficientemente poderoso como para que podamos construir una ciudad de equipo y probar nuestro código. Empuje a azul y haga que kudu lo vuelva a construir, pero con el número de compilación de teamcity como la versión de los dll.

Esben Skov Pedersen
fuente