¿Cómo podemos hacer un seguimiento de qué versión de nuestro código hay en cada entorno?

14

Mi equipo actualmente utiliza un proceso de ramificación / implementación bastante simple que se ve así:

                ┌────────┐ ┌────┐ ┌──────┐
 Environments:  │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Builds:        │  DEV   │ │ QA │ │ PROD │
                └────────┘ └────┘ └──────┘

                     ▲       ▲       ▲
                     │       │       │

                ┌────────┐ ┌────┐ ┌──────┐
 Branches:      │ master │ │ qa │ │ prod │
                └────────┘ └────┘ └──────┘

Cada entorno tiene su propia rama (usamos git ) y su propia compilación que usa esa rama. Cuando queremos promover de un entorno a otro, por ejemplo, de DEV a QA, fusionamos la rama master en qa y lanzamos una nueva compilación de QA (que luego se implementa automáticamente en el entorno de QA). / p>

Estamos considerando pasar a un nuevo proceso que eliminaría tener una sucursal dedicada y construir para cada entorno. En su lugar, una única compilación de lanzamiento crearía un "paquete de implementación" que luego podría implementarse en cualquier entorno. Estamos imaginando que un flujo de trabajo típico se vería así:

                ┌────────┐     ┌────┐     ┌──────┐
 Environments:  │  DEV   │ ──► │ QA │ ──► │ PROD │
                └────────┘     └────┘     └──────┘

                      ▲ 
                       \ 

                        ┌───────────────┐
 Builds:                │ release build │
                        └───────────────┘

                                ▲
                                │

                ┌────────┐ ┌─────────┐
 Branches:      │ master │ │ release │
                └────────┘ └─────────┘

La promoción de un entorno a otro ya no se manejaría en el control de origen; en lugar de eso, simplemente tomaríamos los binarios ya creados (el "paquete de implementación") y los colocaríamos en el nuevo entorno.

Este nuevo sistema nos permitiría implementar cualquier compilación en cualquier entorno, lo que tiene varias ventajas. Por ejemplo, es trivial probar las correcciones de errores de PROD en DEV y QA. Nuestro sistema actual no proporciona una manera fácil de hacer esto sin revertir una rama, lo que obviamente nos gustaría evitar.

El mayor inconveniente de este nuevo sistema es que ya no tenemos una forma automática de rastrear qué código está en qué entorno. Si necesitamos hacer una corrección en PROD, ya no tenemos una rama dedicada en sincronización con el código base de producción actual. Lo mismo ocurre con el control de calidad: si queremos impulsar un cambio rápido al control de calidad sin mejorar el trabajo en progreso desde master , ya no tenemos una rama que refleje el estado actual del entorno de control de calidad.

¿Cómo podemos realizar un seguimiento del código en cada entorno?

Algunas opciones que estamos considerando:

  • utilizando git tags para realizar un seguimiento de qué compromiso está en qué entorno
  • incrustar el compromiso git utilizado por la compilación en cada paquete de implementación
pregunta Nathan Friend 06.11.2015 - 22:58

3 respuestas

14

Las etiquetas Git son lo que realmente quieres usar para designar lanzamientos. La razón es que tienen un significado para usted y se pueden usar para reconocer rápidamente el vínculo entre el código implementado por el estado y cualquier información que pueda tener el servidor de compilación (como el número de compilación).

Si bien esa es la respuesta que está buscando, solo resuelve la mitad del problema. El otro es "hey, aquí está el .[wje]ar desplegado en el servidor, ¿de qué compilación proviene?" Sabemos que nunca tendrás diferentes versiones de la aplicación implementada en dev y qa o prod. Derecho?

La solución a esa parte de la pregunta es hacer que el servidor de compilación ponga la información en el manifiesto. Proveniente de un ejemplo de maven y svn que tengo frente a mí:

<manifestEntries>
    <Specification-Title>${project.name}</Specification-Title>
    <Specification-Version>${project.version}</Specification-Version>
    <Build-Number>${build.number}</Build-Number>
    <Build-Id>${build.id}</Build-Id>
    <Svn-Revison>${svn.revision}</Svn-Revison>
</manifestEntries>

Eso está en la configuración de archivo de maven-war-plugin. Pero también puedes encontrarlo en otros complementos. Luego, en Hudson, parte de la invocación de compilación de Maven es:

-Dbuild.number=${BUILD_NUMBER}
-Dsvn.revision=${SVN_REVISION}
-Dbuild.id=${BUILD_ID}

que establece esas definiciones que luego recoge Maven. Y luego solo es cuestión de buscar en el archivo MANIFEST.MF que se implementó en el servidor para ver qué versión es.

Hay un git plugin , que ofrece un conjunto similar de variables de entorno que incluyen:

  • GIT_COMMIT - SHA de la actual
  • GIT_BRANCH : nombre del repositorio remoto (predeterminado al origen), seguido del nombre de la rama que se está utilizando actualmente, por ejemplo, "origin / master" o "origin / foo"

La combinación de estas dos prácticas le permite identificar fácilmente la compilación (porque los números de compilación avanzan y tienen un significado, a diferencia de las sumas de comprobación de sha) y el compromiso git específico del que está compilada.

    
respondido por el user40980 06.11.2015 - 23:24
3

Un enfoque completamente diferente sería descartar la idea de versions completamente. Solo tiene "una versión" que tiene un comportamiento configurable diferente. La única diferencia sería que tiene una base de código común, incluso en producción, desplegaría work in progress : pero no está activado.

La diferencia solo se reduce a diferentes conjuntos de funciones habilitadas en su producto.

La activación / desactivación se realiza a través de características alternas .

Al revés: todo el proceso de lanzamiento se simplifica: siempre está entregando una versión integrada de su software. Cada característica está siempre disponible en master . No se necesitan sucursales adicionales.

No hay dolor con la combinación de características, porque: no hay ramas que no sean necesarias para fusionar. No hay confusión sobre qué característica está en qué rama y tal vez dependa o se oponga a las características de otras sucursales. Cada parte podría ser activada a voluntad. Incluso una reversión ya no es necesaria: solo es un cambio de botón .

No sé, si eso funciona para su base de código: los requisitos previos en cuanto a la calidad del código y la disciplina del desarrollador son bastante altos: tiene que lidiar con la "limpieza" después de que una función se convierte en < em> funcionalidad principal y tienes que administrar un montón de alternar para evitar un lío más grande.

Tal vez funcione para ti.

    
respondido por el Thomas Junk 07.11.2015 - 12:44
-1

Usamos maven para poner la versión en el archivo de manifiesto. Luego, haga que la aplicación muestre la versión si es una aplicación web, o tenga un punto final de / versión para servicios web.

    
respondido por el Josh Chappelle 11.11.2015 - 01:35