integracion-continua-con-Gitlab

Integración continua con Gitlab

La tecnología avanza muy rápidamente, y en nuestros tiempos, ya parece algo inconcebible seguir trabajando en el servidor, o usar FTP para desplegar cambios en nuestras soluciones de software. Las necesidades de la industria, han propiciado la aparición de tecnologías que facilitan la alta disponibilidad, entre otros. Lejos quedaron las soluciones implementadas en máquinas virtuales y servidores virtualizados. El camino ha ido hacia lo micro, lo hemos visto con la aparición de docker y el posterior auge de los microservicios. Ahora se buscan sistemas muy estables con propósitos muy concretos para minimizar al máximo la superficie de error.

Qué es la integración continua

Normalmente se asocian los términos CI/CD. Son cosas distintas, pero representan un todo, que comprende desde el desarrollo hasta la puesta en producción de la característica que queremos integrar en nuestra solución. Para explicar qué es, primero debemos entender a qué hacen referencia estos conceptos, comúnmente llamado devops. Ambas tuplas, están compuestas por fases circulares que representan conceptos abstractos que se usan para agrupar conjuntos de acciones con un propósito similar. Estas fases suelen ser comunes en la industria, y cuentan con la misma jerarquía sin importar el proveedor que deseemos usar. Cada solución, puede tener sus propias divisiones en cada uno de los pasos, incluso añadir nuevos, todo dependerá siempre de las necesidades que precise.

Por una parte tenemos el CI (continuous integration), que comprende desde la planificación hasta el testeo. Cabe destacar, que en entornos en los cuales se trabaja con lenguajes interpretados, como es el caso de PHP, el paso de compilado suele estar asociado a la instalación de dependencias y pasos adicionales, como pueden ser, la generación de archivos de configuración entre otros. En lenguajes compilados, como por ejemplo Java, aquí se suele incluir la compilación en si del código.

Por otra parte tendríamos lo que corresponde a CD (continuous delivery). En este gran bloque, se vela por la correcta aplicación de los cambios en un entorno de producción y la monitorización para evitar o mitigar problemas durante y de forma posterior al lanzamiento a grandes rasgos. Este es un tema complejo que requiere de mucho esfuerzo y dedicación, puesto que tenemos frente a nosotros uno de los grandes problemas de la programación en la gran mayoría de proyectos, la invalidación de cache =D.

Para entender como funciona la parte de CI, vamos a partir de un sencillo script de configuración en gitlab. Pero antes debemos entender el concepto de pipeline y job. Hay otros servicios que usan una funcionalidad muy similar, como es el caso de github con sus actions. Pero la esencia es la misma, tener automatizado el máximo número de tareas posibles para tener un nexo de unión entre la planificación y la puesta en producción de esos cambios. El pipeline representa el compendio de jobs que va a ejecutar un ente (llamado runner). Los jobs representan cada uno de los pasos a través que nuestro pipeline debe ejecutar, y estas pueden ser ejecutadas en paralelo o en serie, y puede ir desde instalar dependencias a subir la imagen compilada del proyecto al image registry. En nuestro ejemplo, vas a ver un ejemplo de de jobs en serie y en paralelo. Si quieres realizar pruebas con un runner sin limitación te aconsejamos que leas la documentación de gitlab y lo alojes por ti mismo, puesto que el tier gratuito tiene limitación de tiempo: https://docs.gitlab.com/runner/install/index.html.

Configuración

A continuación te mostramos el script en el que nos vamos a basar para explicar cada una de las líneas. Hay que tener en cuenta, que este puede ser diseñado de múltiples formas, dependiendo de nuestras necesidades, esta es una de ellas:

Como podrás observar, la configuración está escrita en yaml, y hay varios niveles, entre los cuales, tenemos como raíz palabras reservadas como stages, workflow o cache. Y nodos que representan nuestros jobs. Toda esta información se encuentra de forma clara y concisa en la documentación oficial.

Como primer nodo tenemos stages, que como su nombre indica, representa los pasos que va a ejecutar nuestro pipeline. Hay que diferenciar entre stage y job. El primero comprende uno o varios jobs, y por defecto, los jobs se ejecutan en paralelo, a excepción de que configuremos otro comportamiento. Aquí hay 3 stages, con nombres representativos de que acciones van a llevar a cabo. Por hacer una analogía con el diagrama de CI anterior, build corresponde al compilado de la aplicación, static_analysis y test pertenecen al paso de test. Aquí puedes añadir tantos stages y jobs como quieras.

A continuación tenemos el bloque de workflow, que le indica a gitlab bajo que condiciones se va a ejecutar nuestro pipeline. El orden de condiciones, así como otros aspectos interesantes relacionados, están descritos en la documentación con ejemplos. En resumen, aquí le estamos indicando que queremos que se ejecute si estamos creando un MR (Merge Request), el commit pertenece a la rama master o el target del pipeline viene de web, trigger(a través de la interfaz), etc. Este nodo suele variar poco o nada entre proyectos.

Por último, con respecto a los nodos raíz con palabras reservadas tenemos cache. Esto nos permite almacenar archivos y/o carpetas para que los siguientes stages tengan acceso a ellos. De esta forma, instalamos las dependencias de composer una única vez y las reutilizamos en el resto del pipeline.

El siguiente paso, será nuestro primer job definido, que se ejecutará en función del orden de stages declarado al inicio del archivo. Como puedes observar, aquí podemos instalar dependencias de php necesarias para nuestra aplicación y de composer en nuestro caso. Es importante que siempre uses las tags de las imágenes de docker con las versiones correctas, para evitar fallos no esperados.

Los siguientes 2 stages, phpcs y phpstan, son herramientas de análisis estático y se encargarán de cargar la caché que hemos definido mas arriba y ejecutar la imagen. Si alguno de los 2 muestra errores, tendremos un pipeline marcado como failed, como mostramos a continuación.

Por último, tenemos el último stage de testing con PHPUnit. Como está instalado como dependencia, lo ejecutamos directamente desde vendor. De lo contrario, podríamos usar una imagen de docker para ejecutar este paso. Como comentamos mas arriba, en todos los pasos se pueden ejecutar comandos sobre el contendor, es muy probable que si tienes test E2E en tu aplicación, tengas que instalar alguna dependencia a nivel de imagen. Es aquí donde debes instalarlo, el job de build no necesita esas dependencias, ahí está la magia de docker ;).

Por último, como tip, os dejamos un comando para que podáis probar los jobs sin necesidad de subir el commit a gitlab. Esto os ahorrará tiempo de prueba y ejecución del pipeline completo para comprobar el correcto funcionamiento del job en particular. Es interesante ver el log que genera cada job pulsando sobre él desde la vista de CI/CD-pipelines en gitlab, te puede ayudar a detectar errores.

Conclusión

A través del artículo anterior hemos visto la facilidad de llevar a cabo la integración continua con gitlab. Es un trabajo costoso y se necesita experiencia para adaptarlo a las necesidades del proyecto, pero supone un gran salto de calidad y productividad. Gitlab cuenta con una documentación excelente, así como gran cantidad de ejemplos y foros de ayuda y problemas en los que podemos buscar cualquier problema que nos surja. Además, podemos alojar nuestro runner y evitar así el coste que tiene usar estas tecnologías si queremos probarlas. También es posible añadir integraciones a gitlab o al runner para llevar a cabo acciones adicionales que no están presentes en la funcionalidad que nos presentan. Fuera del artículo ha quedado la compilación de las imágenes y posterior subida al docker registry y la creación de una imagen por defecto, entre otros. Os invitamos a que investiguéis en la documentación oficial y comparareis con otras alternativas, puede ser muy enriquecedor llevar a cabo la misma configuración con github actions ;).

Comparte
Share on facebook
Share on twitter
Share on linkedin
¿Quieres más información?
Ponte en contacto con nosotros.
Jordi Mahiques
Jordi Mahiques
Backend developer - Departamento de desarrollo

Enviar Comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Artículos relacionados

Suscríbete a nuestra newsletter
para estar al día en el mundo online
¿Tienes alguna incidencia?

Cuéntanos qué ocurre
y nos pondremos con ello lo antes posible.

    Este sitio está protegido por reCAPTCHA, y la Política de privacidad y Términos de servicio de Google.
    ¡Cuéntanos tus ideas!
    +34 96 653 19 14
    info@acceseo.com

      Este sitio está protegido por reCAPTCHA, y la Política de privacidad y Términos de servicio de Google.