diff --git a/slides/background/CoverPage_OpenBokeron.png b/slides/background/CoverPage_OpenBokeron.png new file mode 100644 index 0000000..78be0e0 Binary files /dev/null and b/slides/background/CoverPage_OpenBokeron.png differ diff --git a/slides/background/OpenBokeronPresentation_Cover.jpg b/slides/background/OpenBokeronPresentation_Cover.jpg new file mode 100644 index 0000000..09d4d37 Binary files /dev/null and b/slides/background/OpenBokeronPresentation_Cover.jpg differ diff --git a/slides/background/corners.jpg b/slides/background/corners.jpg new file mode 100644 index 0000000..6f81229 Binary files /dev/null and b/slides/background/corners.jpg differ diff --git a/slides/background/corners2.png b/slides/background/corners2.png new file mode 100644 index 0000000..6980c6e Binary files /dev/null and b/slides/background/corners2.png differ diff --git a/slides/beamerthemeBokeronTemp.sty b/slides/beamerthemeBokeronTemp.sty new file mode 100644 index 0000000..a8e2d6e --- /dev/null +++ b/slides/beamerthemeBokeronTemp.sty @@ -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>}% +} diff --git a/slides/images/LogoOpenBokeron.png b/slides/images/LogoOpenBokeron.png new file mode 100644 index 0000000..17e0bdb Binary files /dev/null and b/slides/images/LogoOpenBokeron.png differ diff --git a/slides/images/jenkins_failing_again.jpg b/slides/images/jenkins_failing_again.jpg new file mode 100644 index 0000000..b2ea3e8 Binary files /dev/null and b/slides/images/jenkins_failing_again.jpg differ diff --git a/slides/images/jenkins_smile.jpg b/slides/images/jenkins_smile.jpg new file mode 100644 index 0000000..f624654 Binary files /dev/null and b/slides/images/jenkins_smile.jpg differ diff --git a/slides/images/jenkinsbot.jpg b/slides/images/jenkinsbot.jpg new file mode 100644 index 0000000..f5f29c6 Binary files /dev/null and b/slides/images/jenkinsbot.jpg differ diff --git a/slides/images/kubernetes.jpeg b/slides/images/kubernetes.jpeg new file mode 100644 index 0000000..c98a7c4 Binary files /dev/null and b/slides/images/kubernetes.jpeg differ diff --git a/slides/images/tenna_spray_github.jpg b/slides/images/tenna_spray_github.jpg new file mode 100644 index 0000000..d4b2712 Binary files /dev/null and b/slides/images/tenna_spray_github.jpg differ diff --git a/slides/main.bbl-SAVE-ERROR b/slides/main.bbl-SAVE-ERROR new file mode 100644 index 0000000..ea32631 --- /dev/null +++ b/slides/main.bbl-SAVE-ERROR @@ -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 + diff --git a/slides/main.tex b/slides/main.tex new file mode 100644 index 0000000..ab268dc --- /dev/null +++ b/slides/main.tex @@ -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} diff --git a/slides/sections/01_Introduccion.tex b/slides/sections/01_Introduccion.tex new file mode 100644 index 0000000..3154394 --- /dev/null +++ b/slides/sections/01_Introduccion.tex @@ -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} diff --git a/slides/sections/02_Instalacion.tex b/slides/sections/02_Instalacion.tex new file mode 100644 index 0000000..d8e7e13 --- /dev/null +++ b/slides/sections/02_Instalacion.tex @@ -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} diff --git a/slides/sections/03_Pipeline.tex b/slides/sections/03_Pipeline.tex new file mode 100644 index 0000000..44839ea --- /dev/null +++ b/slides/sections/03_Pipeline.tex @@ -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} diff --git a/slides/sections/04_DesdeFuera.tex b/slides/sections/04_DesdeFuera.tex new file mode 100644 index 0000000..0ae79f9 --- /dev/null +++ b/slides/sections/04_DesdeFuera.tex @@ -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} diff --git a/slides/sections/05_Consideraciones.tex b/slides/sections/05_Consideraciones.tex new file mode 100644 index 0000000..94d3132 --- /dev/null +++ b/slides/sections/05_Consideraciones.tex @@ -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} diff --git a/slides/sections/06_Cierre.tex b/slides/sections/06_Cierre.tex new file mode 100644 index 0000000..4aef7d5 --- /dev/null +++ b/slides/sections/06_Cierre.tex @@ -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} diff --git a/slides/sections/__latexindent_temp_06_Cierre.tex b/slides/sections/__latexindent_temp_06_Cierre.tex new file mode 100644 index 0000000..4aef7d5 --- /dev/null +++ b/slides/sections/__latexindent_temp_06_Cierre.tex @@ -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} diff --git a/slides/sn-bibliography.bib b/slides/sn-bibliography.bib new file mode 100644 index 0000000..36ab44f --- /dev/null +++ b/slides/sn-bibliography.bib @@ -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}, +}