.net - source - Mejores prácticas/orientación para mantener números de versión de ensamblaje
mejores cms 2019 (5)
Agregando a la respuesta de Bronumskis , quiero señalar que después del estándar Semantic Versioning 2.0 en semver.org , Major.Minor.Build.Revision
sería ilegal debido a la regla de que después de aumentar un número, todos los valores regulares a la derecha tendrían para restablecer a cero.
Una mejor forma de seguir el estándar sería usar Major.Minor+Build.Revision
. Obviamente no se debe usar en AssemblyVersionAttribute
, pero en su lugar se podría usar un atributo personalizado o una clase estática.
Semver en TeamCity debería estar disponible usando el Meta-runner Power Pack. Para git con git-flow (especialmente en el mundo .NET), encontré que GitVersion era útil.
Estoy buscando punteros, sugerencias e incluso dictado sobre cómo administrar los tres números de versión de ensamblaje para un ensamblado de .NET. La versión del Producto es la más simple, ya que esto parece normalmente dictado por las empresas. Luego, la versión del archivo parece ser para versiones entre implementaciones, donde la versión del ensamblaje real solo se usa durante el envío.
En este momento solo estoy buscando un medio simple de etiquetar pruebas y versiones de mantenimiento de un ensamble del cual ninguno dependa, entonces estoy buscando números de compilación y revisión de incremento automático en la versión de archivo, y para la versión final, copiando el actual versión de archivo a la versión de ensamblaje. El producto está en uso de producción, pero todavía está en desarrollo, ya sabe, una de esas pequeñas empresas, sin situaciones de infraestructura de control de cambios.
El control de versiones es algo que me apasiona y he pasado mucho tiempo tratando de crear un sistema de control de versiones fácil de usar. Por lo que ya ha dicho en su pregunta, está claro que ha entendido un punto importante, los números de la versión del ensamblaje no son sinónimos de la versión del producto. Uno es impulsado técnicamente y el otro es impulsado por el negocio.
Lo siguiente supone que utiliza algún tipo de control de origen y un servidor de compilación. Para el contexto usamos TeamCity y Subversion / Git. TeamCity es gratuito para un pequeño (10) número de proyectos y es un muy buen servidor de compilación, pero hay otros, algunos de los cuales son completamente gratuitos.
Lo que significa un número de versión
Lo que una versión significa para una persona puede significar algo diferente a otra, la estructura general es mayor, menor, macro, micro. La forma en que veo un número de versión es dividirlo en dos partes. La primera mitad describe la versión principal (Mayor) y cualquier actualización clave (Menor). La segunda mitad indica cuándo fue construida y cuál fue la versión del código fuente. Los números de versión también significan cosas diferentes según el contexto, es una API, una aplicación web, etc.
Major
. Minor
Build
Revision
-
Revision
Este es el número tomado del control de la fuente para identificar lo que realmente se construyó. -
Build
Este es un número cada vez mayor que se puede utilizar para encontrar una compilación particular en el servidor de compilación. Es un número importante porque el servidor de compilación puede haber construido la misma fuente dos veces con un conjunto diferente de parámetros. Usar el número de compilación junto con el número de origen le permite identificar qué se creó y cómo. -
Minor
Esto solo debería cambiar cuando haya un cambio significativo en la interfaz pública. Por ejemplo, si se trata de una API, ¿el código de consumo podría compilarse? Este número debe restablecerse a cero cuando cambia el número Mayor. -
Major
indica en qué versión del producto estás. Por ejemplo, el Comandante de todos los ensamblados de VisualStudio 2008 es 9 y VisualStudio 2010 es 10.
La excepción a la regla
Siempre hay excepciones a la regla y tendrá que adaptarse a medida que las encuentre. Mi enfoque original se basaba en el uso de la subversión, pero recientemente me he mudado a Git. El control de fuente como la subversión y la fuente segura que usan un repositorio central tienen un número que se puede usar para identificar un conjunto particular de fuentes de un tiempo dado. Este no es el caso para un control de fuente distribuida como Git. Debido a que Git usa repositorios distribuidos que están en cada máquina de desarrollo, no hay un número de incremento automático que pueda usar, hay un truco que usa el número de registros pero es feo. Debido a esto, he tenido que evolucionar mi enfoque.
Major
. Minor
Macro
. Build
El número de revisión se ha ido, la construcción se ha desplazado a donde solía estar la revisión y se ha insertado Macro. Puedes usar la macro como te parezca, pero la mayor parte del tiempo la dejo en paz. Debido a que usamos TeamCity, la información perdida del número de revisión se puede encontrar en la compilación, significa que hay un proceso de dos pasos, pero no hemos perdido nada y es un compromiso aceptable.
Qué configurar
Lo primero que debe entender es que la versión de ensamblaje, la versión de archivo y la versión de producto no tienen que coincidir. No defiendo tener diferentes conjuntos de números, pero hace la vida mucho más fácil cuando se realizan pequeños cambios en un ensamblaje que no afecta a las interfaces públicas que no se ven obligados a recompilar ensamblajes dependientes. La forma en que trato esto es solo establecer los números mayor y menor en la versión de ensamblaje, pero establecer todos los valores en la versión de archivo. Por ejemplo:
- 1.2.0.0 (AssemblyVersion)
- 1.2.3.4 (FileVersion)
Esto le permite implementar soluciones rápidas que no romperán el código existente porque las versiones de ensamblaje no coinciden, pero le permiten ver la revisión / construcción de un ensamblaje al observar el número de versión del archivo. Este es un enfoque común y se puede ver en algunos ensamblajes de código abierto cuando observa los detalles del conjunto.
Usted, como líder del equipo, debería ser responsable de incrementar el número menor cuando se requiera un cambio de ruptura. Una solución para implementar un cambio requerido en una interfaz pero sin romper el código anterior es marcar la actual como obsoleta y crear una nueva interfaz. Significa que se advierte al código existente que el método está obsoleto y se puede eliminar en cualquier momento, pero no es necesario que rompa todo inmediatamente. A continuación, puede eliminar el método obsoleto cuando todo se haya migrado.
Cómo conectarlo juntos
Podrías hacer todo lo anterior de forma manual, pero sería muy lento, la siguiente es cómo automatizamos el proceso. Cada paso es ejecutable.
- Elimine los atributos
AssemblyVersion
yAssemblyFileVersion
de todos los archivos AssemblyInfo.cs del proyecto. - Cree un archivo de información de ensamblado común (llámelo VersionInfo.cs) y agréguelo como un elemento vinculado a todos sus proyectos.
- Añada los atributos
AssemblyVersion
yAssemblyFileVersion
a la versión con los valores de "0.0.0.0". - Cree un proyecto MsBuild que construya su archivo de solución.
- Agregue una tarea antes de la compilación que actualiza VersionInfo.cs. Hay una serie de bibliotecas MsBuild de código abierto que incluyen una tarea AssemblyInfo que puede establecer el número de versión. Simplemente configúralo en un número arbitrario y prueba.
- Agregue un grupo de propiedades que contenga una propiedad para cada uno de los segmentos del número de compilación. Aquí es donde se establece el mayor y menor. El número de compilación y revisión se debe pasar como argumentos.
Con subversión:
<PropertyGroup>
<Version-Major>0</Version-Major>
<Version-Minor>0</Version-Minor>
<Version-Build Condition=" ''$(build_number)'' == '''' ">0</Version-Build>
<Version-Build Condition=" ''$(build_number)'' != '''' ">$(build_number)</Version-Build>
<Version-Revision Condition=" ''$(revision_number)'' == '''' ">0</Version-Revision>
<Version-Revision Condition=" ''$(revision_number)'' != '''' ">$(revision_number)</Version-Revision>
</PropertyGroup>
Espero haber sido claro, pero hay muchas cosas involucradas. Por favor haga cualquier pregunta. Utilizaré cualquier comentario para juntar una publicación de blog más concisa.
La [AssemblyVersion] es un gran negocio en .NET. Una de las filosofías alentadas por Microsoft es que permita que se aumente automáticamente, obligando a recompilar todos los proyectos que dependen del ensamblaje. Funciona bien si usas un servidor de compilación. Nunca es lo incorrecto , pero ten cuidado con las personas que portan espadas.
El otro, más estrechamente asociado con su significado real es que el número es representativo para la versión de la interfaz pública del ensamblado. En otras palabras, solo lo cambia cuando modifica una interfaz o clase pública. Dado que solo tal cambio requiere que los clientes del ensamble sean recompilados. Sin embargo, esto debe hacerse manualmente, el sistema de compilación no es lo suficientemente inteligente como para detectar automáticamente dicho cambio.
Puede ampliar este enfoque aumentando solo la versión cuando el ensamblaje se implementó en máquinas fuera de su alcance. Este es el enfoque que usa Microsoft, sus números de versión de ensambles .NET rara vez cambian. Sobre todo por el gran dolor que causa a sus clientes.
Entonces, lo que Microsoft predica no es lo que practica. Sin embargo, su proceso de compilación y control de control de versiones no tienen paralelo, incluso cuentan con un ingeniero de software dedicado que supervisa el proceso. No funcionó tan bien, la sobrecarga WaitHandle.WaitOne (int) en particular causó una buena cantidad de dolor . Corregido en .NET 4.0 con un enfoque muy diferente, pero eso está un poco más allá del alcance.
Depende de usted y de su confianza en qué tan bien puede controlar el proceso de creación y los ciclos de lanzamiento para hacer su propia elección. Aparte de eso, el auto-incremento de [AssemblyFileVersion] automáticamente es muy apropiado. Sin embargo, la inconveniencia de que esto no es compatible.
No hay una regla rígida cuando se trata de ensambles de versiones, así que siéntete libre de probar cuál funcionaría para ti, pero te sugiero que utilices el enfoque de 4 partes ya que tendrás la flexibilidad en caso de que quieras hacer algunos cambios. en el futuro.
... por ejemplo: 1.0.0. *
Reservado: esto agrega flexibilidad adicional, en caso de que desee realizar algún cambio en el futuro. Pero como predeterminado, mantenlo como 0.
Además, considere firmar el ensamblado con la tecla fuerte. Esto resolverá el problema de conflicto de ensamblaje en caso de que tenga múltiples versiones de ensamblado registradas en el GAC. MSDN Link
Puede usar la parte de compilación del número de versión para autoincrementar.
[assembly: AssemblyVersion("1.0.*")]
En su entorno, una versión de prueba es una versión que tiene una versión de compilación! = 0. Al momento de la publicación, incrementa la parte menor y establece la parte de compilación en 0, así es como identificaría los ensamblados liberados.
Si instala sus ensamblajes en el GAC, su GAC se inundará con muchas versiones diferentes con el tiempo, así que tenga esto en cuenta. Pero si usa los dlls solo localmente, creo que esta es una buena práctica.