Primeros pasos con GitHub Actions
Quizá hayas escuchado ya algo del tema y estés a punto de dar tus primeros pasos con GitHub Actions. Si es así, has llegado al lugar correcto.
En este artículo explicaré lo básico del tema y dejaré unos ejemplos sencillos de entender. De este modo, puedes ya irte adentrando en el mundo de la automatización en los procesos de desarrollo de software.
1. Introducción
1.1. ¿Qué es GitHub Actions?
GitHub Actions es una plataforma de automatización que te permite crear flujos de trabajo personalizados (workflows) directamente dentro de tus repositorios de GitHub. Estos workflows se ejecutan automáticamente en respuesta a eventos específicos, como cuando se publica o hacer push de un commit o se crea un Pull Eequest.
En pocas palabras, GitHub Actions te permite automatizar tareas repetitivas en tu proceso de desarrollo, como Compilar código, Realizar pruebas, Generar documentación a partir del código y Desplegar aplicaciones.
1.2. Por qué es importante aprenderlo.
Porque es una herramienta fundamental para cualquier desarrollador que quiera optimizar su flujo de trabajo y mejorar la calidad de su código. Al automatizar tareas repetitivas, ahorras tiempo y reduces la posibilidad de errores manuales. Además, te permite integrar de manera fluida diferentes herramientas y servicios, lo que facilita la colaboración en equipo y acelera el proceso de desarrollo.
1.3. Objetivo del artículo
Este artículo no pretende ser una guía muy detallada, ni avanzada sobre GitHub Actions. Por el contrario, me enfocaré en explicar conceptos esenciales y luego te iré llevando de la mano a la práctica con unos ejercicios simples.
2. Conceptos Básicos
2.1. Workflows
Un workflow de GitHub Actions es una secuencia automatizada de tareas que se ejecutan en respuesta a eventos específicos dentro de tu repositorio de GitHub.
En pocas palabras, es como una receta que le dices a GitHub para que realice ciertas acciones de manera automática, como construir tu código, ejecutar pruebas o desplegar tu aplicación.
Por ejemplo, puedes crear un workflow que se ejecute cada vez que alguien hace un cambio en tu código y que automáticamente compile el código, ejecute pruebas y genere un informe.
Aquí un ejemplo de un archivo de workflow de GitHub Actions:
name: CI on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - name: Descargar código del repositorio uses: actions/checkout@v4 - name: Construir proyecto run: make build
2.2. Jobs
Un job en un workflow de GitHub Actions es como una tarea específica dentro de un flujo de trabajo más grande. Imagina que un workflow es una receta completa para preparar una comida: cada job sería un paso individual de esa receta, como mezclar los ingredientes, cocinarlos o servirlos.
En resumen, un job es un conjunto de pasos que se ejecutan secuencialmente dentro de un workflow. Estos pasos pueden ser desde descargar el código del repositorio hasta ejecutar pruebas o desplegar una aplicación.
Por ejemplo, en un workflow de CI/CD, un job podría ser el encargado de compilar el código, otro de ejecutar las pruebas y un último de desplegar la aplicación en un servidor.
En el código YAML mostrado anteriormente, existe un único job llamado build
que comprende desde las líneas 9 a la 16.
Cómo funcionan los jobs
- Activación del workflow:
- Se produce un evento que desencadena la ejecución del workflow, como un push a un repositorio, la creación de un pull request, o una programación por fecha y hora.
- Creación de un runner:
- GitHub asigna un runner (un entorno de ejecución virtual) para cada job. El runner se configura con el sistema operativo y las herramientas especificadas en el archivo YAML.
- Ejecución de los pasos:
- Los pasos definidos dentro de un job se ejecutan uno tras otro en el runner asignado.
- Cada paso puede ejecutar comandos, utilizar acciones de terceros o realizar otras tareas.
- Finalización del job:
- Cuando todos los pasos de un job se han ejecutado correctamente, el job se marca como completado. Si alguno de los pasos falla, el job se marcará como fallido y la ejecución del workflow puede detenerse, dependiendo de la configuración.
- Ejecución de los siguientes jobs:
- Si el workflow tiene múltiples jobs, se ejecutarán uno tras otro, siguiendo el orden definido en el archivo YAML.
Aquí otro ejemplo de un workflow con dos jobs: build
y test
name: Node.js CI on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Use Node.js uses: actions/setup-node@v3 with: node-version: '22' - name: Instalar dependencias run: npm ci - name: Construir el proyecto run: npm run build test: needs: - build runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Preparar Node.js uses: actions/setup-node@v3 with: node-version: '22' - name: Instalar dependencias run: npm ci - name: Hacer pruebas run: npm test
Importante:
- Los workflows pueden configurarse para que ejecuten algunos jobs en paralelo, mientras que otros secuencialmente.
- Cuando se ejecutan secuencialmente, usualmente se configuran dependencias entre jobs.
- Muy probablemente, cada job se ejecute siempre en un runner diferente. Por ello, no hay que confiarse en que el runner tendrá presente un archivo o configuración creado localmente en un job para ser usado por otro job posterior.
2.3. Runners
Un runner de GitHub Actions es como una computadora virtual que ejecuta tus workflows. Es el entorno donde se llevan a cabo las tareas que has definido. Imagina que es un asistente que realiza las acciones que le indicas en tu archivo YAML.
Características clave de los runners
- Entornos virtuales: Cada runner proporciona un entorno aislado para ejecutar tus jobs. Además, usualmente son efímeros: se crean a demanda para cada job y al terminar este se destruyen.
- Tipos de runners: Existen runners hospedados por GitHub (GitHub-hosted runners) y runners autohospedados (self-hosted runners) que puedes configurar tú mismo.
- Escalabilidad: GitHub puede escalar automáticamente el número de runners para manejar la carga de trabajo.
Normalmente, los runners hospedados por GitHub pueden tener estos posibles nombres:
- ubuntu-latest
- windows-latest
- macos-latest
En cambio, los runners autohospedados pueden tener el nombre que tú le asignes al momento de la instalación. Esto lo explicaré mejor en otro post aparte.
Si, como todo principiante, estás recién dando tus primeros pasos en GitHub Actions, será mejor que te enfoques solo en usar los runners hospedados por GitHub.
2.4. Steps
Un step en GitHub Actions es como una instrucción individual dentro de un job. Imagina un job como una receta y los steps como cada paso que debes seguir para preparar el plato.
En resumen, un step es una tarea específica que se ejecuta dentro de un job. Puede ser cualquier cosa, desde descargar un archivo hasta ejecutar un comando en la terminal.
Por ejemplo, en un job que compila un proyecto, un step podría ser descargar el código del repositorio y otro step podría ser ejecutar el comando de compilación.
Entonces, un job está conformado por uno o más steps. Así, los steps son las unidades de trabajo más pequeñas e indivisibles en GitHub Actions.
El workflow mostrado al principio tiene un único job que consta de dos steps:
- Descargar código del repositorio (de tipo
uses
) - Construir proyecto (de tipo
run
)
name: CI on: push: branches: - main jobs: build: runs-on: ubuntu-latest steps: - name: Descargar código del repositorio uses: actions/checkout@v4 - name: Construir proyecto run: make build
Normalmente, un step puede ser de dos tipo:
uses
: Llama a un Action existente que agrupa una serie de tareas y pasos encapsulados en una unidad de ejecución. Estos Actions son usualmente creados por terceros y se les puede encontrar en el Marketplace de GitHub.run
: Brinda libertad para definir una secuencia de comandos de shell script.
2.5. Eventos
Un evento en GitHub Actions es un suceso que desencadena la ejecución de un workflow.
Imagina que un evento es como un interruptor que enciende una luz. En este caso, la luz sería el workflow y el interruptor sería el evento. Cuando se produce un evento específico (como hacer un push a un repositorio), el workflow se activa y comienza a ejecutar sus tareas.
Ejemplos comunes de eventos:
- push: Cuando se hacer un push a un repositorio.
- pull_request: Cuando se crea un Pull Request.
- schedule: Cuando se programa una ejecución a una fecha y hora determinada.
- workflow_dispatch: Cuando se inicia un workflow manualmente.
En resumen, los eventos son los detonantes que ponen en marcha los workflows de GitHub Actions.
2.6. Actions
Los Actions de GitHub Actions son como pequeñas piezas de código predefinidas que puedes utilizar para automatizar tareas en tus workflows. Imagina que son como bloques de construcción que encajas para crear tu flujo de trabajo personalizado. Estos Actions pueden realizar tareas como instalar dependencias, ejecutar pruebas, desplegar código, y mucho más.
El Marketplace de GitHub es como una tienda donde puedes encontrar miles de estos Actions creados por la comunidad. Es decir, es un lugar donde puedes buscar y descubrir Actions para cualquier tarea que necesites automatizar, sin tener que escribir todo el código desde cero.
3. Ejemplo 1 de workflow
3.1. Crear repositorio
Empieza por crear un repositorio en GitHub yendo a https://github.com/new y completas la información básica para la creación:
3.2. Crear workflow
A través de la interfaz Web, crea un nuevo archivo en la rama por defecto main
:
Escribe la ruta .github/workflows/workflow1.yml como nombre de archivo:
Pega el siguiente contenido:
--- on: # El workflow se dispara cada vez que se hace # un push hacia la rama main push: branches: - main jobs: build: # Nombre del job name: Compilar nginx # Usa runners hospedados por GitHub runs-on: ubuntu-latest steps: - name: Instalar dependencias run: | # Instala dependencias necesarias para la compilacion # de nginx sudo apt-get update sudo apt-get install -y libpcre2-dev - name: Descargar y extraer codigo run: | wget https://github.com/nginx/nginx/releases/download/release-1.27.3/nginx-1.27.3.tar.gz tar -zxf nginx-1.27.3.tar.gz - name: Compilar el codigo run: | cd nginx-1.27.3 ./configure make
3.3. Detalles del workflow
- Propósito: Este workflow tiene un único job que a través de tres steps instala dependencias con APT (librería de desarrollo de PCRE), luego descarga el código fuente de
nginx-1.27.3
y después lo compila. - Cómo ejecutarlo: Solo basta hacer un commit y push de cualquier archivo dentro del repositorio en la rama
main
.
4. Ejemplo 2 de workflow
4.1. Hacer fork de repositorio
Voy a usar el repositorio simple-java-maven-app como base. Para ello, le doy a la opción «Fork» y creo una copia del mismo en mi propia cuenta de GitHub:
Deja las opciones por defecto y dale clic al botón «Create fork»:
4.2. Crear workflow
Creo un archivo en la rama por defecto master
y creo el archivo .github/workflows/workflow2.yml con este contenido:
--- name: Workflow manual on: # Este workflow se ejecuta manualmente workflow_dispatch: jobs: build: name: Construir proyecto runs-on: ubuntu-latest # Declaro dos outputs creados por el step "ver-info" # que son "nombre" y "version" outputs: nombre: ${{ steps.ver-info.outputs.nombre }} version: ${{ steps.ver-info.outputs.version }} steps: - name: Checkout de repositorio uses: actions/checkout@v4 # Descargar Oracle Java 21 y configurarlo para que # use la cache de Maven - name: Instalar Java uses: actions/setup-java@v4 with: distribution: oracle java-version: 21 cache: maven # Descargo la version minima de Maven requerida # por el proyecto - name: Instalar Maven uses: hb0730/maven-action@v1 with: maven-version: 3.9.3 # Construyo el proyecto sin realizar pruebas - name: Compilar run: mvn -B -DskipTests clean package # Obtengo el nombre y version del proyecto construido # Ambos los guardo como "outputs" de GitHub para poder # ser reutilizados en un step o job posterior - name: Obtener nombre y version de artefacto id: ver-info run: | nombre=$(mvn -q -DforceStdout help:evaluate -Dexpression=project.name) version=$(mvn -q -DforceStdout help:evaluate -Dexpression=project.version) echo "nombre=$nombre" >>$GITHUB_OUTPUT echo "version=$version" >>$GITHUB_OUTPUT # Solo el directorio target lo guardo como artefacto - name: Guardar artefacto uses: actions/upload-artifact@v4 with: name: artefacto-java retention-days: 1 path: | target test: name: Realizar pruebas runs-on: ubuntu-latest needs: - build steps: - name: Checkout de repositorio uses: actions/checkout@v4 - name: Instalar Java uses: actions/setup-java@v4 with: distribution: oracle java-version: 21 cache: maven - name: Set up Maven uses: hb0730/maven-action@v1 with: maven-version: 3.9.3 # Descargo el artefacto antes creado que contiene # al directorio target/ - name: Descargar artefacto uses: actions/download-artifact@v4 with: name: artefacto-java # Realizo las pruebas del proyecto con Maven - name: Probar run: mvn test exe: name: Ejecutar artefacto runs-on: ubuntu-latest needs: - build - test steps: - name: Descargar artefacto uses: actions/download-artifact@v4 with: name: artefacto-java # Luego de descargar el artefacto que contiene al # archivo .jar, lo ejecuto # El nombre del .jar se obtiene del valor de los # outputs "nombre" y "version" creados en el job build - name: Ejecutar .jar env: NOMBRE: ${{ needs.build.outputs.nombre }} VERSION: ${{ needs.build.outputs.version }} run: java -jar "${NOMBRE}-${VERSION}.jar"
4.3. Detalles del workflow
- Propósito: Este workflow tiene tres jobs ejecutados secuencialmente que son
build
,test
yexe
:- El primer job
build
construye el proyecto Java usando Maven y guarda el directorio target como artefacto para uso posterior en otro job del mismo workflow. - El segundo job
test
descarga el artefacto ya antes guardado y lo utiliza para realizar las pruebas del proyecto. - El tercer job
exe
descarga el artefacto y ejecuta el archivo .jar
- El primer job
- Cómo ejecutarlo: En la URL del repositorio del que hiciste fork en tu cuenta (Ejm: https://github.com/arengifoc/simple-java-maven-app), agrega la ruta /actions en la barra de direcciones y luego haz clic en «Workflow manual» (título que le pusiste al workflow dentro del archivo workflow2.yml):
Luego, haz clic en «Run workflow» como se muestra debajo:
Ahora, espera unos segundos o refresca la página y debe aparecer una instancia del pipeline ejecutándose:
Si das clic al nombre del pipeline en ejecución puedes ver los jobs que lo conforman:
Y por último, si das clic a cada uno de los jobs puedes ver el detalle de los mismos.
5. Cierre
Este artículo introductorio «Primeros pasos con GitHub Actions» ha pretendido enseñar los elementos básicos más importantes sobre el tema, lo suficiente como para que un lector principiante pueda en poco tiempo entender los conceptos y llevarlos a la práctica a través de un par de ejemplos.
Los pipelines en GitHub Actions es un tema bastante amplio, por lo mismo seguiré publicando más artículos al respecto sobre aspectos específicos.
Si esto te fue de ayuda, no dudes en compartirlo.
Deja un comentario