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, desde DEV a QA, fusionamos la master
rama qa
y lanzamos una nueva compilación de QA (que luego se implementa automáticamente en el entorno de QA).
Estamos considerando pasar a un nuevo proceso que eliminaría tener una sucursal dedicada y construir para cada entorno. En cambio, una versión de lanzamiento única 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; más bien, simplemente tomamos los binarios ya construidos (el "paquete de implementación") y los colocamos 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 deshacer 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 se encuentra en qué entorno. Si necesitamos hacer una corrección en PROD, ya no tenemos una rama dedicada sincronizada con la base de código de producción actual. Lo mismo ocurre con el control de calidad: si queremos impulsar un cambio rápido al control de calidad sin desenterrar el trabajo en curso master
, ya no tenemos una rama que refleje el estado actual del entorno de control de calidad.
¿Cómo podemos hacer un seguimiento de qué código hay en cada entorno?
Algunas opciones que estamos considerando:
- utilizando etiquetas git para realizar un seguimiento de qué confirmación se encuentra en qué entorno
- incrustando el git commit utilizado por la compilación en cada paquete de implementación
fuente
Respuestas:
Las etiquetas Git son lo que realmente quieres usar para designar lanzamientos. La razón es que tienen 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 "oye, aquí está el implementado
.[wje]ar
en el servidor, ¿de qué compilación vino?" Sabemos que nunca tendrá diferentes versiones de la aplicación implementadas 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. Viniendo de un ejemplo de maven y svn que tengo delante de mí:
Eso está en la configuración del archivo de plugin 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:
que establece esos define que luego recoge Maven. Y luego es solo una cuestión de buscar en el archivo MANIFEST.MF que se ha implementado en el servidor para ver qué versión es.
Hay un complemento git que ofrece un conjunto similar de variables de entorno que incluyen:
GIT_COMMIT
- SHA de la corrienteGIT_BRANCH
- Nombre del repositorio remoto (predeterminado en origen), seguido del nombre de la sucursal que se está utilizando actualmente, por ejemplo, "origen / maestro" u "origen / 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 significado, a diferencia de las sumas de verificación sha) y el compromiso específico de git a partir del cual se construye.
fuente
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 el trabajo en progreso : pero no activado.La diferencia solo se reduce a diferentes conjuntos de características que se habilitan en su producto.
La desactivación / activación se realiza a través de alternar funciones .
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 ramas adicionales.No hay problemas con las funciones de fusión juntas, porque: no hay ramas, no es necesario fusionarlas. No hay confusión sobre qué característica es de qué rama y tal vez dependa o choque con características de otras ramas. Cada parte podría activarse a voluntad. Incluso una reversión ya no es necesaria: es solo un interruptor .
No sé, si eso funciona para su base de código: los requisitos previos en términos de calidad del código y disciplina del desarrollador son bastante altos: tiene que lidiar con la "limpieza" después de que una característica se convierta en una funcionalidad central y tenga que administrar un montón de conmutadores previniendo un desastre mayor .
Quizás te funcione.
fuente
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 / version para servicios web.
fuente