This commit is contained in:
jose-rZM
2026-02-14 16:58:23 +01:00
parent cdd2618210
commit e8555453f7
21 changed files with 896 additions and 0 deletions

View File

@@ -0,0 +1,101 @@
\section{Introducción}
\begin{frame}
\frametitle{\textbf{Open Bokeron (spam nuestro)}}
\begin{itemize}
\item Asociaci\'on de software libre de la ETSII (UMA).
\item Hacemos cosas \#HazCosas
\item Web: \bluehref{https://openbokeron.uma.es}{openbokeron.uma.es}
\end{itemize}
\vspace{0.2in}
\begin{mybox}
\begin{itemize}
\item[\ding{229}] Objetivo del taller: entender un correcto flujo de desarrollo, CI/CD y perderle miedo a Jenkins de forma pr\'actica usando un proyecto base (FastAPI + Svelte).
\end{itemize}
\end{mybox}
\end{frame}
\begin{frame}
\frametitle{\textbf{\'Que es CI/CD?}}
\begin{itemize}
\item \textbf{CI (Integraci\'on Continua)}: integrar cambios peque\~nos frecuentemente y validarlos autom\'aticamente.
\item \textbf{CD (Entrega/Despliegue Continuo)}: llevar el cambio a un entorno desplegable con un proceso reproducible.
\item Se apoya en automatizaci\'on: pipeline + artefactos versionados + entornos.
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Ejecuci\'on del taller y consideraciones}}
\begin{itemize}
\item Se os da una \textbf{VM Ubuntu} con el repo clonado en local.
\item Trabajaremos con:\\
\hspace{0.25em}-- \texttt{backend/} (FastAPI + pytest + ruff)\\
\hspace{0.25em}-- \texttt{frontend/} (Svelte/Vite + svelte-check)\\
\hspace{0.25em}-- pipelines: \texttt{Jenkinsfile.ci} y \texttt{Jenkinsfile.cd}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Jenkins vs GitHub Actions}}
\begin{columns}[T]
\begin{column}{0.48\linewidth}
\textbf{Jenkins}
\begin{itemize}
\item Muy flexible; se integra con casi cualquier cosa.
\item Control total: agentes, credenciales, redes, storage.
\item Contras: mantenimiento, plugins, upgrades y seguridad.
\end{itemize}
\vspace{0.4em}
\centering
\includegraphics[width=1.2\linewidth]{images/jenkins_smile.jpg}
\end{column}
\begin{column}{0.48\linewidth}
\textbf{GitHub Actions}
\begin{itemize}
\item Experiencia integrada con GitHub (PRs, checks, permisos).
\item Menos ops; runners gestionados (o self-hosted pagando).
\item Contras: lock-in, l\'imites de ejecuci\'on, dependes de un externo, starvation.
\end{itemize}
\vspace{0.4em}
\centering
\includegraphics[width=0.75\linewidth]{images/tenna_spray_github.jpg}
\end{column}
\end{columns}
\end{frame}
\begin{frame}
\frametitle{\textbf{Conceptos de Jenkins}}
\small
\begin{columns}[T]
\begin{column}{0.49\linewidth}
\begin{block}{Piezas}
\begin{itemize}
\item \textbf{Controller}: coordina jobs, UI, credenciales y cola.
\item \textbf{Nodo/Agente}: m\'aquina (VM, contenedor, bare metal) donde \emph{se ejecuta} el trabajo.
\item \textbf{Executor}: \# de trabajos simult\'aneos que un agente puede correr.
\item \textbf{Workspace}: carpeta donde Jenkins hace el checkout y trabaja.
\end{itemize}
\end{block}
\end{column}
\begin{column}{0.49\linewidth}
\begin{block}{Pipeline}
\begin{itemize}
\item \textbf{Job/Pipeline}: definici\'on del flujo (en este taller: \texttt{Jenkinsfile.*}).
\item \textbf{Stage}: fase visible (lint, test, build, deploy...).
\item \textbf{Step}: acci\'on concreta dentro de un stage.
\item \textbf{Artefactos}: salidas versionadas (builds, reports) que Jenkins guarda/publica.
\end{itemize}
\end{block}
\end{column}
\end{columns}
\vspace{0.3em}
\begin{mybox}
\begin{itemize}
\item[\ding{229}] En \textbf{nuestro caso}: Jenkins corre en \textbf{bare metal} y el \textbf{controller} y el \textbf{agente} son la \textbf{misma m\'aquina}; los pipelines ejecutan comandos lanzando \textbf{contenedores Docker}.
\end{itemize}
\end{mybox}
\end{frame}

View File

@@ -0,0 +1,67 @@
\section{Instalaci\'on inicial}
\begin{frame}
\frametitle{\textbf{Arquitectura del repo}}
\begin{itemize}
\item API: \texttt{backend/} (FastAPI)
\item Front: \texttt{frontend/} (Svelte + Vite, base path \texttt{/taller/})
\item Orquestaci\'on: \texttt{docker-compose.yml} (frontend + backend)
\item Jenkins:
\begin{itemize}
\item Pipelines: \texttt{Jenkinsfile.ci} y \texttt{Jenkinsfile.cd}
\end{itemize}
\end{itemize}
\vspace{0.15in}
\begin{mybox}
\begin{itemize}
\item[\ding{229}] Importante: el frontend usa un \textbf{base path} \texttt{/taller/}.
\end{itemize}
\end{mybox}
\end{frame}
\begin{frame}
\frametitle{\textbf{Uf seguro que instalar el Jenkins ese es muy difícil...}}
\textbf{¿Seguro?}
\begin{itemize}
\item \texttt{sudo wget -O /etc/apt/keyrings/jenkins-keyring.asc \
https://pkg.jenkins.io/debian-stable/jenkins.io-2026.key}
\item \texttt{echo "deb [signed-by=/etc/apt/keyrings/jenkins-keyring.asc]" \
https://pkg.jenkins.io/debian-stable binary/ | sudo tee \
/etc/apt/sources.list.d/jenkins.list > /dev/null}
\item \texttt{sudo apt install jenkins}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Configuraci\'on inicial y plugins}}
\begin{itemize}
\item Completar el asistente inicial (admin + plugins sugeridos).
\item Configurar credenciales.
\end{itemize}
\end{frame}
\begin{frame}[fragile]
\frametitle{\textbf{Job de prueba}}
\begin{itemize}
\item Creamos un job simple para validar:
\item Ejemplo de pipeline:
\end{itemize}
\small
\begin{verbatim}
pipeline {
agent any
stages {
stage('¿Ya está, no? Ya sé de DevOps') {
steps {
sh 'uname -a'
sh 'docker version'
}
}
}
}
\end{verbatim}
\end{frame}

View File

@@ -0,0 +1,62 @@
\section{Parte pr\'actica}
\begin{frame}
\frametitle{\textbf{Objetivo de la parte pr\'actica}}
\begin{itemize}
\item Entender un pipeline de CI "de verdad": lint + tests + build.
\item Entender un pipeline de CD: test en main + build de im\'agenes + deploy.
\item Veamos en qué afectan los cambios:
\begin{itemize}
\item logs del pipeline
\item artefactos/im\'agenes Docker
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{CI: qu\'e hace Jenkinsfile.ci?}}
\begin{itemize}
\item Stage \textbf{Init}: lee autor y hash corto del commit.
\item Stage \textbf{Backend: lint \& test}:
\begin{itemize}
\item usa contenedor \texttt{python:3.11-slim}
\item crea venv, instala dev deps
\item ejecuta \texttt{ruff} y \texttt{pytest}
\end{itemize}
\item Stage \textbf{Frontend: check \& build}:
\begin{itemize}
\item usa contenedor \texttt{node:20-slim}
\item \texttt{npm install} + \texttt{npm run check} + \texttt{npm test} + \texttt{npm run build}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{CD: qu\'e hace Jenkinsfile.cd?}}
\begin{itemize}
\item Construye im\'agenes Docker con tags tipo \texttt{1.0.\$BUILD\_NUMBER}.
\item Inyecta metadatos en runtime:
\begin{itemize}
\item \texttt{APP\_VERSION}, \texttt{GIT\_COMMIT}, \texttt{COMMIT\_AUTHOR}, \texttt{BUILD\_NUMBER}
\end{itemize}
\item Despliega con \texttt{docker compose up -d} usando \texttt{BACKEND\_TAG} y \texttt{FRONTEND\_TAG}.
\end{itemize}
\vspace{0.1in}
\begin{mybox}
\begin{itemize}
\item[\ding{229}] El rollback es sencillo: si tienes tags, puedes redeployar una versi\'on anterior en segundos. CD genera artefactos (imágenes versionadas) y en nuestro caso, se ocupa del deploy también.
\end{itemize}
\end{mybox}
\end{frame}
\begin{frame}
\frametitle{\textbf{Ejercicio 1: miau}}
\end{frame}
\begin{frame}
\frametitle{\textbf{Ejercicio 2: miau 2}}
\end{frame}

View File

@@ -0,0 +1,62 @@
\section{CI/CD desde fuera (como dev)}
\begin{frame}
\frametitle{\textbf{Flujo de trabajo propuesto (developer view)}}
\begin{itemize}
\item Crear rama: \texttt{feature/...}
\item Hacer cambio peque\~no y con sentido.
\item Abrir Merge Request / Pull Request.
\item Observar checks:\\
\hspace{0.25em}-- CI corre en cada push\\
\hspace{0.25em}-- el MR/PR muestra estado verde/rojo
\item Si falla: arreglar y push de nuevo.
\item Merge a main y observar despliegue (CD).
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Propuesta de cambio para los asistentes}}
\textbf{Cambio sugerido}
\begin{itemize}
\item Cambiar el t\'itulo del hero en \texttt{frontend/src/App.svelte}. Alguien puso "UwU".
\item Nuevo texto sugerido: \textit{Taller CI/CD con Jenkins}.
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{El juego: PR en Gitea + feedback autom\'atico}}
\begin{columns}[T]
\begin{column}{0.62\linewidth}
\begin{itemize}
\item Har\'eis la PR con un \textbf{usuario gen\'erico} que os damos en nuestro \textbf{Gitea}.
\item Al abrir la PR:
\begin{itemize}
\item Jenkins lanza la \textbf{CI} (y la ver\'eis en la web de Jenkins).
\item Aparece el generalísimo \texttt{jenkins-bot}.
\end{itemize}
\item \texttt{jenkins-bot} comentar\'a en la PR:
\begin{itemize}
\item si todo ha ido bien: \textbf{verde} y a mergear.
\item si la hab\'eis liado: a mirar el log.
\end{itemize}
\end{itemize}
\end{column}
\begin{column}{0.36\linewidth}
\centering
\includegraphics[height=0.68\textheight]{images/jenkinsbot.jpg}
\end{column}
\end{columns}
\end{frame}
\begin{frame}
\frametitle{\textbf{Qu\'e observar en Jenkins al hacer el MR/PR}}
\begin{itemize}
\item Log del stage que falla (si falla): ruff, pytest, svelte-check, build...
\item En CD: tag de imagen generado (\texttt{APP\_VERSION}) y deploy.
\item En la app:
\begin{itemize}
\item \texttt{GET /health} refleja build/commit/autor.
\item \texttt{GET /builds} refleja builds recientes via Jenkins REST.
\end{itemize}
\end{itemize}
\end{frame}

View File

@@ -0,0 +1,49 @@
\section{Consideraciones y curiosidades}
\begin{frame}
\frametitle{\textbf{Triggers: webhooks vs polling}}
\begin{columns}[T]
\begin{column}{0.48\linewidth}
\textbf{Webhooks}
\begin{itemize}
\item El repositorio "avisa" a Jenkins.
\item R\'apido y eficiente.
\item El repo le envía toda la información a Jenkins (autor, commit, rama, etc.)
\item Eso tiene pinta de ser difícil... Jenkins tiene plugins para prácticamente cualquier cosa.
\end{itemize}
\end{column}
\begin{column}{0.48\linewidth}
\textbf{Polling}
\begin{itemize}
\item Jenkins pregunta cada X tiempo.
\item Absurdamente simple.
\item Si abres una PR no es inmediato, debes esperar al polling.
\end{itemize}
\end{column}
\end{columns}
\end{frame}
\begin{frame}
\frametitle{\textbf{Rollback con im\'agenes etiquetadas}}
\begin{itemize}
\item En CD generamos tags con \texttt{APP\_VERSION = 1.0.\$BUILD\_NUMBER}.
\item Si el deploy de hoyudorompe algo, puedes volver atr\'as:
\begin{itemize}
\item desplegar \texttt{BACKEND\_TAG=1.0.41 FRONTEND\_TAG=1.0.41} (ejemplo)
\item \texttt{docker compose up -d}
\end{itemize}
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Jenkins REST API: ver CI/CD sin entrar al UI}}
\begin{itemize}
\item Jenkins expone una API JSON por job/build.
\item En este repo, el backend consulta builds recientes y expone en el frontend las últimas 5 builds del CD.
\item Ideas de uso:
\begin{itemize}
\item dashboards del estado de las builds.
\item alertas.
\end{itemize}
\end{itemize}
\end{frame}

View File

@@ -0,0 +1,34 @@
\section{Cierre}
\begin{frame}
\frametitle{\textbf{Recap}}
\begin{itemize}
\item CI: automatiza validaci\'on (lint/tests/build) en cada cambio.
\item CD: produce artefactos versionados y despliega de forma reproducible.
\item Jenkins: flexible, potente, pero requiere mimos (seguridad, plugins, mantenimiento). Sin embargo, una vez lo tienes montado, el mantenimiento ya no es tan drama.
\item Ahora podr\'as entrar en los pipelines de tu futuro puesto de trabajo sin miedo a romper nada... ¿Verdad?
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Preguntas y siguientes pasos}}
\begin{columns}[T]
\begin{column}{0.62\linewidth}
\begin{itemize}
\item Preguntas.
\item ¿Ampliamos taller? Se nos ha quedado en el tintero...
\begin{itemize}
\item Registry (Harbor/Docker Hub/GHCR)
\item SonarQube + quality gates
\item An\'alisis de vulnerabilidades con Trivy
\item Despliegue con Quadlets usando Podman
\item Kubernetes (no)
\end{itemize}
\end{itemize}
\end{column}
\begin{column}{0.36\linewidth}
\centering
\includegraphics[width=0.8\linewidth]{images/kubernetes.jpeg}
\end{column}
\end{columns}
\end{frame}

View File

@@ -0,0 +1,34 @@
\section{Cierre}
\begin{frame}
\frametitle{\textbf{Recap}}
\begin{itemize}
\item CI: automatiza validaci\'on (lint/tests/build) en cada cambio.
\item CD: produce artefactos versionados y despliega de forma reproducible.
\item Jenkins: flexible, potente, pero requiere mimos (seguridad, plugins, mantenimiento). Sin embargo, una vez lo tienes montado, el mantenimiento ya no es tan drama.
\item Ahora podr\'as entrar en los pipelines de tu futuro puesto de trabajo sin miedo a romper nada... ¿Verdad?
\end{itemize}
\end{frame}
\begin{frame}
\frametitle{\textbf{Preguntas y siguientes pasos}}
\begin{columns}[T]
\begin{column}{0.62\linewidth}
\begin{itemize}
\item Preguntas.
\item ¿Ampliamos taller? Se nos ha quedado en el tintero...
\begin{itemize}
\item Registry (Harbor/Docker Hub/GHCR)
\item SonarQube + quality gates
\item An\'alisis de vulnerabilidades con Trivy
\item Despliegue con Quadlets usando Podman
\item Kubernetes (no)
\end{itemize}
\end{itemize}
\end{column}
\begin{column}{0.36\linewidth}
\centering
\includegraphics[width=0.8\linewidth]{images/kubernetes.jpeg}
\end{column}
\end{columns}
\end{frame}