Que es Git
Git es un software de control de versiones, cuyo propósito es llevar el registro e histórico de los cambios en archivos y coordinar el trabajo que varias personas realizan sobre archivos compartidos.
Una de las grandes características que posee Git contra otras tecnologías de control de versiones, tal como Subversion, es que este no solo cuenta con un repositorio central (remoto). Cada usuario que desee trabajar con Git deberá clonar un repositorio en su máquina de trabajo (repositorio local). Sobre este repositorio local, es donde el usuario trabajará y realizará los cambios. A su vez, este será el sitio desde donde el usuario sincronizará los cambios hacia el repositorio central y viceversa (subir y bajar cambios).
Conceptos básicos de Git
Git maneja el término de ramas, para referirse a pequeñas bifurcaciones del código fuente central para la realización, modificación, corrección o eliminación del mismo. Por lo general existen dos tipos de ramas principales o permanentes (master y develop) y 3 tipos de ramas secundarias o temporales (feature, hotfix, bugfix, release).
Master
Esta es la rama principal del repositorio, es una rama permanente, y en ella están todas las liberaciones o versiones a producción, es decir, cuando esta rama sufre alguna modificación de código fuente, se generará una nueva versión para ser lanzada a producción.
- Uso: Es donde está el código fuente final (cada versión liberada). No se trabaja directamente en la rama master, sino que ella es modificada a través de las ramas develop, release y hotfix, mediante un merge (Pull Request). Esta rama tiene sólo las versiones liberadas, queda muy limpia y con muy pocos commits en ella.
- Nomenclatura: master.
- Se crea: Al crear el repositorio, es la rama principal.
- Finaliza: Nunca, junto a develop es una de las dos ramas permanentes.
Develop
Esta es la rama principal del desarrollo, es una rama permanente, y en ella se encontrarán todos los cambios, correcciones, mejoras y demás que sufra el código fuente, a través de la labor desarrollada por los desarrolladores.
- Uso: Es en donde está cada commit realizado. No se trabaja directamente en la rama develop, sino que ella es modificada a través de las ramas feature, release y hotfix mediante un merge(Pull Request).
- Nomenclatura: develop.
- Se crea: Desde master, al crear el repositorio.
- Finaliza: Nunca, junto a master es una de las dos ramas permanentes.
Feature
Esta es una rama temporal de desarrollo, en ella se realizan directamente las correcciones, modificaciones y demás sobre el código fuente.
- Uso: Es donde se realizan las modificaciones del código fuente, por tanto, es el tipo de rama más creada en el ciclo de vida del repositorio, por lo general, por cada caso reportado en el Jira, se creará una rama de este tipo.
- Nomenclatura: feature/XXX, donde XXX es el número del caso reportado en el Jira. Por ejemplo feature/RHU-001.
- Se crea: Desde develop, por lo general por cada caso reportado en el Jira.
- Finaliza: Cuando se comprueba que la modificación del código es correcta.
Hotfix
Esta es una rama temporal para corrección urgente de errores encontrados en producción.
- Uso: Para la corrección de algún problema urgente en el código en producción.
- Nomenclatura: hotfix/XXX, donde XXX es el número de caso urgente del Jira.
- Se crea: De master (es la única rama, aparte de develop, que se crea y regresa a master).
- Finaliza: Cuando se comprueba que la corrección del código es correcta. Debe hacerse un merge hacia develop y hacia master. Una vez hecho el merge hacia master, se debe poner un tag indicando la versión (El tag es opcional).
Release
Esta es una rama temporal para pruebas, en ella se realizan las pruebas de la siguiente versión previo a la salida a producción.
- Uso: Es donde se realizan las pruebas, cada vez que se quiera sacar una versión del código a producción.
- Nomenclatura: release/XXX, donde XXX es el número de versión a liberar. En ella se realizarán todas las pruebas de código a ser liberado.
- Se crea: Desde develop, cuando se desea realizar una liberación.
- Finaliza: Cuando la versión está preparada para liberarse. Debe hacerse un merge hacia develop y hacia master. Si la versión ha salido a la primera bien, no tendrá ningún cambio que llevar hacia develop. Una vez hecho el merge hacia master, se debe poner un tag indicando la versión (El tag es opcional).
Nota: Por la naturaleza del proyecto y estructura de los equipos de trabajo, este tipo de rama no es utilizada en el sistema SIGESA, por lo que cada subgrupo de desarrollo crea otro tipo de rama temporal, a la cual le aplica los cambios propios para la realización de pruebas, por ejemplo (develop-rrhh, develop-ppi, develop-pbs, develop-epf…).
Bugfix
Esta es una rama temporal para la corrección o cambios en las ramas release.
- Uso: Es donde se realizan las correcciones de la rama de pruebas release.
- Nomenclatura: bugfix/XXX, donde XXX es el número o descripción de la corrección.
- Se crea: Desde release, cuando se desea realizar una corrección
- Finaliza: Cuando se comprueba que la corrección del código es correcta. Debe hacerse un merge hacia release.
Nota: Por la naturaleza del proyecto y estructura de los equipos de trabajo, este tipo de rama no es utilizada en el sistema SIGESA.
Conceptos básicos de Bitbucket
Bitbucket es una herramienta de colaboración basada en Git, para la creación de repositorios y alojamiento de código fuente. Mediante Bitbucket se puede realizar la planificación y trazabilidad de un proyecto, así como la colaboración y desarrollo por parte del equipo.
Proyectos y Repositorios
Bitbucket puede gestionar diversos proyectos, lo cuales a su vez abarcan uno o varios repositorios de código fuente, mediante los cuales, para cada uno, se crea una estructura de trabajo similar a la expuesta en la imagen anterior.
Cabe mencionar que tanto los proyectos, repositorios y ramas poseen una configuración de accesos y permisos por usuarios o grupos del sistema.
Para SIGESA, existe tanto un proyecto como un repositorio con dicho nombre, el cual contiene la configuración, información del código fuente y la estructura de ramas correspondiente.
Permisos sobre repositorio y ramas
A nivel de configuración, en un proyecto se puede crear una serie de restricciones o accesos a diversos elementos tales como los repositorios y ramas. SIGESA cuenta con dos tipos de configuración de permisos a nivel de repositorio y ramas.
A nivel de repositorio se establece el permiso de lectura o escritura tanto a usuarios como a grupos. En SIGESA todos los grupos mencionados con anterioridad poseen permisos de lectura y escritura en el repositorio, con lo cual cada integrante de cada grupo tendrá acceso al repositorio, así como a la creación y modificación de ramas, según su rol.
A nivel de rama se definen, de manera similar, permisos que van orientados a las restricciones. Es decir, todos los usuarios podrán realizar cualquier manipulación de ramas, salvo que se cree una restricción que establezca lo contrario.
En SIGESA las restricciones a nivel de rama son las siguientes, tanto para la rama master como para la rama develop:
- Nadie podrá sobrescribir la historia de la rama.
- Nadie podrá eliminar la rama.
- Nadie podrá realizar cambios a la rama directamente.
- Nadie podrá hace modificación a través de un pull request, excepto los usuario del grupo COODINACION-SIGESA.
Con lo anterior, se ha configurado en el repositorio que únicamente los usuarios del grupo COODINACION-SIGESA podrán realizar las integraciones de código a develop y a master para posteriormente generar una nueva versión del sistema para producción.
NETBEANS
Flujo de trabajo en SIGESA
A continuación se detalla el flujo de trabajo para el desarrollo en SIGESA, el cual abarca la creación del caso o incidencia, la generación de ramas desde el repositorio central, la fusión o integración de cambios, la compilación y despliegue de una nueva versión a producción.
Es importante mencionar la utilización de 3 herramientas principales en este ciclo de desarrollo, las cuales, ayudan a la gestión de código, organización y planificación en equipos y control y creación de versiones y despliegues en producción.
Jira
Esta herramienta provee funcionalidades para la gestión de equipos de trabajo, mediante la utilización de tableros tipo kanban. En ella se lleva el control de las tareas a realizar dentro del sistema, así como la planificación de las mismas, utilizando una metodología de desarrollo basada en Scrum.
Bitbucket
Esta herramienta, como se mencionó en secciones anteriores, provee una infraestructura para el manejo de repositorios de código fuente colaborativo, mediante la cual se generan ramas de trabajo para el desarrollo de casos dentro de la aplicación. Además, crea un histórico de modificaciones sufridas por el código de la aplicación, lo cual se le puede dar trasabilidad a versiones anteriores del sistema.
Desde esta herramienta se deciden que características nuevas, modificaciones o correcciones se implementaran en la nueva versión a liberar en producción.
Bamboo
Esta herramienta es la encargada de generar y verificar la correcta compilación o creación de la aplicación una vez se apliquen cambios a las ramas deseadas (en este caso master), además, provee una interfaz, mediante la cual se realiza de manera automática la subida de esa compilación al servidor de producción, por lo que nos garantiza que la versión subida a producción, fue una generada de manera correcta y sin errores de compilación.
Equipo de Scrum
El proceso realizado para la creación, actualización o corrección de alguna característica en el sistema a nivel de código fuente inicia desde el Jira, cada uno de los equipos conformados cuenta con uno o varios tableros o pizarras asignadas, en donde previamente se han registrado los casos o solicitudes de cambios en el sistema. Existe toda una metodología basada en Scrum para la creación, priorización y selección de tareas que serán atendidas por cada uno de los equipos de desarrollo, en un ciclo de trabajo (sprint).
En la metodología Scrum se cuenta con diversos actores o roles, los cuales tienen asignadas diversas responsabilidades en el equipo, estos actores son:
- Product Owner: Es el representante de los clientes del producto (los que utilizan el software), este se focaliza en la parte del negocio y es el responsable del retorno de la inversión del proyecto. Debe ser capaz de trasladar la vision del proyecto al equipo, formalizar los casos a desarrollar (historias) e incluirlos en la pila de trabajo del equipo.
- Scrum master: Es la persona encargada de liderar el equipo, acompañándolo y guiándolo para que se cumplan las reglas y procesos de la metodología. Además, debe colaborar con el equipo para reducir y eliminar los posibles impedimentos que pueden afectar la entrega del producto, también se encarga de las labores de tutoría, formación, coaching y de facilitar reuniones y eventos si en necesarios.
- Equipo de desarrollo: Son los encargados de desarrollar el producto, deben ser capaces de autogestionarse y autoorganizarse para poder entregar un incremento de software al final de cada sprint. Este equipo debe contar con los conocimientos técnicos necesarios para desarrollar de manera conjunta las tareas, llevando cada una de las historias designadas al inicio de sprint.
En la pizarra se determina cuál será la siguiente tarea a desarrollarse. Cuando un desarrollador del equipo de Scrum se desocupe de una tarea anterior, deberá seleccionar la siguiente tarea según la prioridad de la misma. La pizarra cuenta con diversas columnas que determinan el estado de la tarea, a su vez existen anotaciones o etiquetas para determinar algunas características de la tarea.
- POR HACER: Son todas las tareas pendientes por desarrollarse.
- EN PROGRESO: Son aquellas tareas en las que se ha iniciado su desarrollo.
- PEND REV CÓDIGO: En esta etapa las tareas estan concluidas y se realiza una revisión por parte de otro integrante del equipo.
- SU. DESARROLLO: Esta etapa le comunica a Scrum master que debe crear o integrar la tarea a un servidor de desarrollo, para que pueda ser probada en un ambiente más real.
- PR: DESARROLLO: Son las tareas que se encuentran en el servidor de desarrollo y están siento probadas y verificadas por el equipo de desarrollo y el Product Owner.
- HECHO: Son las tareas listas para su subida a producción.
Pasos para el proceso de desarrollo y puesta en producción
Para el presente documento y ejemplo utilizaremos la pizarra designada al equipo de desarrollo SIGESA-RHU y la tarea o caso RHU-6331.
Paso 1: Selección de la tarea
Se debe seleccionar la tarea superior de la columna POR HACER de la pizarra del equipo, debido a que las tareas están priorizadas en dicho orden, y arrastrarla a la columna EN PROGRESO.
Una vez arrastrada a la columna EN PROGRESO se da clic sobre la misma y se registra el desarrollador responsable.
Cabe mencionar que la tarea presenta una breve descripción de la misma y los detalles a realizar en ella, por lo que el desarrollador sabrá puntualmente que es lo que debe realizar en ella.
Paso 2: Creación de la nueva rama
Al igual que en el paso anterior, se debe seleccionar la tarea y abrirla, en donde se mostrará la información de la misma y una opción para crear una rama única para su desarrollo. Se procede a dar clic sobre la opción Create Branch
Inmediatamente, nos mostrará un sub-menú con las opciones para enlazar nuestra tarea de Jira con una rama de código fuente en Bitbucket, en donde seleccionamos la opción Create branch in Bitbucket.
Esta acción hará que se despliegue un asistente para la creación de la rama en la aplicación de Bitbucket, una vez se cargue la pantalla debemos especificar una serie de datos para crear la bifurcación del código deseado
- Repository: Es el repositorio de código fuente en donde deseamos trabajar, debemos tener acceso al mismo.
- Branch type: Es el tipo de rama a crear (para este ejemplo será feature).
- Branch from: Es la rama origen desde donde deseamos crear nuestra bifurcación de código (todas las ramas feature se crean desde develop).
- Branch name: El nombre de la rama(feature/RHU-6331)
Finalmente, presionamos sobre el botón Create branch, lo que creará dicha rama de trabajo.
Una vez creada la rama en el repositorio, procedemos a descargarla mediante alguna herramienta para el trabajo de repositorios basados en Git, o desde la línea de comandos de nuestro equipo. Para el ejemplo se utilizará Apache NetBeans para el trabajo en la rama, se asume el previo clone del repositorio (ver la sección Git en Apache NetBeans).
Procedemos a descargar la rama deseada desde Apache NetBeans en la opción Git > Remote > Pull, con lo cual se mostrará un asistente en donde definimos el repositorio origen y las credenciales de acceso.
Al presionar sobre el botón Next >, se nos desplegarán todas las ramas creadas en el repositorio, aquí debemos seleccionar la rama actual en donde estemos, en este caso develop, y la rama nueva a descargar(feature/RHU-6331).
Finalmente, se debe presionar sobre el botón Finish, con lo cual se procederá a descargar la información de la rama en nuestro equipo.
Nota: Existirán dos ramas, feature/RHU-6331 y origin/feature/RHU-6331, sin embargo, la que dice origin es la referencia de la rama remota que se encuentra en el servidor de Bitbucket, y la que no dice origin, es la rama local en nuestro equipo.
Una vez descargada la información de la rama, procedemos a movernos o cambiar de rama a la rama feature/RHU-6331, esto se realiza mediante la opción Git > Branch/Tag > Switch To Branch…, se mostrará un asistente en donde seleccionamos a la rama en donde queremos trabajar y presionamos el botón Switch.
De aquí en adelante, se debe trabajar a nivel de programación de código para realizar lo correspondiente en la tarea seleccionada.
Cada vez que se deseen guardar los cambios de nuestro trabajo en la rama (copia local), se debe realizar una confirmación de los cambios mediante la opción Git > Commit, la cual mostrará un asistente en donde agregamos un mensaje de lo realizado y los archivos involucrados en el desarrollo.
Nota: Se pueden realizar tantos commits como se desee.
Paso 3: Envío de los cambios al repositorio remoto.
Hasta el momento, todas las modificaciones realizadas al código fuente son almacenadas en nuestra rama local (feature/RHU-6331), sin embargo, se completa todo el desarrollo de la tarea, se debe compartir al repositorio remoto nuestros cambios, con lo que cualquier otro miembro del equipo los podrá acceder y verificar.
Para enviar estos cambios a la rama remota (origin/feature/RHU-6331), se debe realizar mediante la opción Git > Remote > Push, con lo cual se mostrará un asistente en donde definimos el repositorio remoto y las credenciales de acceso.
Al presionar sobre el botón Next >, se nos desplegará y marcará por defecto la rama local y la rama remota, de tal manera que se enviaran los cambios locales al repositorio remoto (feature/RHU-6331 -> feature/RHU-6331).
Si presionamos el botón Next >, nos mostrará una confirmación de lo anterior.
Finalmente, se debe presionar sobre el botón Finish, con lo cual se procederá a subir o enviar la información de la rama local a la rama remota (subida de código fuente).
Paso 4: Revisión de código
Como parte de la metodología implendata en los equipos de desarrollo, se debe realizar un proceso de verificación de código desarrollado en la tarea. Para ello, la persona responsable de la tarea debe cambiar el estado de la misma desde la pizarra en Jira, moviendo la tarea de la columna EN PROGRESO a la columna PEND REV CÓDIGO, esto notificará a otro integrante del equipo (previamente establecido) que deberá revisar el trabajo realizado por el responsable de la tarea.
Nota: La persona encargada de la revisión del código debe ser otra diferente a la responsable de la tarea.
Una vez finalizado el proceso de revisión de código, se debe dar al responsable de la tarea el visto bueno de la misma, o en caso contrario, se le debe de comunicar los posibles errores de la implementación realizada.
Paso 5: Solicitud para pruebas (desarrollo)
Cuando el responsable de la revisión de código, le da el visto bueno al responsable de la tarea, este procederá a solicitar la integración de su código, en una rama especial creada por el Scrum master la cual será compilada y desplegada en un servidor de pruebas. Para esto, el responsable de la tarea deberá traslatar la tarea en la pizarra del equipo, del estado PEND REV CÓDIGO al estado SU. DESARROLLO.
El Scrum master será el responsable de integrar la tarea a la rama especial para realizar las pruebas, esta rama será compilada y desplegada en un servidor de pruebas mediante la herramienta Bamboo, la cual será mostrada más adelante en el documento.
Paso 6: Integración al servidor de desarrollo
Como se mencionó anteriormente, el Scrum master es el responsable de verificar la columna SU. DESARROLLO, y proceder a realizar la integración de código a una rama especial para realizar las pruebas correspondientes de la tarea, en un servidor de pruebas. Cuando esta tarea esté integrada, compilada y desplegada en el servidor de pruebas, el Scrum master trasladara la tarea en la pizarra del estado SU. DESARROLLO al estado PR. DESARROLLO, con esto se le notificará al desarrollador o responsable de la tarea, que la misma ya esta lista para sus pruebas en el servidor de desarrollo.
Es importante destacar que en esta etapa, la tarea puede ser probada o verificada, tanto como por el responsable de la tarea, como por cualquier otro integrante de equipo, inclusive el Product Owner deberá verificarla y validarla.
Paso 7: Fin de la tarea
Al estar completamente validada la tarea por el equipo de desarrollo, esta cambia su estado al estado final de determinado en la pizarra del equipo, el cual es HECHO, con ello se notifica que la tarea está completamente lista para su futura integración a las ramas principales (develop y master), para posteriormente ser puesta en producción.
Paso 8: Solicitar integración a develop
Una vez la rama sea cambiada, por el responsable de desarrollarla, al estado HECHO, este deberá solicitarle al Scrum master que integre la tarea con la rama principal develop, para ello se debera crear suna solicitud de integración (Pull request) de la rama de la tarea a la rama develop.
Desde Bitbucket se deberá seleccionar el repositorio deseado.
Y presionar el botón Create pull request, lo cual nos mostrará un asistente para registrar el pull request
En este asistente se deberá seleccionar dos parámetros principales, los cuales son:
- Source: Es la rama que deseamos integrar (feature/RHU-6331).
- Destination: Es la rama a la cual deseamos enviar los cambios (develop).
Una vez seleccionadas las ramas, presionamos el botón Continue, lo cual, nos mostrará un último detalle con la información de pull request a crear.
Si toda la información es correcta, se procede a presionar el botón Create, lo cual creará el pull request, que posteriormente integrará el Scrum master a develop.
Paso 9: Integración a develop
El Scrum master tendrá la tarea de verificar constantemente las solicitudes de integración de su equipo de trabajo. Él deberá de ingresar a Bitbucket e ingresar a la sección de Pull Request, en donde verificará si otro miembro del equipo le ha solicitado alguna integración. Si ese es el caso, deberá seleccionar el pull request.
Nota: Únicamente los Scrum master podrán realizar la accion de integración, para esta configuración, serían los usuarios dentro del grupo COORDINACION-SIGESA.
Una vez seleccionado, se mostrará la opción para integrar esta tarea a la rama destino, para ello se presiona sobre el botón Merge.
Se mostrará, a continuación, una confirmación del pull request, en donde se integrará el nuevo código de la rama feature/RHU-6331 a la rama develop. Finalmente, presionamos el botón Merge, lo cual hará que se integre el código.
Nota: El ciclo de vida de la rama correspondiente a la tarea, llega en este momento a su fin.
Como se mencionó en secciones anteriores, existe otra herramienta llamada Bamboo, la cual está configurada para detectar los cambios en ramas específicas (develop y master), esta herramienta al detectar un cambio en el código, por medio de una integración de pull request, disparará un proceso el cual compilará las fuentes y creará un ejecutable de la aplicación, basándose en la información actual de la rama.
Este proceso de compilación de código fuente y creación de la aplicación, será notificada a los Scrum master, en donde alertará si el código fuente actual de la rama presenta alguna inconsistencia o error en el mismo, o si, en caso contrario, el código fue compilado de manera correcta y se pudo generar una versión de la aplicación.
Estas notificaciónes también pueden ser vizualizadas desde el Bitbucket.
Paso 10: Integración a master (nueva versión del sistema)
La integración del código a master es una labor exclusiva de los Scrum master y se realiza únicamente desde la rama principal de desarrollo develop. Se debe tener en consideración que existen diversos equipos de desarrollo, los cuales trabajan sobre sistemas y módulos en específico, por este motivo y debido a la estructura de proyectos basados en Git, es que no se despliegan versiones directamente desde develop, es decir, hasta que no exista una posible respuesta positiva por parte del Bamboo, no se debe integrar hacia master.
El proceso de integración a master desde develop es muy similar al proceso anterior, la gran diferencia es que todo este proceso es creado y gestionado por el Scrum master.
En donde debe, similar a lo anterior, crear un Pull request, desde la rama origen develop hacia la rama destino master, y posteriormente realizar el Merge.
De igual manera que con la rama develop, Bamboo, por su configuración, detectará los cambios en rama master y disparará un proceso el cual compilará las fuentes y creará un ejecutable de la aplicación, basándose en la información actual de la rama, este proceso creará una nueva versión del sistema, sin embargo, cabe mencionar que no necesariamente todas las versiones creadas exitosamente son desplegadas en producción, esto debido a que la rama master puede sufrir rápidamente cambios. Sin embargo, gracias a esta configuración en Bamboo, los equipos de desarrollo se garantizan que al menos existe una versión reciente y bien generada creada en Bamboo y lista para una posible puesta en producción.
Paso 11: Puesta en producción.
Al igual que la integración a la rama master, la puesta en producción de una nueva versión, es una labor exclusiva de los Scrum master y se realiza mediante la herramienta Bamboo. Para ello, se ingresa a la herramienta y se selecciona el proyecto.
Una vez dentro del proyecto nos mostrará las últimas compilaciones de la rama.
Si se deseará liberar una nueva versión del sistema, el Scrum master, debe notificar a los demás Scrum master que liberará una nueva versión, en donde los demás Scrum master deben dar su visto bueno, esto se realiza con el fin de dar a conocer a los demás equipos, que las tareas integradas serán puestas en producción.
Para realizar la liberación de la última versión compilada, se debe presionar el botón “Related deployment projects” y seleccionar el plan de despliegue (SIGESA).
A continuación, se debe presionar el botón Deploy, y seleccionar la opción Producción (erp.una.ac.cr).
Finalmente, nos mostrará un último asistente, en donde se debe seleccionar la opción “Create new release from build result“, y él cargará la información correspondiente a la última vesión compilada existosa de la rama master.
Bastará presionar el botón Start deployment, para que el sistema Bamboo inicie el despliegue de la nueva versión del sistema, con los últimos cambios integrados.
Al finalizar este proceso, nos notificará del despliegue exitoso, por lo que podremos navegar hacia nuestro sistema y encontrar nuevos cambios en él.