Antes de empezar. La API de Servidor ya tiene DTO, validaciones y respuestas de error. Hoy le montas la compilación y las pruebas automáticas, con el Maven Wrapper que ya trae el proyecto.
Antes de empezar · sin apuntes
- La API se ejecuta en el entorno local. ¿Qué condiciones serían necesarias para que la consumiera una persona ajena al aula?
- El pipeline del portfolio comprueba HTML, enlaces, formato y accesibilidad. ¿Qué tendría que comprobar el de una API?
- ¿Qué directorios de un proyecto Java no deben incorporarse nunca a un repositorio de código, y por qué?
Se explica
25 minutos · explicación y demostración
Reutilizar el repositorio desde el primer día
El backend ya está en GitHub desde Servidor 1. Conservamos ese repositorio, sus ramas y su historial; no se copia a otro para Intermodular. El portfolio puede tener su propio repositorio de presentación. Si el cliente del producto vive dentro del backend, también se conserva esa estructura: un monorepo puede configurar rutas de trabajo por job.
Qué hace el CI de Java
Maven lee pom.xml, compila el código, ejecuta las pruebas y construye el JAR. GitHub Actions repetirá ese proceso en un runner limpio. El wrapper fija Maven, pero para reproducir la construcción también deben coincidir Java, dependencias y configuración.
Un artefacto es el resultado construido, en este caso el JAR. No se guarda en Git: el workflow lo genera y lo entrega al despliegue. Las pruebas se implementan en Servidor; aquí se comprueba que el proceso las ejecuta y que su fallo bloquea la fusión.
Antes de publicar
Primero se reproduce verify en local y después en CI. Un fallo local se registra y se corrige sobre la misma rama del producto. Un fallo del runner puede deberse a Java, permisos del wrapper o configuración; los logs permiten distinguirlo de un defecto de implementación.
Se trabaja
140 minutos · trabajo guiado sobre el producto compartido
Bloque A · El repositorio de la API
- Abre la carpeta del backend de Servidor. Ejecuta
git remote -v,git statusygit log -5 --oneline; comprueba que es el repositorio utilizado desde la sesión 1, con su historial. No ejecutes git init ni crees otro remoto. - En main actualizada, crea una rama para la issue del CI. Ejecuta
.\mvnw.cmd -B verifyen PowerShell (./mvnw -B verifyen Linux/macOS). Si falla, guarda el mensaje causal y corrige la configuración o enlaza la issue técnica; conserva el trabajo útil de la sesión. - Abre pom.xml y anota Java 21, la versión del proyecto y la presencia del wrapper. Revisa que target y credenciales no se rastrean.
git statuspermite ver qué subirás; el historial de Servidor se conserva completo. - Comprueba las reglas configuradas en Intermodular 2 también en el backend. Si aún falta el check de Java, se añadirá después de su primera ejecución. La política de revisión debe ser la misma en ambos módulos.
- Continúa con el workflow del bloque B. El código que compilamos es el CRUD con DTO y errores disponible después de Servidor 12.
Bloque B · El CI que compila
Trabajo individual, por el flujo establecido: issue, rama, pull request
Crea el archivo .github/workflows/ci.yml:
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
build:
name: Compilar y probar
runs-on: ubuntu-latest
steps:
- name: Descargar el repositorio
uses: actions/checkout@v4
- name: Preparar Java
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "21"
cache: maven
- name: Compilar y ejecutar los tests
run: bash ./mvnw -B verify
distributionyjava-version- Debe declararse la versión registrada en el paso 2, no el valor 21 del ejemplo. El runner no aprovisiona ningún JDK por defecto: la distribución y la versión se declaran de forma explícita. Si el valor declarado no coincide con el que especifica el
pom.xml, la compilación falla con un mensaje que no menciona ninguna de las dos versiones. cache: maven- Conserva entre ejecuciones el repositorio local de dependencias. Sin esta directiva, cada pull request vuelve a descargar el árbol completo de dependencias, con el consiguiente incremento de la duración del job.
./mvnw- El Maven Wrapper incluido en el proyecto. Utiliza la versión de Maven declarada por el propio proyecto y no la instalada en la máquina anfitriona, lo que garantiza una construcción equivalente en el runner y en cualquier entorno local.
-B- Modo por lotes (batch): suprime el coloreado y los indicadores de progreso, que en un registro no interactivo generan ruido y dificultan el diagnóstico.
verify- Fase del ciclo de vida de Maven que compila el código, ejecuta las pruebas y construye el artefacto empaquetado. El fallo de cualquiera de las tres etapas determina el fallo del job.
Si el job falla con «permission denied» al ejecutar ./mvnw
Es la incidencia más frecuente de esta sesión y no guarda relación con el código de la aplicación. El runner ejecuta Linux, donde un archivo requiere el bit de permiso de ejecución; el sistema de archivos de Windows no conserva ese atributo, de modo que el wrapper se incorporó al repositorio sin él. Se corrige registrando el permiso en el índice de Git y publicando el cambio:
git update-index --chmod=+x mvnw, después commit y push.
Conviene retener la causa: es la primera manifestación práctica de que el entorno de construcción no coincide con el entorno de desarrollo, diferencia que reaparecerá en otros contextos.
Si el proyecto no incorpora mvnw
Utiliza mvn -B verify, sin el prefijo ./: los runners incorporan Maven preinstalado. La construcción se completa, pero la solución es inferior, dado que la versión de la herramienta la determina la máquina y no el proyecto. Restaura los archivos del wrapper desde el historial o desde la plantilla de Servidor, conservando el código y el repositorio actuales.
Provocación controlada de fallos. Introduce las dos alteraciones siguientes en una rama de diagnóstico, sin fusionarlas, y restaura su estado antes de aprobar la pull request:
| Alteración introducida | Propiedad que demuestra |
|---|---|
| Supresión de un punto y coma en una clase | El pipeline impide la integración de código que no compila |
| Inversión temporal de una aserción de prueba | El pipeline impide la integración de código que compila pero incumple su especificación |
El segundo caso constituye la diferencia sustancial entre este pipeline y el del portfolio: la validación no se limita a la corrección sintáctica del artefacto, sino que verifica su comportamiento.
Bloque C · Comprobación obligatoria y primer recorrido del flujo
Trabajo individual
- Fusiona la pull request que incorpora el CI.
- Accede a Settings → Rules → Rulesets → main protegida → Edit → Require status checks e incorpora Compilar y probar.
- Abre tres issues correspondientes a los siguientes incrementos previstos de la API y recorre al menos una de forma completa por el flujo de integración.
Lista de verificación de la sesión 7
- El repositorio de la API existe, es público y no contiene la carpeta de construcción.
- Cada pull request muestra el check «Compilar y probar».
- La comprobación es obligatoria y se ha verificado una pull request bloqueada por una prueba fallida.
- Una issue de la API recorrida entera.
Cierre
15 minutos · comprobación del resultado
Antes de cerrar · sin mirar
- ¿Por qué el directorio de construcción no se incorpora al repositorio?
- ¿Qué hace
verifyque no haría solo compilar? - ¿Para qué sirve
cache: maven? - ¿Por qué el wrapper produce una construcción equivalente en el runner y en el entorno local?
Ver respuestas
1 · Porque se regenera con un comando, pesa, cambia entera en cada compilación y provoca conflictos. Al repositorio va lo que escribe una persona.
2 · Ejecuta los tests y construye el artefacto, además de compilar.
3 · Para reutilizar las dependencias ya descargadas y no bajarlas en cada ejecución.
4 · Porque fija la versión de Maven en el propio proyecto, en lugar de usar la que tenga instalada cada máquina.
Antes de la sesión 8
- La API se ejecuta en el entorno local y responde a una petición efectuada desde el navegador.
- Es posible identificar el puerto en el que escucha —el proceso lo indica al arrancar— y la ruta que devuelve la colección de datos.
- El check de compilación está en verde en
main.