Apuntes DAM
Tema 6 de 7DAW · 2º DAW

Despliegue de Aplicaciones Web

Git, Documentación y CI/CD

Flujo de trabajo con ramas y pull requests, versionado semántico y Conventional Commits, documentación de una aplicación web, integración y despliegue continuos con GitHub Actions y monitorización.

55 min lecturaAvanzado

1. El repositorio como fuente de la verdad

En un proyecto profesional, todo lo necesario para construir y desplegar la aplicación vive en el repositorio de Git: el código, el Dockerfile, la configuración del servidor, los scripts de base de datos y la documentación. Nada importante debería existir solo en el servidor o en el portátil de alguien. Así, cualquier cambio queda registrado (quién, cuándo y por qué), se puede revisar antes de aplicarlo y se puede deshacer.

Un flujo de trabajo con ramas

Hay muchas formas de organizar las ramas, pero la mayoría de equipos usan alguna variante de este flujo, conocido como GitHub Flow o desarrollo basado en el tronco: la rama main siempre está lista para desplegar, y cada cambio se hace en una rama corta que se integra mediante una pull request revisada por otra persona y comprobada automáticamente.

bash
1git switch -c feat/filtro-categorias          # rama para el cambio
2git add . && git commit -m "feat(web): filtro por categoría"
3git push -u origin feat/filtro-categorias     # y se abre la pull request
4# … revisión, pruebas automáticas en verde, fusión en main …
5git switch main && git pull
6git tag -a v1.5.0 -m "Versión 1.5.0"          # marcar la versión publicada
7git push origin v1.5.0

Versiones con significado

El versionado semántico da significado a los números de versión MAYOR.MENOR.PARCHE: se sube el parche al corregir errores sin cambiar nada más, el menor al añadir funciones compatibles con lo anterior y el mayor cuando hay cambios incompatibles. Si además los mensajes de commit siguen la convención Conventional Commits (feat:, fix:, docs:, y ! para lo incompatible), la siguiente versión y el registro de cambios se pueden generar automáticamente, que es justo lo que harás en los retos.

2. Documentar para el que viene detrás

La documentación de una aplicación web no es un documento de Word que se entrega al final y nadie abre. Es un conjunto de piezas pequeñas, vivas y cerca del código, que responden a preguntas concretas de personas concretas. Y quien más la necesita suele ser tu yo de dentro de seis meses.

DocumentoResponde aFormato habitual
README.md¿Qué es esto y cómo lo arranco en mi equipo?Markdown en la raíz del repositorio
Guía de despliegue¿Cómo se despliega, se configura y se vuelve atrás?Markdown en docs/ o un wiki
Documentación de la API¿Qué rutas hay y qué devuelven?OpenAPI generado o escrito a mano
Comentarios de documentación¿Qué hace esta clase o función y cómo se usa?Javadoc, phpDocumentor, JSDoc
Registro de cambios¿Qué ha cambiado en cada versión?CHANGELOG.md, generado desde los commits
Decisiones de arquitectura¿Por qué se eligió esto y no aquello?ADR: documentos cortos numerados
php
1/**
2 * Calcula el precio final de una línea de pedido.
3 *
4 * @param float $precio    Precio unitario sin IVA.
5 * @param int   $cantidad  Unidades (mayor que 0).
6 * @param float $descuento Descuento entre 0 y 1.
7 * @return float Importe con IVA redondeado a 2 decimales.
8 * @throws InvalidArgumentException Si la cantidad no es positiva.
9 */
10function importeLinea(float $precio, int $cantidad, float $descuento = 0): float { /* … */ }

Herramientas como phpDocumentor, Javadoc o TypeDoc convierten esos comentarios en una web de documentación, y generadores de sitios como MkDocs o Docusaurus publican las guías escritas en Markdown. Lo importante es que la documentación se actualice en la misma pull request que el código que describe.

3. Integración y despliegue continuos

La integración continua (CI) consiste en que cada cambio que se sube al repositorio se construya y se pruebe automáticamente, para detectar los errores en minutos y no el día antes de la entrega. La entrega continua deja cada versión preparada para desplegarse con un botón, y el despliegue continuo va un paso más allá: si todo está en verde, se publica sola.

Un pipeline es una cadena de montaje con controles de calidad

Cada pieza se revisa
El linter, los tests y el análisis de seguridad se ejecutan en cada cambio.
Se empaqueta una vez
Si todo pasa, se construye el artefacto (una imagen Docker) y se etiqueta con la versión.
Y sale por la puerta
Se despliega primero en pruebas y después, con aprobación o automáticamente, en producción.
.github/workflows/ci.yml
1name: CI/CD
2on:
3  push: { branches: [main] }
4  pull_request:
5
6jobs:
7  pruebas:
8    runs-on: ubuntu-latest
9    steps:
10      - uses: actions/checkout@v4
11      - uses: actions/setup-node@v4
12        with: { node-version: 22, cache: npm }
13      - run: npm ci
14      - run: npm run lint
15      - run: npm test
16
17  desplegar:
18    needs: pruebas                       # solo si las pruebas pasan
19    if: github.ref == 'refs/heads/main'  # y solo desde main
20    runs-on: ubuntu-latest
21    environment: produccion              # puede exigir aprobación manual
22    steps:
23      - uses: actions/checkout@v4
24      - run: docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
25      - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
26      - run: docker push ghcr.io/${{ github.repository }}:${{ github.sha }}
27      - run: ssh despliegue@servidor "./desplegar.sh ${{ github.sha }}"   # clave SSH en los secretos
  • Los secretos (claves SSH, contraseñas) se guardan en el gestor de secretos de la plataforma, nunca en el fichero del pipeline.
  • Pipelines rápidos: usar caché de dependencias y ejecutar en paralelo lo que se pueda. Si tarda media hora, nadie esperará a que termine.
  • Rojo significa parar: un pipeline que falla se arregla antes de seguir añadiendo cambios.
PlataformaDónde se configura
GitHub Actions.github/workflows/*.yml
GitLab CI/CD.gitlab-ci.yml
JenkinsJenkinsfile (muy usado en empresas con servidores propios)
Vercel, Netlify, RenderDespliegue automático al conectar el repositorio
Github Actions - CI/CD Gratuito y fácil en Github — Pelado Nerd

4. Después del despliegue: observar

Desplegar no es el final. Hay que saber si la aplicación funciona bien para los usuarios reales, y enterarse de los problemas antes que ellos. Para eso se combinan tres fuentes de información:

  1. Registros: qué ha pasado, petición a petición, centralizados para poder buscar (Loki, ELK).
  2. Métricas: números en el tiempo, como peticiones por segundo, errores o uso de memoria (Prometheus y Grafana).
  3. Alertas: avisos automáticos cuando algo se sale de lo normal, y comprobaciones externas de disponibilidad (Uptime Kuma, UptimeRobot).

Las copias de seguridad también se despliegan

Un despliegue serio incluye copias automáticas de la base de datos y de los ficheros subidos, guardadas fuera del servidor y, sobre todo, probadas: una copia que nunca se ha restaurado es solo una esperanza. En los ejercicios programarás una política de rotación de copias.

5. Retos

Dos piezas de cualquier sistema de publicación automática: calcular la siguiente versión semántica y generar el registro de cambios a partir de los mensajes de commit.

Retos de Bash en el IDE

Escribe el script y pulsa Ejecutar tests: se ejecuta en un Linux real con Bash y se prueba con varios casos, algunos ocultos.

🖥️BashLa siguiente versión semánticaFácil

Cada línea es «versión tipo», donde la versión es MAYOR.MENOR.PARCHE y el tipo es major, minor o patch. Escribe la siguiente versión: major sube el primero y pone los otros a 0; minor sube el segundo y pone a 0 el parche; patch sube el último. Si la versión no tiene el formato correcto o el tipo no es válido, escribe «Versión no válida».

⏳
Los tres tipos
⏳
Entradas no válidas
⏳
Test oculto #3
0/3 tests pasados
🖥️BashChangelog a partir de los commitsDifícil

La entrada son mensajes de commit con el formato de Conventional Commits («tipo(ámbito)!: descripción», con ámbito y ! opcionales). Genera un changelog con las secciones «## Cambios incompatibles» (commits con !), «## Novedades» (feat) y «## Correcciones» (fix), en ese orden, cada una con líneas «- descripción» en el orden original y omitiendo las secciones vacías. Los demás tipos (docs, chore, test…) se ignoran salvo que lleven !. Termina con una línea en blanco y «Siguiente versión: major», «minor», «patch» o «ninguna».

⏳
Versión con novedades
⏳
Cambio incompatible
⏳
Solo mantenimiento
⏳
Test oculto #4
0/4 tests pasados

¿Has terminado este tema?

Crea una cuenta gratis para guardar qué temas has terminado, subir de nivel y ganar medallas.

Guardar mi progreso