Compare commits

...

3 Commits

Author SHA1 Message Date
jose-rZM
e8555453f7 Init 2026-02-14 16:58:23 +01:00
jose-rZM
cdd2618210 Update gitignore 2026-02-14 16:57:41 +01:00
jose-rZM
18f3644f82 Create gitignore 2026-02-14 16:19:23 +01:00
22 changed files with 934 additions and 0 deletions

38
.gitignore vendored Normal file
View File

@@ -0,0 +1,38 @@
# === LaTeX build files ===
*.aux
*.log
*.out
*.toc
*.nav
*.snm
*.synctex.gz
*.fls
*.fdb_latexmk
*.xdv
# === Bibliography ===
*.bbl
*.bcf
*.blg
*.run.xml
# === Beamer specific ===
*.vrb
# === Temporary files ===
*.tmp
*.bak
*.swp
*~
# === Output PDFs ===
*.pdf
# === Latexindent ===
*.indent.log
# === VS Code settings ===
.vscode/
# === OS crap ===
.DS_Store

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@@ -0,0 +1,185 @@
% Bokeron Template based on Bayes Business School Beamer theme by Emilio Luis S\'aenz Guill\'en
\ProvidesPackage{beamerthemeBokeronTemp}
\RequirePackage{silence}
\WarningsOff[mathdesign/mdbch]
\RequirePackage{etoolbox}
% Eliminate navigation symbols
\setbeamertemplate{navigation symbols}{}
% Section and subsection numbering in table of contents
\setbeamertemplate{section in toc}[sections numbered]
\setbeamertemplate{subsection in toc}[subsections numbered]
% Current position in the presentation
\useoutertheme[subsection = false]{miniframes}
\setbeamercolor{section in head/foot}{bg=BokeronBlue, fg=white}
% Captions numbering
\setbeamertemplate{caption}[numbered]
% Set slide margins
\setbeamersize{text margin left=2em, text margin right=10em}
% Set Normal Text Color
\setbeamercolor{normal text}{fg=Black}
% Structure colour (bullet points and section headings...)
\setbeamercolor{structure}{fg=BokeronBlue}
% Font
\RequirePackage{fontspec}
\setromanfont{Liberation Sans}
\IfFontExistsTF{Open Sans}{\setsansfont[Scale=MatchLowercase]{Open Sans}}{\setsansfont[Scale=MatchLowercase]{Liberation Sans}}
\RequirePackage{tikz}
% Font substitution
\DeclareFontFamilySubstitution{TS1}{\sfdefault}{lmr}
\DeclareFontFamilySubstitution{OMS}{\sfdefault}{lmr}
% Define colours
\definecolor{BokeronTitleBlue}{RGB}{0, 149, 197}
\definecolor{LighterBokeronTitleBlue}{RGB}{204,217,236}
\definecolor{BokeronBlue}{RGB}{30, 160, 186}
\definecolor{BoxLightBlue}{RGB}{173, 235, 255}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%% TITLE %%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Adjust Frame Title Position
\setbeamertemplate{frametitle}{\vskip-0.2\paperheight\insertframetitle}
% Frame Title Font
\setbeamerfont{frametitle}{family=\rmfamily,series=\mdseries,size=\Large}
% Set Color for Title-like Elements
\setbeamercolor{titlelike}{fg=BokeronTitleBlue}
% Title page
\setbeamertemplate{title page}{
\vbox{}
\vfill
\hbox{
\begin{minipage}[t]{0.4\textwidth}
{\usebeamerfont{title}\usebeamercolor[fg]{title}\inserttitle\par}
\ifx\insertsubtitle\@empty\else
{\usebeamerfont{subtitle}\usebeamercolor[fg]{subtitle}\insertsubtitle\par}
\fi
\vspace{0.1in}
{\usebeamerfont{author}\usebeamercolor[fg]{author}\insertauthor\par}
\vspace{0.1in}
{\usebeamerfont{institute}\usebeamercolor[fg]{institute}\insertinstitute\par}
{\usebeamerfont{date}\usebeamercolor[fg]{date}\insertdate\par}
\end{minipage}
\hfill
}
\vfill
}
% Sizes
\setbeamerfont{title}{family=\rmfamily,size=\LARGE}
\setbeamerfont{author}{size=\large}
\setbeamerfont{institute}{size=\large}
% Colours
\setbeamercolor{title}{fg=white}
\setbeamercolor{subtitle}{fg=white}
\setbeamercolor{author}{fg=white}
\setbeamercolor{institute}{fg=white}
\setbeamercolor{date}{fg=white}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%% BACKGROUND %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\usebackgroundtemplate%
{%
\includegraphics[width=\paperwidth,height=\paperheight]{background/corners2.png}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%% CLOSING SLIDE %%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setbeamertemplate{endpage}{
\begin{frame}[plain]
\begin{tikzpicture}[remember picture, overlay]
% Background image
\node[at=(current page.center)] {
\includegraphics[width=\paperwidth,height=\paperheight]{background/CoverPage_OpenBokeron.png}
};
\end{tikzpicture}
\end{frame}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% ITEMIZE %%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setbeamertemplate{itemize item}{\textbullet}
\setbeamertemplate{itemize subitem}{--}
\setbeamertemplate{itemize subsubitem}{\textbullet}
% First-Level List Identations
\setlength{\leftmargini}{1.25em}
% Second-Level List Indentation
\setlength{\leftmarginii}{1em}
% Third-Level List Indentation
\setlength{\leftmarginiii}{1em}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%% FRAME TITLES %%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Normal frame title
\newcommand{\normalframetitle}{%
\setbeamertemplate{frametitle}{\vskip0.2\paperheight\insertframetitle}
\setbeamerfont{frametitle}{size=\LARGE,series=\mdseries}
\setstretch{1}
}
% Small frame title
\newcommand{\smallframetitle}{%
\setbeamertemplate{frametitle}{\vskip0.05\paperheight\insertframetitle}
\setbeamerfont{frametitle}{size={\fontsize{11}{15}},series=\bfseries}
}
% Smaller frame title
\newcommand{\smallerframetitle}{
\setbeamertemplate{frametitle}{\vskip0.025\paperheight\insertframetitle}
\setbeamerfont{frametitle}{size={\fontsize{8}{12}},series=\bfseries}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%% TABLES %%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\renewcommand{\arraystretch}{1.3}
\newcommand{\tableheadrow}{\rowcolor{BokeronBlue}}
\newcommand{\tableheadcol}[1]{{\bfseries\color{white}#1}}
\AtBeginEnvironment{tabular}{\color{black}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%% BLOCK %%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setbeamerfont{block title}{family=\rmfamily,size=\large}
\setbeamercolor{block title}{fg=white,bg=BokeronTitleBlue}
\setbeamercolor{block body}{bg=LighterBokeronTitleBlue}
\setbeamertemplate{blocks}[rounded][shadow=false]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% FOOTLINE %%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\setbeamertemplate{footline}{%
\vskip0.15\paperheight
}
\setbeamercolor{myfootlinecolor}{bg=white,fg=BokeronBlue}
\setbeamertemplate{footline}
{%
\begin{beamercolorbox}[colsep=1.5pt, ht=3.5ex, dp=1.125ex, leftskip=.3cm, rightskip=.3cm plus1fil]{myfootlinecolor}
\leavevmode{\usebeamerfont{author in head/foot}\insertshortauthor}%
\hfill
{\usebeamerfont{institute in head/foot}\insertshortinstitute}%
\hfill%
{\usebeamerfont{title in head/foot}\insertframenumber/\inserttotalframenumber}
\end{beamercolorbox}
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%% OTHERS %%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Disable warning on \author
\pdfstringdefDisableCommands{%
\def\\{}%
\def\texttt#1{<#1>}%
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

179
slides/main.bbl-SAVE-ERROR Normal file
View File

@@ -0,0 +1,179 @@
% $ biblatex auxiliary file $
% $ biblatex bbl format version 3.3 $
% Do not modify the above lines!
%
% This is an auxiliary file used by the 'biblatex' package.
% This file may safely be deleted. It will be recreated by
% biber as required.
%
\begingroup
\makeatletter
\@ifundefined{ver@biblatex.sty}
{\@latex@error
{Missing 'biblatex' package}
{The bibliography requires the 'biblatex' package.}
\aftergroup\endinput}
{}
\endgroup
\refsection{0}
\datalist[entry]{apa/apasortcite//global/global/global}
\entry{fowler_ci}{online}{}{}
\name{author}{1}{}{%
{{un=0,uniquepart=base,hash=312ac886938a9b2be4f8eb607567fe4c}{%
family={Fowler},
familyi={F\bibinitperiod},
given={Martin},
giveni={M\bibinitperiod},
givenun=0}}%
}
\strng{namehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{fullhash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{fullhashraw}{312ac886938a9b2be4f8eb607567fe4c}
\strng{bibnamehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authorbibnamehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authornamehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authorfullhash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authorfullhashraw}{312ac886938a9b2be4f8eb607567fe4c}
\field{sortinit}{F}
\field{sortinithash}{2638baaa20439f1b5a8f80c6c08a13b4}
\field{extradatescope}{labelyear}
\field{labeldatesource}{}
\true{uniqueprimaryauthor}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Continuous Integration}
\field{urlday}{18}
\field{urlmonth}{1}
\field{urlyear}{2026}
\field{year}{2023}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://martinfowler.com/articles/continuousIntegration.html
\endverb
\verb{url}
\verb https://martinfowler.com/articles/continuousIntegration.html
\endverb
\endentry
\entry{humble2010continuous}{book}{}{}
\name{author}{2}{}{%
{{un=0,uniquepart=base,hash=9e89d796d06f74d6551850b1c3bff900}{%
family={Humble},
familyi={H\bibinitperiod},
given={Jez},
giveni={J\bibinitperiod},
givenun=0}}%
{{un=0,uniquepart=base,hash=e88f486e16133b897ffb346a75f56d96}{%
family={Farley},
familyi={F\bibinitperiod},
given={David},
giveni={D\bibinitperiod},
givenun=0}}%
}
\list{location}{1}{%
{Boston}%
}
\list{publisher}{1}{%
{Addison-Wesley}%
}
\strng{namehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{fullhash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{fullhashraw}{06b8a2e32b3cda03592e143a7f761e36}
\strng{bibnamehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authorbibnamehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authornamehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authorfullhash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authorfullhashraw}{06b8a2e32b3cda03592e143a7f761e36}
\field{sortinit}{H}
\field{sortinithash}{23a3aa7c24e56cfa16945d55545109b5}
\field{extradatescope}{labelyear}
\field{labeldatesource}{}
\true{uniqueprimaryauthor}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation}
\field{year}{2010}
\endentry
\enddatalist
\datalist[entry]{apa/global//global/global/global}
\entry{fowler_ci}{online}{}{}
\name{author}{1}{}{%
{{un=0,uniquepart=base,hash=312ac886938a9b2be4f8eb607567fe4c}{%
family={Fowler},
familyi={F\bibinitperiod},
given={Martin},
giveni={M\bibinitperiod},
givenun=0}}%
}
\strng{namehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{fullhash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{fullhashraw}{312ac886938a9b2be4f8eb607567fe4c}
\strng{bibnamehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authorbibnamehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authornamehash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authorfullhash}{312ac886938a9b2be4f8eb607567fe4c}
\strng{authorfullhashraw}{312ac886938a9b2be4f8eb607567fe4c}
\field{sortinit}{F}
\field{sortinithash}{2638baaa20439f1b5a8f80c6c08a13b4}
\field{extradatescope}{labelyear}
\field{labeldatesource}{}
\true{uniqueprimaryauthor}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Continuous Integration}
\field{urlday}{18}
\field{urlmonth}{1}
\field{urlyear}{2026}
\field{year}{2023}
\field{urldateera}{ce}
\verb{urlraw}
\verb https://martinfowler.com/articles/continuousIntegration.html
\endverb
\verb{url}
\verb https://martinfowler.com/articles/continuousIntegration.html
\endverb
\endentry
\entry{humble2010continuous}{book}{}{}
\name{author}{2}{}{%
{{un=0,uniquepart=base,hash=9e89d796d06f74d6551850b1c3bff900}{%
family={Humble},
familyi={H\bibinitperiod},
given={Jez},
giveni={J\bibinitperiod},
givenun=0}}%
{{un=0,uniquepart=base,hash=e88f486e16133b897ffb346a75f56d96}{%
family={Farley},
familyi={F\bibinitperiod},
given={David},
giveni={D\bibinitperiod},
givenun=0}}%
}
\list{location}{1}{%
{Boston}%
}
\list{publisher}{1}{%
{Addison-Wesley}%
}
\strng{namehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{fullhash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{fullhashraw}{06b8a2e32b3cda03592e143a7f761e36}
\strng{bibnamehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authorbibnamehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authornamehash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authorfullhash}{06b8a2e32b3cda03592e143a7f761e36}
\strng{authorfullhashraw}{06b8a2e32b3cda03592e143a7f761e36}
\field{sortinit}{H}
\field{sortinithash}{23a3aa7c24e56cfa16945d55545109b5}
\field{extradatescope}{labelyear}
\field{labeldatesource}{}
\true{uniqueprimaryauthor}
\field{labelnamesource}{author}
\field{labeltitlesource}{title}
\field{title}{Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation}
\field{year}{2010}
\endentry
\enddatalist
\endrefsection
\endinput

92
slides/main.tex Normal file
View File

@@ -0,0 +1,92 @@
%% Requires compilation with XeLaTeX or LuaLaTeX
\documentclass[10pt,table,dvipsnames, t, compress, aspectratio=169]{beamer}
%% Packages
\makeatletter
\def\input@path{{./}{slides/}}
\makeatother
\usepackage{tikz}
\usetikzlibrary{tikzmark,calc,arrows.meta,shapes.arrows,decorations.pathreplacing}
\usepackage{caption, subcaption, bbm, mathtools, amsmath, lmodern}
\usepackage{graphicx, amssymb, cancel, pifont, bm}
\usefonttheme[onlymath]{serif}
% Bibliography
\usepackage[style=apa, backend=biber]{biblatex}
\addbibresource{sn-bibliography.bib}
% Theme
\usetheme{BokeronTemp}
% Hyperref
\usepackage{hyperref}
% url in blue
\newcommand{\bluehref}[2]{%
\begingroup
\hypersetup{urlcolor=blue}%
\href{#1}{\color{blue}#2}%
\endgroup
}
% Color box
\usepackage{xcolor}
\usepackage{tcolorbox}
\newtcolorbox{mybox}{colback=BoxLightBlue, colframe=BokeronBlue, width=0.9\linewidth}
%% Title
\title{\textbf{\large Taller CI/CD con Jenkins}}
\subtitle{De 0 a deployment con FastAPI + Svelte (y Docker)}
\author{Open Bokeron}
\institute[Open Bokeron]{Open Bokeron\\ \bluehref{https://openbokeron.uma.es}{openbokeron.uma.es}}
\date{18/01/2026}
\begin{document}
%----------------------------------------------------------------------------------------
% TITLE SLIDES
%----------------------------------------------------------------------------------------
{
\usebackgroundtemplate{
\begin{tikzpicture}[remember picture, overlay]
\node[at=(current page.center)] {
\includegraphics[width=\paperwidth,height=\paperheight,keepaspectratio]{background/OpenBokeronPresentation_Cover.jpg}
};
\end{tikzpicture}
}
\begin{frame}[plain]
\titlepage
\end{frame}
}
\smallframetitle
\begin{frame}{Agenda}
\tableofcontents
\end{frame}
% Current section
\AtBeginSection[ ]
{
\begin{frame}{}
\tableofcontents[currentsection,currentsubsection,
sectionstyle=show/shaded]
\end{frame}
}
\input{sections/01_Introduccion}
\input{sections/02_Instalacion}
\input{sections/03_Pipeline}
\input{sections/04_DesdeFuera}
\input{sections/05_Consideraciones}
\input{sections/06_Cierre}
\AtEndDocument{\usebeamertemplate{endpage}}
\end{document}

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}

View File

@@ -0,0 +1,31 @@
@book{humble2010continuous,
author = {Humble, Jez and Farley, David},
title = {Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation},
year = {2010},
publisher = {Addison-Wesley},
address = {Boston},
}
@online{jenkins_docs,
author = {{Jenkins Project}},
title = {Jenkins User Documentation},
year = {2026},
url = {https://www.jenkins.io/doc/},
urldate = {2026-01-18},
}
@online{github_actions_docs,
author = {{GitHub}},
title = {GitHub Actions Documentation},
year = {2026},
url = {https://docs.github.com/actions},
urldate = {2026-01-18},
}
@online{fowler_ci,
author = {Fowler, Martin},
title = {Continuous Integration},
year = {2023},
url = {https://martinfowler.com/articles/continuousIntegration.html},
urldate = {2026-01-18},
}