Gestión de Código Fuente

# MODELO CASTOR DE GESTIÓN DE CÓDIGO FUENTE Y ESTRATEGIA DE BRANCH

El modelo de gestión propuesto para el equipo Castor estará basado en la metodología Git flow, que como su nombre indica, es un flujo de trabajo aplicado a un repositorio Git.

Vincent Driessen fue el encargado de popularizarlo, definiendo un modelo estricto de ramificación diseñado en torno a los lanzamientos del proyecto.

Es ideal para proyectos que lleven una planificación de entregas iterativas. Permite la paralelización del desarrollo mediante ramas independientes para la preparación, mantenimiento y publicación de versiones del proyecto así como soporta la reparación de errores en cualquier momento.

En resumen, al elegir GIT Flow, encontraremos dos herramientas de trabajo:

* Una modelo que brinda un mayor control y organización en el proceso de integración continua.
* Una extensión (incluida en GIT) que contiene un conjunto de comandos que simplifican el trabajo desde la consola.

El flujo de trabajo con Git Flow nos ayuda a organizar el repositorio y nuestro trabajo. Se establece un convenio de nombres para nuestras ramas que permite a todos los miembros del equipo saber qué es cada cosa. Además, establece unas reglas comunes a la hora de mover la información de una rama a otra.

Disponemos de un conjunto de comandos que nos ahorra tiempo. En este enlace puedes ver una comparación entre los comandos de GitFlow y lo que realmente se ejecuta por debajo.

## Ramas en Git Flow

En cuanto a la política de ramas, Git Flow propone:

*Master* como rama principal del proyecto. Contiene el código de producción. NUNCA trabajaremos sobre ella. De esta rama no nace ninguna excepto los hotfix.

*Develop* como rama de desarrollo. NUNCA trabajaremos sobre ella. De esta rama nacen todas las ramas de feature. La rama develop se mergeará con master cuando vayamos a desplegar el proyecto a través de las releases.

*Feature* serán las ramas sobre las que trabajaremos normalmente. Llevan por defecto el prefijo feature/ seguido del nombre de la rama (ej: feature/add-event-cpt). Nacen SIEMPRE desde la rama develop y mueren cuando son mergeadas.

*Hotfix* son las ramas que utilizaremos para corregir errores críticos encontrados en producción. Llevan el prefijo hotfix/ seguido del nombre de la rama (ej: hotfix/fix-form-submit). Nacen SIEMPRE desde la rama master y se mergean contra master y develop, con el objetivo de poner el hotfix en producción y que también esté disponible para nuevos evolutivos en la rama de desarrollo.

*Release* son las ramas que utilizaremos para crear nuevas versiones para desplegar a producción. Llevan el prefijo release/ seguido del número de versión. Es el mecanismo a través del cual mergeamos los nuevos desarrollos que tenemos en develop contra master. Es recomendable utilizar SemVer para los números de versión.

*Bugfix* son ramas que se utilizan para corregir errores que aún no han llegado a producción. Llevan el prefijo bugfix/ seguido del nombre de la rama (ej: bugfix/fix-wrong-logout-link). Nacen SIEMPRE desde la rama develop.

## Esquema de versionamiento

**Nomenclatura:**

**V**<*versión mayor*>.<*versión menor*>.<*parche/fix*>

*Versión mayor*: se utiliza para denotar la versión principal y es afectada sólo cuando hay una adición mayor de funcionalidades o un cambio tecnológico de base tecnológica.

*Versión menor*: Se utiliza cuando completamos requerimientos representados en historias de usuario.

*Parche/fix*: Se utiliza para identificar cambios realizados con el propósito de corregir errores identificados en el software publicado en producción.

## Repositorios de código fuente

**Nomenclatura:**

**Propietario.**<*nombre del proyecto*>.<*nombre del recurso*>

*Propietario*: se utiliza para denotar el nombre del propietario del proyecto.

*Nombre del proyecto*: se utiliza para denotar el nombre del proyecto.

*Nombre del recurso*: se utiliza para denotar el recurso que el código despliega, se recomienda dar un enfoque basado en los grupos de recursos que componen una solución de software, algunos ejemplos son:

* *IaaC*: Infraestructura como código, si la infraestructura del proyecto está en nube, en este repositorio van los archivos (yml o arm) que definen y despliegan la infraestructura del proyecto.
* *DataBase*: Contiene los scripts DML (Data Modeling Languages) y DDL (Data Definition Language) que permiten la creación de la base de datos.
	+ *DML*: Sentencias que crean, editan y eliminan tablas, vistas, índices, procedimientos almacenados, etc.
	+ *DDL*: Sentencias que permiten consultar, insertar, actualizar, editar y eliminar registros.
* *BackEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de backend, es recomendable aislarlo del código de frontend.
* *FrontEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de frontend, es recomendable aislarlo del código de backend.
* *Mobile*: Código fuente del  cliente móvil.
* *WebApp*: Código fuente del cliente Web.
* *Report*: Código o archivos de definición de reportes, por ejemplo cuando se usan herramientas externas de reporteo como Tableau, Power BI, etc. y que hacen parte de la solución.

## Pipelines CI/CD

### BUILD (Azure Devops) / Continuous Integration (Github)

**Nomenclatura:**

<*nombre del proyecto*>-<*nombre del recurso*>-CI

*Nombre del proyecto*: se utiliza para denotar el nombre del proyecto.

*Nombre del recurso*: se utiliza para denotar el recurso que el código despliega, se recomienda dar un enfoque basado en los grupos de recursos que componen una solución de software, algunos ejemplos son:

* *IaaC*: Infraestructura como código, si la infraestructura del proyecto está en nube, en este repositorio van los archivos (yml o arm) que definen y despliegan la infraestructura del proyecto.
* *DataBase*: Contiene los scripts DML (Data Modeling Languages) y DDL (Data Definition Language) que permiten la creación de la base de datos.
	+ *DML*: Sentencias que crean, editan y eliminan tablas, vistas, índices, procedimientos almacenados, etc.
	+ *DDL*: Sentencias que permiten consultar, insertar, actualizar, editar y eliminar registros.
* *BackEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de backend, es recomendable aislarlo del código de frontend.
* *FrontEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de frontend, es recomendable aislarlo del código de backend.
* *Mobile*: Código fuente del  cliente móvil.
* *WebApp*: Código fuente del cliente Web.
* *Report*: Código o archivos de definición de reportes, por ejemplo cuando se usan herramientas externas de reporteo como Tableau, Power BI, etc. y que hacen parte de la solución.

### Release (Azure Devops) / Deployment (Github)

**Nomenclatura:**

*<nombre del proyecto>-<nombre del recurso>-<versionado>-CD*

*Nombre del proyecto*: se utiliza para denotar el nombre del proyecto.

*Nombre del recurso*: se utiliza para denotar el recurso que el código despliega, se recomienda dar un enfoque basado en los grupos de recursos que componen una solución de software, algunos ejemplos son:

* *IaaC*: Infraestructura como código, si la infraestructura del proyecto está en nube, en este repositorio van los archivos (yml o arm) que definen y despliegan la infraestructura del proyecto.
* *DataBase*: Contiene los scripts DML (Data Modeling Languages) y DDL (Data Definition Language) que permiten la creación de la base de datos.
	+ DML: Sentencias que crean, editan y eliminan tablas, vistas, índices, procedimientos almacenados, etc.
	+ DDL: Sentencias que permiten consultar, insertar, actualizar, editar y eliminar registros.
* *BackEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de backend, es recomendable aislarlo del código de frontend.
* *FrontEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de frontend, es recomendable aislarlo del código de backend.
* *Mobile*: Código fuente del  cliente móvil.
* *WebApp*: Código fuente del cliente Web.
* *Report*: Código o archivos de definición de reportes, por ejemplo cuando se usan herramientas externas de reporteo como Tableau, Power BI, etc. y que hacen parte de la solución.

*Versionado*: Versionado parametrizado en la plataforma para cada vez que se ejecuta un pipeline de CD.

## Library (Azure Devops) / Deploy keys and Secrets (Github)

**Nomenclatura:**

*<ambiente>* versión*:<versión> <nombre del recurso>*

*Ambiente*: Denota el ambiente al ambiente al cual pertenecen los datos consignados en las variables.

*Versión*: Versión de la solución a la cual pertenecen los datos consignados en las variables.

*Nombre del recurso*: se utiliza para denotar el recurso que el código despliega, se recomienda dar un enfoque basado en los grupos de recursos que componen una solución de software, algunos ejemplos son:

* *IaaC*: Infraestructura como código, si la infraestructura del proyecto está en nube, en este repositorio van los archivos (yml o arm) que definen y despliegan la infraestructura del proyecto.
* *DataBase*: Contiene los scripts DML (Data Modeling Languages) y DDL (Data Definition Language) que permiten la creación de la base de datos.
	+ *DML*: Sentencias que crean, editan y eliminan tablas, vistas, índices, procedimientos almacenados, etc.
	+ *DDL*: Sentencias que permiten consultar, insertar, actualizar, editar y eliminar registros.
* *BackEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de backend, es recomendable aislarlo del código de frontend.
* *FrontEnd*: En caso de que la tecnología de desarrollo permite una clara separación del código de frontend, es recomendable aislarlo del código de backend.
* *Mobile*: Código fuente del  cliente móvil.
* *WebApp*: Código fuente del cliente Web.

*Report*: Código o archivos de definición de reportes, por ejemplo cuando se usan herramientas externas de reporteo como Tableau, Power BI, etc. y que hacen parte de la solución.

## Ejemplo Aplicado

##### Caso de estudio

Utilicemos un ejemplo aplicado para demostrar el uso de los conceptos anteriormente definidos, lo haremos con un proyecto llamado beyondGIT.

Utilicemos una aplicación con una arquitectura de componentes sencilla, en la cual el desarrollo del FrontEnd móvil será independiente del desarrollo web.

1. Un navegador o una aplicación móvil realizan solicitudes de recursos vía API.
2. Las solicitudes se transmiten mediante HTTPS y son gestionadas por Azure App Services (backend)
3. La Azure App Services administra las solicitudes de API y puede ser escalado vertical u horizontalmente para manejar los cambios en la demanda.
4. Una Azure Database for MySQL proporciona un servicio de base de datos relacional con la tecnología de la edición comunitaria de MySQL, configurada en modo de implementación de servidor flexible para habilitar el escalado de su base de datos.

##### Definición de los repositorios

Definimos los repositorios de código según los componentes de la solución.

Acorde a lo definido anteriormente tendremos los siguientes repositorios de código fuente asociados a este proyecto:

* Castor-beyondGIT-DataBase-DML (Tablas, índices, triggers, etc.)
* Castor-beyondGIT-DataBase-DDL (Insert, update, delete,)
* Castor-beyondGIT-Backend
* Castor-BeyondGIT-Frontend-Mobile
* Castor-BeyondGIT-Frontend-Web

Continuemos el ejercicio asumiendo que vamos a trabajar en el repositorio FrontEnd

Recordemos que GitFlow es tanto una metodología como un Framework de trabajo que en clientes windows ya viene incluido en el instalador y que para su instalación en Linix y Mac requiere de la ejecución de unos pasos adicionales que podrán ser consultados en la siguiente URL:

Wiki de GitFlow

##### Código fuente repositorio Castor-beyondGIT-Backend

###### Inicializar git flow en el repositorio

Una vez clonado el proyecto o iniciar un nuevo proyecto con Git es necesario inicializar Git Flow. Para hacer esto es obligatorio estar ubicados el el directorio raíz del proyecto y usar el siguiente comando:

```
git-flow init

```

Una vez ejecutado el comando, GitFLow realiza una serie de preguntar para establecer la configuración de nombrado de las ramas y prefijos de versionado, para el uso de Castor se ha decidido que la propuesta de ramas de GitFlow será utilizada por defecto, a lo que simplemente se debe dar enter cada vez que la consola pregunte hasta finalizar el asistente en consola.

A continuación se muestran las preguntas:

```
Which branch should be used for bringing forth production releases?
 - develop
 - master
Branch name for production releases: [master]

Which branch should be used for integration of the "next release"?
 - develop
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Bugfix branches? [bugfix/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
Hooks and filters directory? [/Users/your-usuer/Sites/your-dirname]

```

Y la siguiente imagen nos permite ver el resultado aplicado en consola.

una vez ejecutado el comando *git-flow init* no encontraremos en la siguiente etapa:

###### Iniciar el desarrollo del módulo de registro de usuarios (Feature/Registrarse)

```
git-flow feature start RegistroUsuarios

```

Con este comando git flow partirá de la rama develop como base para generar una rama de nombre RegistroUsuarios

Una vez ejecutado el comando *git-flow feature start RegistroUsuarios* nos encontramos en la siguiente etapa:

###### Integrar el código del módulo de registro de usuarios en la rama develop

```
git-flow feature finish RegistroUsuarios

```

Una vez se considera que el código que implementa este feature está terminado y ha superado las pruebas unitarias se procede a integrar este código en la rama Develop, esto lo logramos a través del comando git-flow feature finish RegistroUsuarios.

Una vez ejecutado el comando *git-flow feature start RegistroUsuarios* nos encontramos en la siguiente etapa:

###### Definir un Release

```
git-flow release start V-0.1.0

```

Una vez se tienen acumuladas funcionalidades suficientes para proponer un despliegue debemos acumular todas estas funcionalidades en una rama release de modo que podamos proceder a aislar el código y proceder con tareas como las pruebas de aceptación, pruebas de estrés, etc.

Para construir esta rama utilizamos el comando git-flow release start V-x.x.x, donde la versión deberá reflejar el release mayor de la aplicación, el consecutivo del release (en este caso 1) y el 0 corresponde al control de fixes en el código., este comendo debe ejecutarse estando en la rama develop.

Una vez ejecutado el comando *git-flow release start V-0.1.0* nos encontramos en la siguiente etapa:

**¡¡ATENCIÓN!!** Ya que el release debe ser visible para todos los integrantes del proyecto de modo que pueda ser usado para las pruebas y tareas a que haya lugar, este debe ser publicado, de modo que quien realiza el start del release debe utilizar el siguiente comando para hacer visible la rama en el repositorio centralizado:

```
git-flow release publish V-0.1.0

```

###### Publicar un Release en Master/Main

```
git-flow release finish V-0.1.0

```

Una vez estamos seguros que el código que se encuentra en nuestro release esta listo para ser publicado en producción ejecutamos el comando git-flow release finish V-x.x.x lo que desencadenará las siguientes acciones:

* El código contenido en la rama release será fusionado (merge) con la rama Master o Main según configuración.
* Se etiquetara el código con el nombre del release, en este caso V-0.1.0
* El código también será fusionado en la rama develop.
* Se borrará la rema release/V-0.1.0

Una vez ejecutado el comando *git-flow release finish V-0.1.0* nos encontramos en la siguiente etapa:

###### Corrección de errores Hotfix

```
git-flow hotfix start V-0.1.1

```

Si una vez publicado en Master se encuentra un error tendremos la posibilidad de aislar el código publicado de modo que podamos realizar los correctivos necesarios y publicar lo antes posible la corrección en producción sin tener que recurrir a acciones de rollback que puedan comprometer nuevas funcionalidades en las que el proyecto esté trabajando, una vez ejecutado el comando git-flow hotfix start V-x.x.x usará la rama Master como base.

Una vez ejecutado el comando *git-flow hotfix start V-0.1.1* nos encontramos en la siguiente etapa:

**¡¡ATENCIÓN!!** Nótese que al crear este hotfix el tercer dígito de la versión aumenta un entero y los dígitos de release mayor y menor se mantienen, es por eso que pasamos de la versión V-0.1.0 a la versión V-0.1.1.

###### Publicar Hotfix en Master/Main

```
git-flow hotfix finish V-0.1.1

```

Una vez corregido el error (es) y superado los planes de pruebas aplicables se procede a publicar en la rama master o main según configuración el código fuente con la corrección del error (es) detectados, esto lo haremos a través del comando git-flow hotfix finish V-x.x.x lo que desencadenará las siguientes acciones:

* El código contenido en la rama hotfix será fusionado (merge) con la rama Master o Main según configuración.
* Se etiquetara el código con el nombre del hotfix, en este caso V-0.1.1
* El código también será fusionado en la rama develop.
* Se borrará la rema hotfix/V-0.1.1

Una vez ejecutado el comando *git-flow hotfix finish V-0.1.1* nos encontramos en la siguiente etapa:

###### Esquema resumen de comandos

En la siguiente grafica podras ver un resumen de los comandos aplicados en el ejemplo practicó, por favor ten en cuenta que estos no son todos los comandos que conforman GIT-FLOW, si quieres conocerlo más en detalle al final te dejaremos unos links con material de referencia que puede ayudarte a aumentar y mejorar mucho más tu conocimiento :

###### Referencias

* Aprende Git de manera sencill: Git Flow
* git-flow cheatsheet
* Git Flow explicado en 10 minutos
* 16 GitHub - ¿Qué es GitFlow? | Curso práctico de cero a experto WonCode
* Git Flow

NOTA: recuerda que este es un espacio de construcción colectiva que tiene como objetivo el asegurar y compartir el conocimiento, así que te invitamos a hacerte participe aportando mayor detalle al contenido, realizando correcciones, aclaraciones, en general aportes que ayuden a una construcción de conocimiento colectivo Castor.