Act: Ejecutar GitHub Actions Localmente
Act es una herramienta de línea de comandos que permite ejecutar workflows de GitHub Actions en tu máquina local usando Docker, eliminando la necesidad de hacer push al repositorio remoto para probar cada cambio en el pipeline. Con soporte para secretos, artefactos y runners personalizados, Act acorta significativamente el ciclo de desarrollo de pipelines CI/CD.
Requisitos Previos
- Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
- Docker instalado y funcionando
- Git instalado
- Al menos 4 GB de RAM (las imágenes de runner son grandes)
- Espacio en disco: 5-20 GB para las imágenes de runner
Instalación de Act
# Método 1: Script de instalación oficial (recomendado)
curl --proto '=https' --tlsv1.2 -sSf \
https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash
# Verificar la instalación
act --version
# Método 2: Descargar el binario directamente
ACT_VERSION=$(curl -s https://api.github.com/repos/nektos/act/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4)
wget "https://github.com/nektos/act/releases/download/${ACT_VERSION}/act_Linux_x86_64.tar.gz"
tar -xzf act_Linux_x86_64.tar.gz
sudo mv act /usr/local/bin/
# Método 3: Con Homebrew (si está disponible)
brew install act
Configuración del Entorno
En la primera ejecución, Act pregunta qué tamaño de imagen de runner usar:
# Ejecutar por primera vez (se generará el fichero de configuración)
act
# Se pedirá elegir entre:
# - Micro: ~200MB (funcionalidades muy básicas)
# - Medium: ~500MB (Node.js incluido, recomendado para empezar)
# - Large: ~17GB (replica exactamente ubuntu-latest de GitHub)
Crea el fichero de configuración .actrc en el directorio del proyecto o en ~/.actrc:
# Configuración global en ~/.actrc
tee ~/.actrc << 'EOF'
# Imagen de runner por defecto (Medium es buen equilibrio)
-P ubuntu-latest=catthehacker/ubuntu:act-latest
-P ubuntu-22.04=catthehacker/ubuntu:act-22.04
-P ubuntu-20.04=catthehacker/ubuntu:act-20.04
# Usar Docker del host en lugar de Docker-in-Docker (más rápido)
--bind
# No mostrar la confirmación de descarga de imágenes
--pull=missing
EOF
Configura el fichero .env del proyecto para variables de entorno:
# Crear fichero de variables locales (no subir al repositorio)
tee .env << 'EOF'
# Variables de entorno para pruebas locales
NODE_ENV=test
DATABASE_URL=postgresql://localhost:5432/test_db
API_BASE_URL=http://localhost:3000
EOF
# Añadir a .gitignore
echo ".env" >> .gitignore
Ejecución de Workflows
# Listar todos los jobs disponibles en los workflows
act --list
# Ejecutar el evento push (el más común)
act push
# Ejecutar un workflow específico
act push --workflows .github/workflows/ci.yml
# Ejecutar un job específico dentro de un workflow
act push --job build
# Ejecutar el evento pull_request
act pull_request
# Ejecutar con un evento personalizado (fichero JSON)
act --eventpath .github/events/push.json
# Ver qué se ejecutaría sin ejecutarlo realmente (dry-run)
act push --dry-run
# Ejecutar con output detallado para depuración
act push --verbose
Crear ficheros de eventos de ejemplo:
# .github/events/push.json - Evento push simulado
mkdir -p .github/events
tee .github/events/push.json << 'EOF'
{
"ref": "refs/heads/main",
"repository": {
"full_name": "mi-org/mi-repo",
"name": "mi-repo",
"owner": {
"login": "mi-org"
}
},
"head_commit": {
"id": "abc123def456",
"message": "Prueba local de CI"
}
}
EOF
Gestión de Secretos
# Método 1: Pasar secretos directamente en la línea de comandos
act push \
--secret DOCKER_USERNAME=miusuario \
--secret DOCKER_PASSWORD=micontraseña \
--secret SSH_PRIVATE_KEY="$(cat ~/.ssh/id_rsa)"
# Método 2: Usar un fichero de secretos
tee .secrets << 'EOF'
DOCKER_USERNAME=miusuario
DOCKER_PASSWORD=micontraseña_docker
NPM_TOKEN=npm_xxxxxxxxxxxx
DEPLOY_HOST=produccion.tudominio.com
EOF
# Ejecutar usando el fichero de secretos
act push --secret-file .secrets
# IMPORTANTE: nunca subas .secrets al repositorio
echo ".secrets" >> .gitignore
# Método 3: Variables de entorno del sistema
export DOCKER_PASSWORD=micontraseña
act push --secret DOCKER_PASSWORD
Imágenes de Runner Personalizadas
Para flujos de trabajo que necesitan herramientas específicas:
# Dockerfile.runner - Runner personalizado con tus herramientas
FROM catthehacker/ubuntu:act-22.04
# Instalar herramientas adicionales necesarias en los pipelines
RUN apt-get update && apt-get install -y \
awscli \
kubectl \
helm \
jq \
&& rm -rf /var/lib/apt/lists/*
# Instalar versión específica de Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
&& apt-get install -y nodejs
# Instalar herramientas de Python
RUN pip3 install boto3 ansible
# Construir la imagen personalizada
docker build -t mi-runner:latest -f Dockerfile.runner .
# Usar la imagen personalizada en la configuración de act
tee -a .actrc << 'EOF'
-P ubuntu-latest=mi-runner:latest
EOF
# O directamente en la línea de comandos
act push \
--platform ubuntu-latest=mi-runner:latest
Manejo de Artefactos
Act soporta la subida y descarga de artefactos usando un servidor local:
# Instalar el servidor de artefactos para act
docker run -d \
--name act-artifacts \
-p 8080:8080 \
-v /tmp/act-artifacts:/storage \
ghcr.io/jefuller/artifact-server:latest
# Configurar act para usar el servidor de artefactos
tee -a .actrc << 'EOF'
--artifact-server-path /tmp/act-artifacts
EOF
# Ejecutar workflow que genera artefactos
act push
# Los artefactos estarán en /tmp/act-artifacts/
ls -la /tmp/act-artifacts/
Workflow de ejemplo con artefactos:
# .github/workflows/ci.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ejecutar pruebas y generar reportes
run: |
npm test -- --coverage --reporters=json
npm run build
- name: Guardar resultados de cobertura
uses: actions/upload-artifact@v4
with:
name: coverage-report
path: coverage/
retention-days: 30
- name: Guardar build
uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
Depuración de Workflows Fallidos
# Ejecutar con output máximo
act push --verbose 2>&1 | tee act-debug.log
# Mantener el contenedor activo después del fallo para inspección
act push --keep
# Entrar al contenedor del runner para depurar manualmente
# Primero, encontrar el ID del contenedor
docker ps | grep act
# Conectarse al contenedor
docker exec -it act-mi-workflow-build bash
# Dentro del contenedor, ejecutar los comandos manualmente
cd /github/workspace
npm ci
npm test
# Inspeccionar variables de entorno disponibles
env | grep -E "GITHUB_|INPUT_"
Añadir pasos de depuración en el workflow:
- name: Depuración - Estado del sistema
run: |
echo "=== Variables de entorno ==="
env | sort
echo "=== Directorio actual ==="
pwd && ls -la
echo "=== Versiones de herramientas ==="
node --version || echo "Node no disponible"
python3 --version || echo "Python no disponible"
docker --version || echo "Docker no disponible"
if: runner.debug == '1' || failure()
# Habilitar modo debug
act push --env ACTIONS_STEP_DEBUG=true --env ACTIONS_RUNNER_DEBUG=true
Solución de Problemas
Docker socket no accesible:
# Verificar permisos del socket de Docker
ls -la /var/run/docker.sock
# Añadir tu usuario al grupo docker
sudo usermod -aG docker $USER
newgrp docker
La imagen de runner tarda mucho en descargarse:
# Usar una imagen más ligera
act push -P ubuntu-latest=node:20-bullseye-slim
# O especificar la imagen en el workflow mismo:
# runs-on: ubuntu-latest → Act usará la imagen configurada en .actrc
Variables de entorno del paso no disponibles:
# Act no soporta todas las expresiones de GitHub Actions
# En particular, ${{ env.VAR }} puede no funcionar igual
# Usar export explícito como workaround:
act push --env MY_VAR=valor
Acción uses: no encontrada:
# Algunas acciones del marketplace no funcionan localmente
# Verificar compatibilidad en: https://github.com/nektos/act#not-supported-github-actions
# Para acciones que fallan, se puede reemplazar temporalmente:
# uses: actions/upload-artifact@v4 → run: echo "Artefacto: ${{...}}"
Conclusión
Act transforma el desarrollo de pipelines CI/CD al permitir iterar rápidamente sin hacer push al repositorio remoto. La capacidad de simular distintos eventos, gestionar secretos localmente y usar imágenes de runner personalizadas hace que el tiempo de depuración de workflows se reduzca drásticamente. Úsalo como parte habitual del flujo de desarrollo antes de confirmar cambios en los workflows de GitHub Actions.


