Volver al catálogo
Season 24 14 Episodios 1h 0m 2026

GitHub Actions

Edición 2026. Un análisis técnico exhaustivo de GitHub Actions, que cubre su modelo de ejecución, flujos de trabajo avanzados, control de entornos, runners y seguridad. Edición 2026.

CI/CD DevOps
GitHub Actions
Reproduciendo ahora
Click play to start
0:00
0:00
1
El caso empresarial para GitHub Actions
Una comparación ejecutiva de GitHub Actions frente a herramientas tradicionales de CI/CD como Azure DevOps y GCP Cloud Build. Exploramos las ventajas arquitectónicas de la automatización basada en eventos que convive con tu código fuente.
5m 25s
2
El modelo mental de ejecución
Un desglose técnico de la jerarquía de GitHub Actions. Comprende la relación crítica entre Workflows, Jobs, Steps y Actions.
3m 59s
3
Triggers basados en eventos y filtros
Análisis en profundidad de los triggers de eventos de GitHub Actions. Aprende a configurar filtros precisos de rutas y ramas para controlar exactamente cuándo se ejecutan tus workflows.
5m 01s
4
Evaluación de estado con variables y contextos
Comprende las diferencias críticas entre las variables de entorno y los Contexts de GitHub. Aprende cuándo se evalúa cada uno durante el ciclo de vida del workflow.
3m 54s
5
El límite de seguridad: Secrets y GITHUB_TOKEN
Un vistazo técnico a la gestión de secrets en GitHub Actions. Exploramos el GITHUB_TOKEN efímero y la jerarquía de secrets de repositorio y organización.
4m 44s
6
Optimizando datos: Caching frente a Artifacts
Aprende la diferencia exacta entre Dependency Caching y Workflow Artifacts. Deja de ralentizar tus builds con el mecanismo de almacenamiento equivocado.
4m 37s
7
Controlando el flujo con concurrencia
Domina el control de ejecución de los workflows. Aprende a usar la palabra clave concurrency para cancelar ejecuciones redundantes y evitar despliegues superpuestos.
4m 05s
8
Controlando despliegues con Environments
Descubre cómo mapear tus workflows de GitHub Actions a objetivos de despliegue externos usando Environments para imponer aprobaciones manuales y aislar secrets.
4m 33s
9
Acceso a la nube sin contraseñas mediante OIDC
Elimina las credenciales de la nube de larga duración de tus repositorios. Aprende a usar OpenID Connect (OIDC) para autenticar de forma segura GitHub Actions con AWS, Azure y GCP.
4m 26s
10
Escalando pipelines DRY
Compara Reusable Workflows y Composite Actions. Aprende qué mecanismo elegir al estandarizar tus pipelines de CI/CD en toda una empresa.
4m 07s
11
Creando Custom Actions: Docker frente a JavaScript
Toma el control de tu pipeline creando Custom Actions. Exploramos los pros y contras de rendimiento y compatibilidad entre las actions de JavaScript y de contenedores Docker.
4m 09s
12
Gestión de flotas: Runners Hosted frente a Self-Hosted
Navega por los límites de los runners de GitHub. Aprende cuándo depender de máquinas alojadas en GitHub y cuándo tu arquitectura exige runners Self-Hosted.
3m 42s
13
Escalado en Kubernetes: Actions Runner Controller
Descubre cómo el Actions Runner Controller (ARC) orquesta flotas de runners efímeros y de autoescalado de forma nativa en tus clústeres de Kubernetes.
3m 36s
14
Integridad de la cadena de suministro con Attestations
Protege la cadena de suministro de tu software. Aprende a generar attestations de artefactos y procedencia infalsificables directamente desde tus workflows.
4m 15s

Episodios

1

El caso empresarial para GitHub Actions

5m 25s

Una comparación ejecutiva de GitHub Actions frente a herramientas tradicionales de CI/CD como Azure DevOps y GCP Cloud Build. Exploramos las ventajas arquitectónicas de la automatización basada en eventos que convive con tu código fuente.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 1 de 14. La mayoría de las builds empresariales se tratan como algo secundario en una herramienta completamente aparte. Haces push del código, se produce un context switch, y esperas que un webhook se dispare correctamente en algún servidor remoto. El caso de uso empresarial de GitHub Actions resuelve este problema moviendo la ejecución de tu pipeline directamente junto a tu código fuente. El error más común es tratar a GitHub Actions estrictamente como una herramienta de CI/CD, como si fuera solo un reemplazo moderno de Jenkins. Llámalo por lo que realmente es. Es un motor de automatización flexible, event-driven, profundamente integrado en tu repositorio. Responde a prácticamente cualquier cambio de estado dentro de la plataforma de control de versiones. Fíjate en un setup empresarial estándar usando herramientas como GCP Cloud Build o Azure DevOps. El código fuente vive en GitHub, pero la ejecución ocurre en otro lugar. Esto requiere gestionar service accounts multiplataforma, mantener webhooks frágiles y sincronizar controles de acceso entre múltiples proveedores. Cuando un pipeline falla, los desarrolladores salen de su repositorio, hacen login en una consola cloud independiente y rebuscan entre logs desconectados de su pull request. La proximidad al código elimina esta fricción. Cuando tu motor de automatización está integrado directamente en la plataforma de control de versiones, eliminas el coste de integración. La identidad del usuario, las branch protection rules y el contexto del cambio de código son entendidos de forma nativa por la instancia de computación que ejecuta tu pipeline. Piensa en un pipeline tradicional en una herramienta de cloud build independiente. Normalmente, escucha un commit de código, se descarga el código fuente, hace la build de un artefacto y reporta un simple estado de pass o fail de vuelta al repositorio. Toda su visión del mundo se limita a la compilación de código y al deploy. Una GitHub Action opera a una escala mucho mayor. Como entiende de forma nativa los eventos del repositorio, puedes construir un workflow que se dispare en el momento exacto en que se abre una pull request. En una sola ejecución fluida, puede leer el payload del evento, asignar a los ingenieros senior adecuados como reviewers basándose en qué archivos específicos han cambiado, ejecutar un linter y publicar cualquier fallo de sintaxis directamente como comentarios inline en las líneas de código exactas. El desarrollador resuelve los problemas sin salir nunca de la vista de la pull request. Automatizas el workflow en sí, no solo el artefacto de la build. Desde un punto de vista arquitectónico, esto convierte tu repositorio de un volumen de almacenamiento pasivo a un controlador activo. Dejas de automatizar solo tus deploys y empiezas a automatizar tu gobernanza operativa. Si una issue se etiqueta con una label crítica, una action puede aprovisionar automáticamente una base de datos de testing temporal. Si un escaneo de dependencias automatizado detecta una vulnerabilidad de seguridad, una action puede abrir al instante un ticket de seguimiento, asignarlo al equipo de seguridad y hacer ping a tu sistema de chat interno. Todo utiliza exactamente la misma infraestructura de computación subyacente. En una organización grande, puedes definir estos workflows de forma centralizada y compartirlos entre cientos de repositorios. Si tu equipo de seguridad actualiza la política de escaneo de contenedores requerida, actualizan una action central. Cada repositorio que llama a esa action hereda inmediatamente el nuevo requisito de seguridad sin que los equipos de producto individuales tengan que reescribir sus scripts del pipeline. Esta centralización proporciona una ventaja enorme para los equipos de platform engineering. Aquí está la clave. La arquitectura empresarial lucha constantemente con el tool sprawl. Cada nueva herramienta de pipeline añade carga cognitiva, requiere mantenimiento dedicado y crea otra superficie de exposición para las políticas de seguridad. Al consolidar tu capa de ejecución directamente en GitHub, estandarizas cómo se comporta cada repositorio. Exactamente la misma infraestructura que hace el deploy de tus microservicios en producción también gestiona el mantenimiento de tu repositorio. La mayor ventaja arquitectónica de GitHub Actions no es que tenga build agents más rápidos o mejor caché. Es que elimina la frontera entre el workflow del desarrollador y el sistema de integración continua. Si estos episodios te resultan útiles y quieres apoyar el programa, puedes buscar DevStoriesEU en Patreon. ¡Gracias por escuchar y happy coding a todos!
2

El modelo mental de ejecución

3m 59s

Un desglose técnico de la jerarquía de GitHub Actions. Comprende la relación crítica entre Workflows, Jobs, Steps y Actions.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 2 de 14. Un workflow no es un simple script que se ejecuta de principio a fin. Es una máquina de estados paralelizada que distribuye tu código entre varias máquinas virtuales exactamente al mismo tiempo. Si escribes tu configuración esperando un único proceso continuo, tus datos desaparecerán a mitad de camino. Entender el modelo mental de ejecución evita que esto pase. En el nivel más alto está el workflow. Es un proceso automatizado y configurable, definido en un fichero YAML dentro de tu repositorio. Contiene el plano de lo que debe ocurrir cuando se activa. Un workflow en sí mismo no ejecuta código directamente. Orquesta el siguiente nivel inferior. Un workflow contiene uno o más jobs. Aquí es donde se establecen los límites físicos de ejecución. Por defecto, cada job en un workflow se ejecuta en paralelo. Si defines un job de build y un job de test, GitHub levanta una máquina virtual independiente, llamada runner, para cada job. Arrancan exactamente al mismo tiempo. No saben nada el uno del otro. El job de build se ejecuta en el runner A, y el job de test se ejecuta en el runner B. Como se ejecutan en máquinas virtuales completamente distintas, no comparten el sistema de archivos, las variables de entorno ni la memoria. Dentro de un job, el modelo de ejecución cambia por completo. Un job está formado por una secuencia de steps. Mientras que los jobs se ejecutan en paralelo en distintas máquinas, los steps se ejecutan de forma secuencial exactamente en la misma máquina. El step uno termina antes de que empiece el step dos. Como se ejecutan en el mismo runner, los steps comparten datos. En nuestro job de build, el step uno podría descargar el código de tu aplicación. El step dos lo compila. El step tres lo empaqueta. Como estos steps ocurren en la misma máquina virtual, el step dos lee de forma nativa los ficheros descargados por el step uno. Esto nos lleva a un punto de confusión muy común. La gente suele confundir los steps con las actions. Un step no es una action. Un step es simplemente una unidad de ejecución dentro de un job. Es un hueco en tu secuencia. Puedes rellenar ese hueco de dos maneras. Puedes escribir un comando de shell puro, o puedes llamar a una action. Una action es un bloque de código empaquetado y reutilizable, diseñado para realizar una tarea compleja específica, como configurar el entorno de un lenguaje. Una action es el payload reutilizable. El step es el contenedor que la aloja dentro de la secuencia del job. Volvamos a ver nuestro escenario de build y test. El workflow arranca. Dos runners se inician simultáneamente. En el runner de build, los steps se ejecutan uno a uno. El primer step llama a una action de checkout para descargar el repositorio. El segundo step ejecuta un comando de shell para compilar el código. Estos steps comparten el espacio del disco local sin problemas. Mientras tanto, en el runner de test, se está ejecutando una secuencia de steps completamente distinta de forma aislada. Si tu job de test necesita el resultado compilado del job de build, no puede simplemente mirar en el disco duro. El job de test está en un servidor distinto. Aquí está la clave. El límite de un job es el límite físico de la máquina virtual, lo que significa que escribir un workflow de GitHub Actions es, en realidad, un ejercicio de mapeo de infraestructura. Gracias por estar ahí. Espero que hayas aprendido algo nuevo.
3

Triggers basados en eventos y filtros

5m 01s

Análisis en profundidad de los triggers de eventos de GitHub Actions. Aprende a configurar filtros precisos de rutas y ramas para controlar exactamente cuándo se ejecutan tus workflows.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 3 de 14. Se hace push de un único commit automatizado a tu repositorio. Ese commit activa un workflow. Ese workflow hace otro commit, que vuelve a activar el workflow. En cuestión de minutos, te has fundido cientos de run minutes en un bucle infinito accidental. La forma de evitar esto, y controlar exactamente cuándo se ejecutan tus workflows, es mediante triggers y filtros basados en eventos. Cada workflow de GitHub Actions empieza con la palabra clave on. Esto le dice a GitHub qué eventos deben despertar tu workflow. Puedes especificar un solo evento, como un push, o varios eventos en un array. Pero los eventos no siempre son triggers simples. Algunos eventos, como los issues o las pull requests, tienen múltiples tipos de actividad. Cuando un issue se abre, se edita o se cierra, dispara el mismo evento base. Si simplemente escribes que un workflow se ejecuta con issues, se ejecutará para todas esas actividades. Para ser preciso, especificas los tipos de actividad exactos. Puedes decirle a GitHub que solo ejecute el workflow cuando se abra un issue, ignorando las ediciones o cuando se cierre. Esto ahorra run minutes y evita procesamiento innecesario. Los tipos de actividad gestionan qué ha pasado, pero los filtros de branch y path gestionan dónde ha pasado. Cuando lanzas un trigger de un workflow en un push o pull request, normalmente no quieres que se ejecute en cada branch. Usas filtros de branch para apuntar a destinos específicos, como la branch main o las branches de release. También puedes filtrar por paths. Si un desarrollador corrige un error tipográfico en un archivo readme, no necesitas ejecutar toda tu test suite. Los filtros de path te permiten incluir o excluir archivos y directorios específicos. Aquí está la clave. Cuando mezclas filtros de path positivos y negativos, el orden en el que los escribes importa. Un filtro positivo le dice al workflow que se ejecute si cambia un path específico. Un filtro negativo, indicado por un signo de exclamación, le dice al workflow que ignore los cambios en un path. GitHub los evalúa de arriba a abajo. Si pones un filtro negativo después de un filtro positivo, el filtro negativo anula al positivo para cualquier archivo que coincida. Pongamos esto en práctica. Quieres lanzar un trigger para una build cada vez que se hace push de código a la branch main, pero quieres ahorrar dinero ignorando los cambios que solo afectan a la documentación. Debajo de la palabra clave on, especificas el evento push. Debajo de eso, defines un filtro de branch para main. Luego, añades un filtro de paths. Puedes empezar con un filtro positivo para todo, usando un wildcard. Justo debajo, añades un filtro negativo para la carpeta docs, apuntando específicamente a los archivos markdown. Si un commit solo modifica un archivo markdown en la carpeta docs, el workflow se queda dormido. Si un commit modifica un archivo python y un archivo markdown, el workflow se ejecuta porque el archivo python activa el filtro positivo. Ahora volvamos a ese bucle infinito. Cuando tu workflow se ejecuta, GitHub proporciona una credencial temporal llamada GitHub Token para autenticarse contra el repositorio. Por diseño, cualquier evento lanzado usando este token específico no creará nuevos workflow runs. Este es un mecanismo de seguridad integrado para evitar bucles recursivos. Sin embargo, si tu workflow usa un Personal Access Token para hacer commit de código o push de tags, esa red de seguridad desaparece. El nuevo commit activará otro workflow run, que hace otro commit, creando un bucle infinito. Si tienes que usar un Personal Access Token, tienes que ser extremadamente disciplinado con tus filtros de branch y path para asegurarte de que el commit automatizado no cumpla las condiciones del trigger para el workflow. La forma más efectiva de optimizar tus costes de computación no es escribir código más rápido, sino simplemente asegurarte de que tus workflows solo se ejecuten cuando sea absolutamente necesario. Gracias por escuchar, ¡feliz programación a todos!
4

Evaluación de estado con variables y contextos

3m 54s

Comprende las diferencias críticas entre las variables de entorno y los Contexts de GitHub. Aprende cuándo se evalúa cada uno durante el ciclo de vida del workflow.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 4 de 14. Intentas usar una variable de entorno del runner para determinar si un job debe iniciarse, y tu pipeline falla antes incluso de que arranque una máquina. Estás seguro de que la variable existe, pero GitHub actúa como si estuviera vacía. El problema no es tu variable, es tu timing. Para solucionarlo, tenemos que hablar sobre la evaluación del estado con variables y contextos. En GitHub Actions, el estado de tu workflow se evalúa en dos fases completamente separadas, que ocurren en dos lugares completamente diferentes. Esta es la diferencia principal entre un contexto y una variable de entorno. Veamos primero los contextos. Los contextos son conjuntos de información que GitHub evalúa directamente, antes incluso de que tu workflow se envíe a un runner. Contienen datos sobre la ejecución del workflow, el repositorio, el evento webhook que activó la ejecución y el usuario que la inició. Como GitHub evalúa los contextos inmediatamente, puedes usarlos para controlar la estructura de tu pipeline. Accedes a un contexto usando una sintaxis de expresión específica, normalmente un signo de dólar seguido de dobles llaves que contienen el nombre del contexto. Por otro lado, las variables de entorno por defecto se evalúan más tarde, en la propia máquina del runner que ejecuta tu job. Cuando el runner arranca, establece automáticamente varias variables de entorno por defecto, como el nombre del repositorio o la rama actual. Accedes a ellas exactamente igual que lo harías en un script normal de bash o PowerShell. También puedes definir tus propias variables de entorno usando la clave env en tu archivo del workflow. Puedes asociar la clave env a un workflow entero, a un solo job o a un step específico. Aquí está la clave. El ciclo de vida dicta qué puedes usar y dónde. Un error común es intentar usar una variable de entorno del runner dentro de un condicional if a nivel de job. Si le dices a un job que se ejecute solo si una variable de entorno de bash específica es igual a un valor determinado, el workflow fallará. El runner aún no ha arrancado. La máquina no existe, así que la variable de entorno tampoco existe. Para tomar decisiones antes de que el runner arranque, tienes que usar un contexto. Veamos un caso práctico. Quieres que un job de deploy se ejecute solo si el código se ha mergeado en la rama main. A nivel de job, escribes un condicional if. Usas la expresión de contexto para comprobar si el contexto github punto ref es igual al string refs barra heads barra main. GitHub evalúa esto al instante. Si es true, GitHub aprovisiona un runner y le envía el job. Una vez que el job está en el runner y tus steps empiezan a ejecutarse, pasas a las variables de entorno. Dentro de un step de script de bash en ese mismo job, puede que necesites saber el nombre de la rama para etiquetar un build artifact. Aquí, simplemente escribes un signo de dólar seguido de GITHUB guion bajo REF. El runner lee esto del entorno de su sistema operativo local. Estás haciendo referencia exactamente al mismo dato, el nombre de la rama, pero accedes a él a través de mecanismos completamente diferentes dependiendo de dónde se encuentre la ejecución en ese momento. Los contextos dirigen el workflow en los servidores de GitHub. Las variables de entorno controlan los scripts de ejecución en el runner. Si alguna vez te encuentras peleando con variables vacías en la lógica de tu workflow, pregúntate si la máquina que evalúa esa lógica realmente ha arrancado ya. Como siempre, gracias por escuchar. Nos vemos en el próximo episodio.
5

El límite de seguridad: Secrets y GITHUB_TOKEN

4m 44s

Un vistazo técnico a la gestión de secrets en GitHub Actions. Exploramos el GITHUB_TOKEN efímero y la jerarquía de secrets de repositorio y organización.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 5 de 14. Los desarrolladores suelen crear Personal Access Tokens de larga duración para tareas básicas del repositorio, dejando credenciales permanentes en su codebase. Pero para la mayoría de las interacciones con GitHub, no necesitas crear ningún token: hay un token seguro y efímero esperándote en cada job. Este es el tema central del episodio de hoy: El límite de seguridad: secrets y GITHUB_TOKEN. Cuando lanzas un workflow, GitHub provisiona automáticamente un secret único llamado GITHUB_TOKEN. Este no es un Personal Access Token estándar. Funciona como un installation access token de corta duración de una GitHub App. Existe exclusivamente durante la duración del job del workflow. En el momento en que el job termina, o tras un máximo de 24 horas, el token caduca y se vuelve completamente inútil. Un error común es generar un Personal Access Token permanente solo para que un workflow añada un label a una issue o publique un comentario en una pull request. Esto amplía tu superficie de ataque innecesariamente. El GITHUB_TOKEN integrado ya posee los permisos necesarios para interactuar con el repositorio que lanzó el workflow. Si tu job necesita añadir un label a una issue, le pasas este token integrado al step que ejecuta la llamada a la API. Nunca se crea, almacena ni expone ninguna credencial permanente. Eso cubre la interacción con el propio GitHub. Pero tu workflow inevitablemente necesitará comunicarse con el mundo exterior. Aquí es donde entran en juego los secrets cifrados personalizados. Cuando creas un secret personalizado, no se queda como plain text en un servidor de GitHub. El valor se cifra localmente usando una sealed box de Libsodium antes incluso de transmitirse. El cifrado se basa en criptografía de clave pública. Cuando añades un secret a través de la interfaz web o la API, GitHub proporciona una clave pública. Tu cliente usa esa clave para sellar la caja. Solo la máquina virtual aislada del runner tiene la clave privada correspondiente necesaria para abrir esa caja, y solo descifra el payload en el momento exacto en que se ejecuta el job. Puedes definir estos secrets cifrados a diferentes niveles dependiendo de tu arquitectura. Los secrets a nivel de repositorio se aplican a un único codebase. Los secrets a nivel de organización te permiten compartir una única credencial, como la contraseña de una base de datos de producción, entre múltiples repositorios. Esto centraliza la gestión de credenciales, pero requiere un control estricto. Los secrets de organización usan políticas de acceso donde defines explícitamente qué repositorios tienen permiso para leer el secret. Apliquemos esto a un escenario concreto. Supongamos que tienes una contraseña de base de datos a nivel de organización necesaria para un step de migración de base de datos. No quieres que esta contraseña sea accesible para todo el workflow. GitHub Actions impone un límite de seguridad estricto aquí. Los secrets no se inyectan automáticamente en el entorno de cada step. Debes mapear explícitamente el secret a una variable de entorno en el step específico que lo requiera. Al escribir el archivo del workflow, accedes al valor cifrado usando una referencia de context específica, llamándolo desde el objeto secrets, y lo asignas a una variable de entorno local. Como lo mapeaste explícitamente, el step anterior a la migración no puede ver la contraseña, y el step posterior tampoco puede verla. Aquí está la clave. La seguridad en la automatización trata de minimizar la vida útil y limitar el alcance. Confía en el GITHUB_TOKEN efímero para las acciones internas del repositorio para evitar gestionar credenciales permanentes, y mapea estrictamente los secrets cifrados solo a los steps individuales que requieran acceso externo. Eso es todo por hoy. ¡Hasta la próxima!
6

Optimizando datos: Caching frente a Artifacts

4m 37s

Aprende la diferencia exacta entre Dependency Caching y Workflow Artifacts. Deja de ralentizar tus builds con el mecanismo de almacenamiento equivocado.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 6 de 14. Configuras un workflow con varios jobs y, para asegurarte de que el segundo job tenga todo lo necesario, empaquetas toda tu carpeta de dependencias y la pasas al siguiente. Pero de repente, tu build tarda cinco minutos más y el uso de almacenamiento se dispara. El problema es una confusión fundamental entre dos mecanismos de datos distintos, y de eso trata exactamente este episodio: Optimización de datos: Caching vs Artifacts. Vamos a aclarar la confusión de inmediato. Tanto el caching como los artifacts mueven archivos entre tus runners de GitHub Actions, pero resuelven problemas completamente diferentes. Piensa en los artifacts como lo que produce tu workflow. Piensa en el caching como lo que consume tu workflow. Si intercambias estos roles, crearás un cuello de botella silencioso en toda tu pipeline. Los artifacts son archivos generados que quieres conservar después de que finalice un job. Podría ser un binario compilado, un informe de test coverage o un archivo comprimido de tu directorio de build final. Existen por dos razones principales. Primero, para permitirte descargar el resultado final de tu workflow una vez que termine. Segundo, para pasar datos generados entre diferentes jobs dentro de la misma ejecución del workflow. Como cada job se ejecuta en una máquina virtual nueva, cualquier archivo creado en el job uno se pierde al instante cuando ese job termina, a menos que lo subas explícitamente. Al usar la action de upload artifact, guardas esos archivos en el almacenamiento de GitHub. Luego, el job dos usa la action de download artifact para traerlos a su propio workspace limpio. Ahora, compara eso con el caching de dependencias. El caching es puramente una optimización de rendimiento diseñada para acelerar tu workflow en diferentes ejecuciones a lo largo del tiempo. Cuando haces una build de software, normalmente descargas miles de dependencias de terceros, como paquetes de NPM o pip. Descargarlas por la red en cada ejecución es lento. En lugar de descargar dependencias nuevas cada vez, la action de cache guarda tu carpeta de dependencias descargada en los servidores de caché. Le asigna a esta caché una key única, casi siempre basada en el hash de tu lock file. En la ejecución del workflow de mañana, GitHub comprueba si el lock file coincide con una key existente. Si es así, restaura la carpeta directamente en tu runner en segundos, saltándose el package registry por completo. Aquí está la clave. El mayor error que puedes cometer es usar la action de upload artifact para mover una carpeta de dependencias enorme, como node modules, entre jobs. Los artifacts procesan los datos comprimiéndolos, subiéndolos, descargándolos y descomprimiéndolos. Hacer esto con decenas de miles de pequeños archivos de texto añade una latencia de red enorme a tu run time y se come las cuotas de almacenamiento de tu cuenta. Los artifacts no están diseñados para la velocidad pura; están diseñados para la transferencia segura de datos y el registro permanente. Las cachés, por otro lado, están muy optimizadas para descargar rápidamente árboles de dependencias pesados, y caducan y se eliminan automáticamente para ahorrar espacio. Imagina una pipeline en condiciones que utilice ambas correctamente. Tienes un workflow con un job de build y un job de deploy. En el job de build, tu primer paso usa la action de cache para restaurar al instante tus dependencias de NPM de la ejecución de ayer. Tu código compila rápidamente, produciendo un binario de aplicación final. Luego usas la action de upload artifact para guardar solo ese archivo binario. El job de build termina, y el runner se destruye. El job de deploy arranca en un nuevo runner. No necesita la caché, y no necesita las dependencias de NPM. Simplemente usa la action de download artifact para coger el binario compilado que acabas de generar, y luego lo sube a tu servidor de producción. El caching es un atajo desechable para las cosas que descargas, mientras que los artifacts son el traspaso esencial para las cosas que creas. Gracias por estar ahí. Espero que hayas aprendido algo nuevo.
7

Controlando el flujo con concurrencia

4m 05s

Domina el control de ejecución de los workflows. Aprende a usar la palabra clave concurrency para cancelar ejecuciones redundantes y evitar despliegues superpuestos.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 7 de 14. Un desarrollador hace push de tres commits muy rápidos a una pull request abierta en cinco minutos. Si tu servidor de CI está ejecutando tres test suites redundantes, estás quemando dinero. Necesitas una forma de decirle al sistema que solo importa el código más reciente, y eso es exactamente lo que consigues controlando el flujo con concurrencia. Por defecto, GitHub Actions ejecuta los workflows activados en paralelo. Si haces push cinco veces, levanta cinco runners independientes. Para las comprobaciones básicas, esto desperdicia minutos de runner. Para los deploys, es directamente peligroso. Si dos ejecuciones del workflow intentan hacer deploy al mismo entorno de staging simultáneamente, creas una race condition. El commit más antiguo podría incluso terminar de hacer deploy después del más nuevo, sobrescribiendo tus actualizaciones y dejando tu entorno en un estado obsoleto. Esto lo solucionas usando la palabra clave concurrency. Puedes aplicarla al nivel superior de todo el workflow o restringirla a un job específico. El mecanismo se basa completamente en los concurrency groups. Un concurrency group es simplemente un string que tú defines. Si dos ejecuciones comparten exactamente el mismo nombre de grupo, GitHub aplica límites de concurrencia entre ellas. Mucha gente comete el error de hardcodear este string. Si pones como nombre de grupo solo la palabra deploy, hacer push a tu rama de testing cancelará un deploy activo en tu rama main de producción. El nombre del grupo debe ser dinámico. Lo construyes usando variables de contexto, como la referencia de la rama actual. Si nombras el grupo usando el número de la pull request, los límites de concurrencia se aplican solo a los pushes dentro de esa pull request específica. Tu rama main no se ve afectada en absoluto. Cuando se lanza un nuevo workflow, GitHub comprueba si ya hay una ejecución activa para ese concurrency group. Si la hay, el comportamiento por defecto es poner la nueva ejecución en un estado pending. Espera en una cola. Aquí está la clave. La cola solo guarda un job en estado pending. Si se lanza una tercera ejecución mientras la primera está corriendo y la segunda está pending, la segunda ejecución se expulsa de la cola. Solo la ejecución más reciente se queda esperando. Esperar es más seguro para los deploys, pero para el testing de pull requests, esperar sigue consumiendo un tiempo innecesario. Aquí es donde entra en juego la configuración cancel-in-progress. Es un boolean que añades bajo la definición de tu concurrency group. Cuando pones cancel-in-progress en true, cambias el comportamiento de encolar a terminar. Volvamos al desarrollador que hace tres commits muy rápidos. El primer push lanza una test suite. Dos minutos después, vuelve a hacer push. Como configuraste el concurrency group con el nombre de la rama y activaste cancel-in-progress, GitHub ve la nueva ejecución, termina instantáneamente la test suite activa del primer commit y empieza a testear el segundo commit. Cuando ocurre el tercer push un minuto después, termina la segunda ejecución y empieza la tercera. El desarrollador sigue obteniendo el pass o fail final, pero tú solo has pagado por ejecutar los tests una vez. Los controles de concurrencia transforman tus pipelines de CI de un sistema reactivo que ejecuta ciegamente cada trigger, a un sistema consciente del estado que solo gasta recursos en el código que realmente importa. Gracias por escuchar, ¡feliz programación a todos!
8

Controlando despliegues con Environments

4m 33s

Descubre cómo mapear tus workflows de GitHub Actions a objetivos de despliegue externos usando Environments para imponer aprobaciones manuales y aislar secrets.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 8 de 14. Las credenciales de tu base de datos de producción nunca deberían ser accesibles para una pull request aleatoria desde una feature branch. Sin embargo, si todos tus secrets se almacenan a nivel de repositorio, cualquier workflow podría obtenerlos. Resolver esta brecha de seguridad es precisamente la razón por la que necesitas controlar los deploys con Environments. Primero, debemos aclarar un malentendido común. Un environment en GitHub Actions no es un servidor físico. GitHub no levanta una máquina virtual ni una instancia en la nube llamada production para ti. Un environment es puramente un límite lógico configurado en los settings de tu repositorio de GitHub. Actúa como un guardián, controlando cuándo se le permite ejecutarse a un job y qué datos puede ver ese job. La razón principal de esta feature es aplicar políticas de release y proteger datos sensibles. Al crear un environment, puedes asociarle secrets y variables específicas directamente. Podrías crear un environment llamado staging y otro llamado production. Cada uno tiene su propio conjunto único de API keys, almacenadas exactamente bajo el mismo nombre de variable. En tu archivo de workflow, vinculas un job específico a un environment simplemente indicando su nombre. Cuando el workflow se ejecuta, el job que hace referencia al environment de staging obtiene las keys de staging. El job que hace referencia al environment de production obtiene las keys de production. Esto aísla tus datos sensibles por completo. Un job que se ejecuta en una feature branch no puede leer las keys de production porque no se ejecuta en el contexto del environment de production. Pero aislar los secrets es solo la mitad del poder de los environments. La otra mitad son las protection rules. Estas reglas actúan como barreras estrictas en tu pipeline de deploy. La protection rule más común es la de un required reviewer. Veamos cómo fluye esto en un escenario real. Tienes un workflow que hace la build de tu aplicación y hace el deploy automáticamente a staging. Ese job termina con éxito. El siguiente job en el workflow está configurado para hacer deploy a production, y hace referencia a tu environment de production. Si tienes configurada una regla de required reviewer para ese environment, el workflow se detiene justo ahí. El job se pausa. No se envía a ningún runner, y las API keys de production permanecen guardadas de forma segura. GitHub envía una notificación al manager o equipo designado indicando que hay un deploy en espera. El workflow se quedará en este estado pendiente hasta que se tome alguna acción. Solo cuando el manager hace clic en aprobar en la interfaz de GitHub, se abre la barrera. En ese momento exacto, el job se envía a un runner disponible, los secrets de production se descifran y se inyectan, y el script de deploy se ejecuta. Puedes añadir otras protection rules por encima de las aprobaciones manuales. Una opción es un wait timer, que obliga a un job a retrasarse un número determinado de minutos antes de empezar. Esto te da un margen para cancelar un rollout si notas un pico en la tasa de errores en tus dashboards de monitorización justo después de un deploy en staging. También puedes configurar deployment branches. Esto restringe el environment para que solo acepte jobs que se ejecuten desde ramas específicas, como tu main branch o release tags específicos. Si un developer intenta forzar un job de deploy a production desde una bugfix branch aleatoria, la barrera del environment simplemente rechaza la ejecución. Aquí está la clave. Los environments desacoplan tus mecánicas de deploy de tu control de acceso. Tu archivo de workflow describe los pasos exactos necesarios para hacer el deploy de tu código, pero los settings del environment dentro de GitHub dictan quién tiene la autoridad para permitir que eso pase y qué secrets se desbloquean cuando lo hacen. Si disfrutas de estos deep dives técnicos, puedes apoyar el programa buscando DevStoriesEU en Patreon. ¡Gracias por escuchar, y happy coding a todos!
9

Acceso a la nube sin contraseñas mediante OIDC

4m 26s

Elimina las credenciales de la nube de larga duración de tus repositorios. Aprende a usar OpenID Connect (OIDC) para autenticar de forma segura GitHub Actions con AWS, Azure y GCP.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 9 de 14. La credencial cloud más segura es la que caduca cinco minutos después de que termine tu deploy. Sin embargo, muchos equipos siguen copiando claves de administrador de larga duración en los settings del repositorio, con la esperanza de que nunca se filtren. Hoy, solucionamos esto viendo el Passwordless Cloud Access a través de OIDC. Históricamente, conectar un workflow de GitHub a un proveedor cloud implicaba generar una access key en AWS, Google Cloud o Azure, y guardarla como un GitHub Secret de larga duración. Si ese secret se filtraba, cualquiera podía usarlo desde cualquier lugar hasta que un administrador lo revocara manualmente. La gente suele pensar que OpenID Connect, u OIDC, es solo un nuevo tipo de secret que pegas en tu repositorio. No lo es. OIDC reemplaza por completo los secrets almacenados. Es un protocolo que genera un token criptográfico dinámico al vuelo para demostrar la identidad del workflow a tu proveedor cloud. GitHub actúa como un Identity Provider de OIDC. Cuando se ejecuta un workflow, puede pedirle a GitHub que emita un JSON Web Token, o JWT. Para que esto ocurra, tienes que añadir un permiso específico a tu archivo de workflow. Configuras el bloque permissions para permitir acceso de escritura al ID token. Esto le dice a GitHub que el workflow está autorizado para generar una credencial de identidad. Aquí está la clave. Este token no da acceso por sí solo. Es simplemente un documento firmado digitalmente que contiene claims. Los claims son fragmentos de metadatos que indican hechos verificables sobre el workflow que se está ejecutando. El token incluye el nombre del repositorio, la organización, la rama, el entorno y el evento que disparó la ejecución. Como GitHub firma criptográficamente el token, tu proveedor cloud puede confiar en estos claims. Esto forma la base de un deploy zero-trust. Veamos un job de deploy haciendo push de una imagen a un Elastic Container Registry de AWS. El workflow arranca y le pide un token OIDC a GitHub. El token se genera, conteniendo claims que verifican que viene de la rama main de tu repositorio backend. Luego, el workflow envía este token a AWS. AWS primero comprueba la firma digital para asegurarse de que el token realmente viene de GitHub. Después, lee los claims. Comprueba estos claims contra una trust policy estricta que definiste antes. La policy podría decir que solo acepta tokens de tu repositorio específico y solo si el workflow se está ejecutando en la rama main. Como los claims coinciden, AWS acepta el token. AWS no devuelve una key permanente. En su lugar, emite un access token temporal. Este token podría ser válido por solo quince minutos. Tu workflow usa esta credencial temporal para hacer push de la imagen del contenedor al registry. Cuando el job termina, la credencial caduca. No hay nada que rotar, y nada almacenado en GitHub que un atacante pueda extraer. Al configurar esto, presta mucha atención al subject claim, a menudo llamado el claim sub. Este es el campo principal que los proveedores cloud usan para filtrar el acceso. Por defecto, GitHub formatea el subject claim para incluir el nombre del repositorio y la referencia de git, como la rama o el tag. Tienes que asegurarte de que tu trust policy cloud valide estrictamente este subject claim. Si solo compruebas el nombre de la organización, cualquier repositorio de tu organización podría pedir recursos cloud. Al vincular el acceso cloud temporal a metadatos específicos del workflow, garantizas que un repositorio comprometido no pueda tocar tu infraestructura a menos que la petición venga de la rama y el entorno exactos en los que confías explícitamente. Eso es todo por este episodio. Gracias por escuchar, y ¡sigue programando!
10

Escalando pipelines DRY

4m 07s

Compara Reusable Workflows y Composite Actions. Aprende qué mecanismo elegir al estandarizar tus pipelines de CI/CD en toda una empresa.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 10 de 14. Al gestionar la integración continua en cincuenta repositorios, copiar y pegar exactamente el mismo YAML es una pesadilla de mantenimiento anunciada. Cambias una herramienta de análisis de seguridad y, de repente, tienes que actualizar manualmente cincuenta archivos diferentes. Este episodio trata sobre cómo escalar pipelines DRY para solucionar exactamente eso. Para dejar de repetirte en GitHub Actions, tienes dos herramientas principales: Reusable Workflows y Composite Actions. Los ingenieros suelen elegir la incorrecta, ya que ambas evitan la duplicación. Una Composite Action no es un workflow. Es simplemente un conjunto de steps. Un Reusable Workflow es una pipeline completa que agrupa jobs enteros. Si tu lógica compartida necesita abarcar varias máquinas, orquestar dependencias complejas entre jobs, o gestionar secrets de forma segura, debes usar un Reusable Workflow. Una Composite Action coge una secuencia de steps, como hacer el checkout del código, configurar un entorno de lenguaje e instalar dependencias, y los empaqueta en una única custom action. Cuando un workflow usa esta action, todos esos steps agrupados se ejecutan secuencialmente dentro del job actual existente. La Composite Action no decide en qué máquina runner se ejecuta. Se ejecuta donde el job padre la coloque. Existe puramente para limpiar la lógica repetitiva de los steps dentro de un único entorno de ejecución. Los Reusable Workflows operan a un nivel arquitectónico mucho más alto. Son archivos YAML completos que otro workflow puede lanzar. El workflow que hace la petición es el caller workflow, y el workflow que se lanza es el called workflow. Como un called workflow define jobs enteros, controla la infraestructura. Un job dentro del Reusable Workflow podría ejecutarse en un runner de Ubuntu para hacer la build de una aplicación, mientras que un job dependiente se ejecuta en un runner de macOS para testearla. Imagina un equipo de Platform Engineering estandarizando una pipeline de deploy de Node. Quieren asegurarse de que cada equipo ejecute los mismos checks de seguridad antes de subir el código. En lugar de confiar en que cincuenta equipos de producto mantengan archivos YAML idénticos, los ingenieros de plataforma crean un Reusable Workflow central en un repositorio compartido. Este archivo central define la secuencia exacta de jobs necesarios para escanear, hacer la build y el deploy de la aplicación. Los cincuenta repositorios de producto crean entonces un caller workflow mínimo. Este caller workflow contiene solo un job que apunta directamente al archivo compartido del equipo de plataforma usando su path. Pasas los datos de configuración al called workflow usando inputs, especificando parámetros como el nombre del entorno de destino o la versión de Node. El caller workflow también puede pasarle secrets. Puedes mapear secrets específicos explícitamente, o indicarle al called workflow que simplemente herede todos los secrets disponibles para el caller. Cuando el equipo de plataforma necesita rotar un secret de deploy o añadir una nueva herramienta de análisis estático, actualizan el called workflow central. Al instante, los cincuenta repositorios ejecutan el nuevo check de seguridad en su siguiente commit. Los equipos de producto no tocan nada de configuración. Aquí está la clave. Usa Composite Actions para ocultar la engorrosa lógica de los steps dentro de un único entorno, pero usa Reusable Workflows para forzar arquitecturas de pipeline estandarizadas en toda tu organización. Eso es todo por este episodio. ¡Gracias por escuchar, y sigue programando!
11

Creando Custom Actions: Docker frente a JavaScript

4m 09s

Toma el control de tu pipeline creando Custom Actions. Exploramos los pros y contras de rendimiento y compatibilidad entre las actions de JavaScript y de contenedores Docker.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 11 de 14. Un contenedor garantiza versiones exactas de las herramientas, pero conlleva un coste de latencia oculto en cada ejecución del workflow. La consistencia de tu entorno podría estar ralentizando a tu equipo y atándolo a un único sistema operativo sin que te des cuenta. Crear custom actions: Docker vs JavaScript resuelve esta tensión. Una custom action es lógica reutilizable que escribes una vez y compartes en múltiples repositorios. Al crear una, debes elegir una arquitectura de ejecución. Los dos modelos principales son JavaScript y Docker. Muchos ingenieros optan por defecto por las Docker actions porque buscan seguridad absoluta y dependencias predecibles. Suponen que un contenedor es la opción más robusta. La realidad es que crear una Docker action impide permanentemente que cualquier runner de macOS o Windows utilice tu herramienta. Las Docker actions solo se ejecutan en entornos Linux. Las JavaScript actions adoptan un enfoque diferente. Se ejecutan directamente en la máquina host. Escribes tu lógica, la compilas en un único archivo con todas sus dependencias y apuntas los metadatos de la action a ese entry file. Cuando se lanza un workflow, el runner utiliza su runtime de Node integrado para ejecutar tu script. Esto desacopla tu lógica del sistema operativo subyacente. Exactamente la misma action se ejecutará de forma nativa en runners de Linux, macOS y Windows sin modificaciones. Las Docker container actions, por el contrario, empaquetan el sistema operativo, las dependencias del sistema y tu código juntos en una unidad inmutable. Tú dictas el entorno exacto. El runner lee un Dockerfile proporcionado por tu action, hace build o pull de la imagen del contenedor, y ejecuta tu código dentro de ese espacio aislado. Aquí está la clave. El estricto aislamiento de una Docker action introduce una penalización de cold-start. Imagina un equipo creando una herramienta de linting de código custom para compartir en toda su organización. Si la construyen como una Docker action, el runner tiene que hacer pull de esa imagen del contenedor antes de poder evaluar una sola línea de código. Eso podría añadir un retraso de quince segundos al inicio de cada job de linting. A lo largo de cientos de pull requests al día, ese tiempo de inactividad se acumula en horas de compute desperdiciado. Si el equipo construye esa misma lógica de linting en JavaScript, el runner simplemente descarga el archivo del script y lo ejecuta al instante. Tu elección de arquitectura dicta cómo se comporta tu action en el mundo real. Si tu herramienta depende de binarios de sistema complejos, requiere una versión muy específica de un compilador de lenguaje, o envuelve scripts de Bash legacy que son frágiles fuera de una distribución de Linux específica, Docker es la opción correcta. Pagas el impuesto de la latencia a cambio de estabilidad garantizada. Si tu objetivo es crear una herramienta rápida y ampliamente adoptada que funcione en cualquier tipo de proyecto, JavaScript es el mejor camino. La elección arquitectónica entre Docker y JavaScript para una custom action nunca trata sobre en qué lenguaje de programación prefieres escribir, es un trade-off difícil entre un control estricto del entorno y la velocidad de ejecución multiplataforma. Eso es todo por hoy. ¡Hasta la próxima!
12

Gestión de flotas: Runners Hosted frente a Self-Hosted

3m 42s

Navega por los límites de los runners de GitHub. Aprende cuándo depender de máquinas alojadas en GitHub y cuándo tu arquitectura exige runners Self-Hosted.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 12 de 14. Los cloud runners de GitHub son extremadamente prácticos, hasta que tus integration tests necesitan acceder a una base de datos legacy protegida por un firewall corporativo. De repente, un runner público no puede acceder a tus datos privados. Aquí es exactamente donde entra en juego el Fleet Management: Hosted vs Self-Hosted runners. Por defecto, GitHub Actions utiliza GitHub-hosted runners. Cuando se dispara un workflow, GitHub levanta una máquina virtual nueva. Puedes solicitar Ubuntu, Windows o macOS. El runner ejecuta tu job, reporta el resultado y, a continuación, la máquina virtual se destruye inmediatamente. Es como empezar de cero cada vez. No gestionas el sistema operativo, no instalas parches de seguridad ni te preocupas por los archivos residuales de una build anterior. Sin embargo, ese aislamiento es un arma de doble filo. Dado que esos runners están en la infraestructura cloud de GitHub, operan con direcciones IP dinámicas y no tienen acceso directo a tus redes privadas. Si tienes una aplicación interna, o una base de datos que no puede estar expuesta a internet público, necesitas un runner que viva dentro de tu propio perímetro de seguridad. Esto es un self-hosted runner. Tú pones el hardware. Puede ser un servidor físico en un data center, una máquina virtual en tu proveedor cloud, o un contenedor. Instalas la aplicación del runner de GitHub Actions en esa máquina. El runner se conecta hacia afuera con GitHub, recupera los jobs pendientes, los ejecuta localmente y envía los logs de vuelta. Al estar en tu red, puede comunicarse de forma segura con tu infraestructura interna sin necesidad de abrir puertos en tu firewall. Aquí está la clave. Tú eres el dueño del hardware, lo que significa que te encargas del mantenimiento. Eres responsable de las actualizaciones del sistema operativo, la seguridad de la red y de instalar las dependencias necesarias, como los runtimes de los lenguajes o las build tools. Un error común es pensar que los self-hosted runners se comportan exactamente igual que los hosted. Y no es así. Los GitHub-hosted runners son efímeros por diseño. Los self-hosted runners estándar son stateful. Cuando un job termina en un self-hosted runner por defecto, la máquina sigue funcionando. Si tu job escribe un archivo temporal, arranca un proceso en segundo plano o se descarga una imagen de contenedor grande, todo eso se queda en el disco cuando empieza el siguiente job. Esto crea graves riesgos de contaminación cruzada. Un script de build defectuoso en una pull request podría dejar archivos corruptos, haciendo que el job de deployment que se ejecuta justo después falle. Tienes que configurar activamente tu infraestructura self-hosted para que sea efímera si eso es lo que quieres, a menudo usando webhooks para levantar contenedores nuevos por cada job. Si simplemente necesitas más potencia de procesamiento o una dirección IP estática, pero sigues queriendo que GitHub se encargue del mantenimiento de la máquina, hay un punto intermedio llamado larger runners. Son máquinas GitHub-hosted donde tú defines las especificaciones de hardware y las características de red, pero siguen siendo efímeras y gestionadas por GitHub. Al final, la decisión entre hosted y self-hosted rara vez se reduce solo a los costes de computación. Es un trade-off fundamental entre la comodidad de un entorno desechable y sin mantenimiento, y la necesidad de controlar los límites de tu propia red. Gracias por pasar unos minutos conmigo. Hasta la próxima, cuídate.
13

Escalado en Kubernetes: Actions Runner Controller

3m 36s

Descubre cómo el Actions Runner Controller (ARC) orquesta flotas de runners efímeros y de autoescalado de forma nativa en tus clústeres de Kubernetes.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 13 de 14. Tienes un equipo enorme y, a las nueve de la mañana, cien desarrolladores hacen push de código simultáneamente. Tus servidores de build estáticos se saturan con la cola, o los has sobredimensionado y se quedan ahí desperdiciando capacidad de cómputo cara toda la noche. Kubernetes Scale: Actions Runner Controller soluciona esto transformando tu build pipeline en un sistema dinámico y nativo de contenedores. Los self-hosted runners estándar suelen ser máquinas virtuales estáticas o contenedores de larga duración. Los configuras, los registras en un repositorio y se quedan ahí haciendo polling en busca de trabajo. Esta configuración garantiza que pagues por el tiempo de inactividad, y cuando hay un pico repentino de builds, la cola simplemente se acumula hasta que un runner existente termina su tarea actual. Actions Runner Controller, o ARC, cambia radicalmente este modelo. ARC es un operador de Kubernetes que orquesta runner scale sets con auto-scaling. En lugar de mantener worker nodes de larga duración, aprovisiona runners efímeros Just-in-Time basándose en el tamaño exacto de tu cola. Para lograr esto sin saturar los rate limits de la API, ARC se apoya en dos componentes arquitectónicos principales dentro de tu clúster de Kubernetes. El primero es el pod Listener. El Listener utiliza un long poll por HTTPS para conectarse a GitHub. En lugar de pedirte que abras puertos de entrada en el firewall para recibir webhooks, el Listener contacta con GitHub y mantiene la conexión abierta. Se queda ahí esperando tranquilamente a que GitHub le pase un mensaje de Job Available. Cuando el Listener recibe ese mensaje, le pasa la información al pod Controller. El Controller actúa como motor de aprovisionamiento. Inmediatamente habla con la API de Kubernetes para levantar un runner pod totalmente nuevo, específicamente para ese único job pendiente. Este pod es un runner efímero Just-in-Time. Arranca, recibe un token de registro de corta duración, ejecuta el workflow y, acto seguido, se termina a sí mismo. Volvamos a esa avalancha de código de las nueve de la mañana. Cien desarrolladores hacen push de commits exactamente al mismo tiempo. El pod Listener detecta la ráfaga repentina de mensajes de Job Available desde GitHub. Avisa al Controller, que solicita al instante cien pods efímeros de Kubernetes. Tu clúster hace scale out, asignando nodos si es necesario, y los jobs se ejecutan en paralelo. A medida que termina cada workflow, su pod se destruye por completo. A las nueve y cuarto, la cola está despejada y tu número de runners escala de vuelta a cero. Has usado computación paralela masiva durante exactamente quince minutos, y luego has dejado de pagar por ella. Aquí está la clave. Como cada job se ejecuta en un pod aislado y recién aprovisionado que se destruye justo después de la ejecución, eliminas por completo la contaminación de estado entre builds. Una cache sucia, un background process residual o una environment variable alterada de un run anterior simplemente no pueden romper el siguiente. Obtienes la seguridad de un build environment impecable cada vez, junto con la eficiencia de cómputo exacta del auto-scaling de Kubernetes. El verdadero valor de Actions Runner Controller es que evita que trates a los runners de continuous integration como una infraestructura pesada que tienes que mantener, convirtiéndolos en cambio en capacidad de cómputo puramente transitoria que solo existe mientras un job se está ejecutando activamente. Gracias por pasar unos minutos conmigo. Hasta la próxima, cuídate.
14

Integridad de la cadena de suministro con Attestations

4m 15s

Protege la cadena de suministro de tu software. Aprende a generar attestations de artefactos y procedencia infalsificables directamente desde tus workflows.

Descargar
Hola, soy Alex de DEV STORIES DOT EU. GitHub Actions, episodio 14 de 14. Un usuario descarga tu herramienta de línea de comandos compilada desde una página de releases. Si una dependencia comprometida o un actor malicioso intercambió ese binario después de compilarlo, un chequeo de checksum estándar no le salvará. Los hashes estándar solo demuestran que el archivo que descargaron coincide con el archivo alojado, no de dónde vino realmente. Para garantizar que un archivo fue generado por tu código exacto, necesitas Supply Chain Integrity con Attestations. Un attestation no es solo un build log o un archivo de texto con un hash junto a tu release. Es una declaración criptográficamente firmada e infalsificable sobre la procedencia de un artifact. Vincula tu binario final directamente con el commit SHA exacto, el workflow run específico y la identidad OpenID Connect del entorno de build. El proceso ocurre completamente dentro de tu workflow de GitHub Actions. Después de que tu código compile, utilizas la action oficial de build provenance. Esta action calcula el checksum de tu artifact finalizado y contacta con una autoridad de firma centralizada, específicamente Sigstore. El workflow intercambia su token temporal de OpenID Connect, específico del job, por un certificado de firma de corta duración. Como este token es generado por GitHub Actions y mapeado directamente a tu repositorio, actúa como un carnet de identidad infalsificable para el workflow runner. Esta interacción genera un registro criptográfico permanente. Este registro declara inequívocamente que este hash de archivo exacto fue producido por tu repositorio, lanzado por un commit específico, durante un workflow run específico. La firma se adjunta al artifact, creando un conjunto de pruebas que viaja con el archivo dondequiera que se aloje. Aquí está la clave. El verdadero valor de seguridad ocurre en el lado del consumidor. Cuando un usuario descarga tu herramienta de línea de comandos, no tiene que confiar ciegamente en el hosting provider ni en el mirror de descarga. Antes de ejecutar el binario, usa la CLI de GitHub para verificar el attestation localmente. Ejecuta un comando attestation verify contra el ejecutable descargado, especificando explícitamente al owner de tu repositorio como la fuente esperada. La CLI inspecciona la firma criptográfica y la comprueba contra el log de transparencia público. Si la firma es válida, demuestra matemáticamente que el archivo fue compilado por tu workflow oficial. Si un actor malicioso interceptó la descarga, manipuló la compilación o reemplazó el binario en la página de releases, la verificación falla al instante. La firma no se puede falsificar porque el atacante nunca podrá poseer el token de identidad temporal de OpenID Connect generado dentro de tu workflow run seguro. La identidad está intrínsecamente vinculada a la infraestructura de GitHub Actions en el momento exacto de la build. Este mecanismo cierra una brecha crítica en la seguridad de la software supply chain. Ya no estás pidiendo a los usuarios que confíen en una ubicación de almacenamiento. En su lugar, el artifact se autentica por sí mismo. Los attestations cambian tu modelo de seguridad, pasando de confiar en dónde vive un archivo a demostrar matemáticamente dónde nació. Como este es el último episodio de nuestra serie sobre GitHub Actions, te animo encarecidamente a que te pongas manos a la obra y empieces a crear estos workflows tú mismo. Visita devstories dot eu para sugerir temas que te gustaría ver en nuestras futuras series. Eso es todo por este episodio. ¡Gracias por escuchar, y sigue creando!