Repositorios y CI/CD
Qué es un repositorio y qué tipos hay, las forjas de software con su fork y su pull request, y cómo la integración y el despliegue continuos automatizan todo lo que ocurre después de un commit.
Repositorios de código y repositorios de artefactos
Un repositorio es el almacén donde vive un proyecto junto con toda su historia: no solo la versión actual de cada fichero, sino cada cambio, quién lo hizo, cuándo y por qué. Es la pieza sobre la que se apoya el control de versiones, y también el punto de partida de todo lo automático que ocurre después.
Conviene no mezclar dos cosas que se llaman igual y guardan cosas distintas. El repositorio de código guarda el fuente y su historia. El repositorio de artefactos guarda el resultado ya compilado y empaquetado, los ficheros JAR o WAR de un proyecto Java por ejemplo, junto con las dependencias externas que hacen falta para construirlo.
| Tipo de repositorio | Qué guarda | Ejemplos |
|---|---|---|
| De código fuente | Los ficheros del proyecto y la historia completa de cambios | Git, Subversion, Mercurial |
| De artefactos y dependencias | Los binarios construidos y las bibliotecas de terceros | Nexus, Artifactory, Archiva |
| Forja o plataforma colaborativa | Repositorios de código más las herramientas para trabajar en equipo sobre ellos | GitHub, GitLab, Bitbucket, SourceForge, Gforge, Redmine y Google Code |
Un repositorio de artefactos evita que cada máquina se descargue las dependencias de internet una y otra vez, y garantiza que todos construyan con exactamente la misma versión de cada biblioteca.
Para el examen
Qué evita un repositorio de artefactos: descargar las dependencias de internet una y otra vez
Qué garantiza: que todos construyan con la misma versión de cada biblioteca
Forjas de software y flujos colaborativos
Una forja (forge) es una plataforma que aloja repositorios y añade encima todo lo que un equipo necesita para trabajar sobre ellos: gestión de incidencias, revisión de código, wiki, control de permisos y automatización. El concepto viene del mundo del software libre y de código abierto (FOSS), donde hacía falta un lugar público en el que colaborar entre desconocidos.
El flujo colaborativo típico, popularizado por GitHub, encadena dos operaciones. Con el fork se hace una copia del proyecto ajeno dentro de la propia cuenta de la plataforma, sin salir de la nube; esa copia es tuya y en ella puedes hacer lo que quieras. Después la clonas a tu equipo, trabajas y subes los cambios a tu copia.
Con el pull request (llamado merge request en GitLab) le propones al dueño del proyecto original que incorpore tus cambios. No es un comando de Git, sino una función de la plataforma: abre una página donde se ve la diferencia propuesta, se comenta línea a línea, se ejecutan automáticamente las pruebas y, si el responsable lo aprueba, se fusiona. Es el mecanismo estándar de revisión de código incluso dentro de un mismo equipo, donde no hace falta fork y basta con una rama.
El fork es tuyo y no requiere permiso de nadie; el pull request es una petición que el dueño del repositorio original puede aceptar, rechazar o pedir que se modifique.
Para el examen
Fork: es tuyo y no requiere permiso
Pull request: una petición al dueño del repositorio original
Qué puede hacer el dueño: aceptarla, rechazarla o pedir cambios
Integración continua, entrega y despliegue continuos
La integración continua consiste en que cada cambio que alguien sube al repositorio se compile y se pruebe automáticamente, sin esperar a un momento de integración al final del proyecto. Así, si un cambio rompe algo, se sabe en minutos y con un solo autor sospechoso, en vez de descubrirlo semanas después mezclado con el trabajo de todos.
El servidor de integración vigila el repositorio y reacciona a cada subida. La lectura del repositorio se puede disparar de tres formas: a mano, de forma planificada a intervalos regulares, o a la escucha, avisado por el propio repositorio en cuanto entra algo nuevo.
| Sigla | Nombre | Hasta dónde llega automáticamente |
|---|---|---|
| CI | Integración continua | Compilar, analizar la calidad del código y pasar las pruebas |
| CD (entrega) | Continuous Delivery | Dejar el paquete listo y validado para desplegar, pero el paso a producción lo aprueba una persona |
| CD (despliegue) | Continuous Deployment | Desplegar en producción sin intervención humana si todo el proceso ha ido bien |
Las dos siglas CD se distinguen por quién aprieta el botón: en entrega continua el despliegue queda preparado y lo autoriza una persona; en despliegue continuo no hay botón que apretar.
Servidores y servicios de integración continua habituales: Jenkins, que es el más veterano y el que se cita casi siempre en examen, Travis CI, CircleCI, TeamCity, Codeship, Bamboo, y las funciones integradas en las propias forjas, como GitHub Actions o GitLab CI.
Para el examen
Entrega continua: el despliegue queda preparado y lo autoriza una persona
Despliegue continuo: no hay botón: llega solo a producción
Cómo se distinguen: por quién aprieta el botón
El pipeline: qué ocurre desde el commit hasta el despliegue
Un pipeline es la secuencia de etapas automáticas por las que pasa un cambio. Cada etapa solo se ejecuta si la anterior ha terminado bien, de modo que el proceso se detiene en cuanto algo falla y nadie pierde tiempo desplegando código roto. Este es el circuito típico de un proyecto Java gestionado con Jenkins, que lleva Maven dentro para encargarse de la construcción y de las dependencias.
- El servidor lee del repositorio de código (Git, Subversion o TFS) todo lo que se ha subido.
- Recupera del repositorio de artefactos las dependencias externas necesarias y compila el proyecto.
- Pasa el análisis de código estático, por ejemplo con SonarQube, que rechaza el cambio si no cumple el estándar de calidad acordado.
- Ejecuta las pruebas unitarias con JUnit, ya con el código en ejecución, para comprobar que la funcionalidad sigue en pie.
- Despliega el resultado en un servidor de aplicaciones (JBoss, WildFly, WebSphere), tarea que puede delegarse en una herramienta de automatización como Ansible.
Los cuatro primeros pasos son integración continua; el quinto es el que convierte el proceso en despliegue continuo. Es la forma más rápida de recordar dónde acaba CI y dónde empieza CD.
El paso 3 y el paso 4 se complementan y se preguntan enfrentados: el análisis estático mira el código sin ejecutarlo y detecta lo que huele mal (duplicidades, complejidad excesiva, incumplimientos del estándar), mientras que las pruebas unitarias ejecutan el código y detectan lo que se comporta mal.
Commit
Alguien sube su cambio al repositorio compartido.
Compilación
El servidor construye el proyecto desde cero.
Pruebas automáticas
Unitarias y de integración. Si fallan, el proceso se detiene aquí.
Análisis y empaquetado
Calidad del código y artefacto listo. Hasta aquí llega la integración continua.
Despliegue
Automático en el despliegue continuo; con autorización de una persona en la entrega continua.
Para el examen
Qué es integración continua: compilar, probar, analizar y empaquetar
Qué lo convierte en despliegue continuo: el despliegue automático a producción