GitHub Actions
Plataforma de CI/CD nativa de GitHub. Workflows declarativos en YAML que automatizan build, test, deploy y cualquier tarea del ciclo de desarrollo — directamente desde el repositorio.
GitHub Actions es la plataforma de automatización integrada en GitHub. Cada repositorio puede definir workflows en YAML que se ejecutan en respuesta a eventos — push, PR, schedule, release, o cualquier webhook.
¿Por qué elegirlo?
- Integración nativa — vive dentro del repositorio, sin configurar servicios externos
- Marketplace — más de 20,000 actions reutilizables
- Runners gratuitos — 2,000 minutos/mes en repos públicos (ilimitado), privados con límite por plan
- Matrix builds — testear en múltiples OS/versiones en paralelo
- Secrets management — variables encriptadas a nivel repo, environment y org
Anatomía de un workflow
# .github/workflows/ci.yml
name: CI # Nombre del workflow
on: # Triggers
push:
branches: [main]
pull_request:
branches: [main]
permissions: # Permisos del GITHUB_TOKEN
contents: read
env: # Variables globales
NODE_VERSION: 20
jobs: # Uno o más jobs
build:
runs-on: ubuntu-latest # Runner
steps:
- uses: actions/checkout@v4 # Action reutilizable
- uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
cache: 'pnpm'
- run: pnpm install # Comando shell
- run: pnpm test
- run: pnpm buildTriggers principales
on:
# Push y PRs
push:
branches: [main, 'release/**']
paths: ['src/**', 'package.json'] # solo si estos archivos cambian
pull_request:
types: [opened, synchronize, reopened]
# Programado (cron UTC)
schedule:
- cron: '0 6 * * 1' # lunes a las 6:00 UTC
# Manual desde UI o API
workflow_dispatch:
inputs:
environment:
description: 'Deploy target'
required: true
type: choice
options: [staging, production]
# Cuando se publica un release
release:
types: [published]
# Cuando otro workflow termina
workflow_run:
workflows: [CI]
types: [completed]Jobs y dependencias
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm test
# Deploy solo si lint y test pasan
deploy:
needs: [lint, test]
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- run: ./deploy.shMatrix strategy
Testear en múltiples combinaciones:
jobs:
test:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
node: [18, 20, 22]
fail-fast: false # no cancelar otros si uno falla
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- run: npm testSecrets y variables
jobs:
deploy:
runs-on: ubuntu-latest
environment: production # environment con protecciones
steps:
- run: ./deploy.sh
env:
API_KEY: ${{ secrets.API_KEY }}
DEPLOY_URL: ${{ vars.DEPLOY_URL }}Niveles de secrets:
- Repository — disponibles en todos los workflows del repo
- Environment — requieren aprobación y tienen reglas de protección
- Organization — compartidos entre repos de la org
Caching
- uses: actions/cache@v4
with:
path: |
~/.pnpm-store
node_modules
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-Artifacts
Compartir archivos entre jobs o descargar después:
- uses: actions/upload-artifact@v4
with:
name: build-output
path: dist/
retention-days: 7
# En otro job:
- uses: actions/download-artifact@v4
with:
name: build-outputReusable workflows
Definir workflows que otros repos pueden llamar:
# .github/workflows/reusable-deploy.yml
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
deploy_key:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: echo "Deploying to ${{ inputs.environment }}"# Llamar desde otro workflow
jobs:
deploy:
uses: org/repo/.github/workflows/reusable-deploy.yml@main
with:
environment: production
secrets:
deploy_key: ${{ secrets.DEPLOY_KEY }}Composite actions
Crear actions propias combinando steps:
# .github/actions/setup-project/action.yml
name: Setup Project
description: Install dependencies and build
runs:
using: composite
steps:
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install --frozen-lockfile
shell: bash
- run: pnpm build
shell: bashSeguridad
# Principio de mínimo privilegio
permissions:
contents: read
pull-requests: write
# Pinear actions por SHA (no por tag)
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
# Limitar permisos del GITHUB_TOKEN por defecto
# Settings → Actions → General → Workflow permissions → Read repository contentsCostos y límites
| Plan | Minutos/mes | Storage |
|---|---|---|
| Free | 2,000 | 500 MB |
| Team | 3,000 | 2 GB |
| Enterprise | 50,000 | 50 GB |
Repos públicos: minutos ilimitados en runners Linux.
Anti-patrones
- Workflows monolíticos — un YAML de 500 líneas. Dividir en reusable workflows.
- Sin caché — reinstalar dependencias en cada run desperdicia minutos.
- Secrets en logs —
echo $SECRETlos expone. GitHub los enmascara pero no confiar ciegamente. - Tags mutables en actions —
@v4puede cambiar. Pinear por SHA para seguridad. - Sin timeout — jobs que cuelgan consumen minutos. Siempre definir
timeout-minutes.
¿Por qué importa?
GitHub Actions eliminó la necesidad de mantener un servidor de CI separado para la mayoría de los proyectos. Al vivir junto al código, los workflows son versionados, revisados en PRs y ejecutados sin configuración externa. Para proyectos open source, los minutos gratuitos lo hacen la opción por defecto.
Referencias
- GitHub Actions Documentation — GitHub, 2024. Documentación oficial completa.
- GitHub Actions Marketplace — GitHub, 2024. Catálogo de actions reutilizables.
- Security Hardening for GitHub Actions — GitHub, 2024. Guía oficial de seguridad.
- Awesome Actions — Sarah Drasner, 2024. Colección curada de actions por categoría.
- GitHub Actions: The Full Course — Fireship, 2023. Introducción visual en 100 segundos + tutorial.