No hace mucho tiempo, en uno de los proyectos de nuestra compañía, se decidió finalmente abandonar el uso de Subversion para almacenar y versionar código a favor de Git.
Los principales objetivos de la transición fueron los siguientes:
- Mejora de la transparencia del proceso de desarrollo.
- Implementación del procedimiento de revisión de código obligatorio antes de actualizar las actualizaciones de los entornos de prueba.
- Implemente la integración continua para generar actualizaciones después de la revisión del código e instálelas en entornos de prueba.
Un requisito previo para lograr estos objetivos era el uso de GitLab (este servidor Git ya fue utilizado por el cliente y ya había un código que pertenecía al frente de la solución) y Jira (también ya utilizado por el cliente).
Se propuso utilizar Git Flow como modelo de desarrollo objetivo, agregando un código de revisión. Este modelo de desarrollo de facto se ha convertido en el estándar en el desarrollo de software de código abierto y es utilizado por la mayoría de los gigantes de la industria. Es por eso que su soporte está integrado en muchas herramientas populares para trabajar con Git. Se ha escrito una gran cantidad de materiales sobre el tema de su uso; citaré el más exitoso de ellos para la familiarización inicial: uno y dos .
Por sí mismo, este modelo ofrece solo principios generales de mantenimiento de código, dejando de lado los procesos que acompañan su redacción. Por lo tanto, la implementación de todo lo demás, incluido el código de revisión, depende del servidor Git específico. En este sentido, GitHub es más conveniente: se creó originalmente como una plataforma para la colaboración de un gran número de desarrolladores independientes y le permite limitar los derechos para enviar confirmaciones (Push) en el repositorio con la capacidad de crear solicitudes para enviar código. Además, GitLab ofrece su propio flujo de trabajo para mantener el código llamado GitLab Flow, diseñado para usar GitLab CI. Por lo tanto, en GitLab, la funcionalidad para crear solicitudes de envío de código no está implementada y se propone utilizar solicitudes de fusión de rama para revisar el código de cambio. Para construir e instalar artefactos en el proyecto, Jenkins ya se usó, lo que le permite crear y configurar de manera flexible las tareas de ensamblaje e implementación, y se decidió no cambiar a GitLab CI, rechazando simultáneamente la idea de usar GitLab Flow.
También noto que el proyecto se ha configurado integraciones en Jira y Git. En Jira, en el complemento Git, se agregó un repositorio creado para almacenar el código fuente para el seguimiento, y en GitLab, este repositorio se configuró para integrarse con Jira en la sección "Integraciones" del repositorio.
Para resolver este problema, se desarrolló un flujo de trabajo para trabajar con código que es similar en estructura a Git Flow, pero que permite realizar revisiones de código cada vez que se realizan cambios en las ramas principales del proceso (desarrollo, lanzamiento-n y maestro) usando GitLab. A continuación, se describirá el proceso resultante, así como las etapas de integración continua y entrega de software a las cadenas adyacentes. Entre paréntesis están los comandos correspondientes para ejecutar.
El repositorio creado para almacenar el código fuente se carga en el repositorio local (git clone) y se inicializa Git Flow (git flow init), además de la rama maestra (para crear etiquetas para almacenar versiones estables), se crea la rama de desarrollo (la rama de desarrollo principal, en que integra ramificaciones de funciones, lanzamientos y arreglos), se establecen máscaras para ramificaciones de funciones, lanzamientos y arreglos, y también se realiza una transición a la ramificación de desarrollo.
A continuación, la rama del código fuente actual de Subversion se transfiere a la copia de trabajo, el código se confirma (git add -A + git commit -m "Mensaje de confirmación") a la rama de desarrollo del repositorio local y su carga al repositorio remoto (desarrollo de origen de inserción de git). Después de eso, puede comenzar a desarrollar una nueva funcionalidad usando Git para versionar el código.
Durante el desarrollo, se descarga la versión actual de la rama de desarrollo y se crean ramas para desarrollar nuevas funciones (función de flujo de git, iniciar MYFEATURE) de acuerdo con los códigos de tareas de Jira dentro de los cuales se lleva a cabo el desarrollo.
Se realiza automáticamente una transición a la rama creada (git checkout MYFEATURE), se desarrolla la funcionalidad planificada y los cambios se confirman en la rama local MYFEATURE (git commit -m "Mensaje de compromiso"). Tenga en cuenta que para la correcta integración de Git y Jira, el código de confirmación en Jira al que se aplica esta corrección debe indicarse en los mensajes de confirmación. Luego, estos commits se mostrarán en las tareas correspondientes, así como en la sección "Git commits" del proyecto, con la ayuda de la cual puede determinar inequívocamente qué se incluye en un lanzamiento en particular.
Cuando la funcionalidad de la tarea seleccionada se desarrolla y está lista para enviarse al entorno de prueba, los commits creados se cargan en la rama remota con el mismo nombre (git push -u origin MYFEATURE) y se realiza una solicitud para fusionar la rama descargada con la rama de desarrollo al líder del equipo o sus funciones de actuación.

Para solicitar una fusión, el desarrollador resuelve conflictos de fusión (si los hay) y el líder del equipo de desarrollo (o que actúa) produce una revisión del código, durante el cual es posible crear confirmaciones adicionales (git commit -m "Mensaje de confirmación") con correcciones a los comentarios recibidos durante la revisión de código, en una rama con nueva funcionalidad y enviándolas al repositorio central (git push -u origin MYFEATURE). Después de completar con éxito la revisión, el líder del equipo (o la actuación) confirma la fusión de las sucursales. Aquí no es superfluo establecer la bandera para eliminar la rama después de la fusión; de lo contrario, el número de ramas puede crecer rápidamente a escalas indecentes.
Para garantizar una integración continua en el repositorio de GitLab, se configura un Web Hook en la sección "Integraciones", que llama a las tareas de Jenkins para construir e instalar nuevas funcionalidades en el entorno de prueba. Jenkins, utilizando un complemento para trabajar con Git, descarga el código fuente, obtiene el nombre de la tarea y utiliza la API de Jira para solicitar una lista de componentes que se han cambiado y deben ensamblarse, iniciar el proceso de compilación, ejecutar las pruebas unitarias y cargar los artefactos creados si pasan con éxito en Sonatype Nexus y los instala en un entorno de prueba. Si en una de las etapas ocurre una falla o fallan las pruebas de la Unidad, entonces, con la ayuda del complemento de Telegram, se informa al equipo de desarrollo sobre el resultado de la compilación. Si la instalación se realizó correctamente, se notifica al equipo de control de calidad que la tarea está lista para la prueba.
Si aparecen defectos, se descarga la versión actual de la rama de desarrollo y desde la confirmación de fusión de la rama MYFEATURE con la rama de desarrollo se crea la rama hotfix-MYFEATURE (git checkout [BASECOMMIT] -b hotfix-MYFEATURE).
Al crear, se realiza un pago automático a la rama creada, se realizan correcciones y los cambios se confirman en la rama local hotfix-MYFEATURE (git commit hotfix-MYFEATURE -m "Confirmar mensaje"). Cuando se completa la corrección y está lista para enviarse al entorno de prueba, se envían a una rama remota con el mismo nombre (git push -u origin hotfix-MYFEATURE) y se crea una solicitud de fusión con la rama de desarrollo.

Para solicitar una fusión, el desarrollador resuelve los conflictos de fusión (si corresponde) y realiza una revisión del código, durante el cual es posible crear confirmaciones adicionales con correcciones a los comentarios recibidos. Una vez que la revisión se completa con éxito, las ramas se fusionan. Inmediatamente después de que el parche se transfiere a la rama de desarrollo, el Web Hook también funciona para llamar a la tarea en Jenkins para construir, ejecutar pruebas unitarias, cargar los artefactos creados en Sonatype Nexus e instalar el parche en el entorno de prueba. Un mecanismo de notificación similar funciona para las correcciones.
Si se solucionan todos los defectos, se descarga la versión actual de la rama de desarrollo y desde la confirmación de fusión de la rama hotfix-MYFEATURE a la rama de desarrollo, se crea la rama release-mn (git flow release start RELEASENAME [BASECOMMIT]).

La creación de una rama de lanzamiento también inicializa el lanzamiento de un Web Hook para llamar a una tarea en Jenkins, que descarga el código fuente de Git, obtiene el nombre de la rama de lanzamiento y, utilizando la API de Jira, consulta la lista de componentes que se modificaron como parte de las tareas de lanzamiento, descarga las versiones actuales de Sonatype Nexus y los establece en un entorno de prueba de regresión. Después de la instalación de la versión en el entorno de prueba de regresión, se ejecutan scripts para preparar el entorno para la prueba (reinicio de la aplicación, limpieza de la base de datos, etc.) y las pruebas automáticas de regresión se ejecutan para verificar el funcionamiento de la funcionalidad del sistema principal, lo que da como resultado un informe utilizando el complemento Allure Reports para Jenkins. Después de la instalación, el equipo de control de calidad recibe una notificación en Telegram sobre los resultados de la ejecución de la prueba automática y la disponibilidad de la versión para la prueba de regresión manual.
Si aparecen defectos durante la prueba de regresión, la versión actual de la rama release-mn se descarga y, desde la última confirmación, la rama hotfix / BUGNAME se crea con el nombre del defecto en Jira (git checkout -b hotfix / BUGNAME [BASECOMMIT]).
Se realiza un pago automático en la rama creada, se realizan las correcciones necesarias y los cambios se confirman en la rama local hotfix / BUGNAME (git commit hotfix / BUGNAME -m "Confirmar mensaje"). Cuando se completa la corrección y está lista para enviarse al entorno de prueba de regresión, se envían a una rama remota con el mismo nombre (git push -u origin hotfix / BUGNAME) y se crea una solicitud de fusión con la rama release-mn

Para solicitar una fusión, el desarrollador resuelve los conflictos de fusión (si corresponde) y realiza una revisión del código, durante el cual es posible crear confirmaciones adicionales con correcciones a los comentarios recibidos durante la revisión del código. Estas confirmaciones también se realizan en la rama local hotfix / BUGNAME (git commit hotfix / BUGNAME -m "Commit message") y se envían a una rama remota con el mismo nombre (git push -u origin hotfix / BUGNAME). Una vez que la revisión se completa con éxito, las ramas se fusionan. La fusión inicializa el lanzamiento de Web Hook para llamar a la tarea en Jenkins, similar a la anterior, pero diferente en que descarga el código de Git, obtiene el nombre del defecto, usa la API de Jira para solicitar una lista de componentes que se han cambiado como parte de la solución, recopilar estos componentes, descarga a Sonatype Nexus y los instala en un entorno de prueba de regresión. Además, por analogía, el entorno está preparado para la auto-evaluación, se ejecutan las auto-pruebas de regresión y se notifican sus resultados.
Cuando se reparan todos los defectos, la versión se instala en un entorno productivo. Para hacer esto, combine la rama release-mn con las ramas desarrollada y maestra, y también cree una etiqueta de lanzamiento.
Cuando se crea, inicializa el lanzamiento de Web Hook para llamar a la tarea en Jenkins, que descarga el código fuente de Git, obtiene el número de versión y, utilizando la API de Jira, solicita una lista de tareas que se incluyeron en la versión y los componentes que se modificaron como parte de estas tareas, después de que bombea la versión actual de los artefactos de Sonatype Nexus y los instala en un entorno productivo.
Con las revisiones para las ventas, se decidió utilizar un proceso similar al lanzamiento; de lo contrario, las etapas de prueba de los cambios realizados se perderán.
Al implementar el proceso, también se realizó capacitación para empleados que no tenían experiencia trabajando con Git y GitLab, para lo cual se desarrolló un programa de capacitación adecuado. Con él, usted mismo podrá impartir capacitación sobre el uso de Source Tree e Intellij IDEA para trabajar con Git, así como con GitLab para realizar revisiones de código. En el próximo post le daré, complementando con ilustraciones.