Developer Tools

GitHub Actions CI/CD: Crea, prueba e implementa flujos de trabajo desde cero

Aprende a configurar GitHub Actions para integración y despliegue continuos. Cubre triggers, jobs, matrices, secrets, caché, Docker y ejemplos de flujos de trabajo del mundo real.

10 min de lectura

Colaboración de código en GitHub en pantalla

GitHub Actions convierte cada push, pull request y merge en un pipeline automatizado: ejecuta pruebas, genera artefactos, analiza vulnerabilidades y despliega a producción. Es la plataforma CI/CD que vive directamente dentro de tu repositorio, sin infraestructura que gestionar.

Cómo funciona GitHub Actions

Cada workflow es un archivo YAML en .github/workflows/. Cuando se dispara un evento trigger, GitHub lanza una máquina virtual nueva, ejecuta tus jobs y reporta los resultados, todo en cuestión de segundos.

Push a main
  ↓
Workflow disparado
  ↓
Job: Build & Test (ubuntu-latest)
  ├── Paso 1: Checkout del código
  ├── Paso 2: Instalar Node.js
  ├── Paso 3: npm ci
  ├── Paso 4: npm test
  └── Paso 5: npm run build
  ↓
✅ Todas las verificaciones pasaron

Tu primer workflow

Crea .github/workflows/ci.yml:

name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - run: npm test
      - run: npm run build

Eso es todo. Cada push a main y cada PR ahora ejecuta tu suite de pruebas automáticamente.

Triggers: cuándo se ejecutan los workflows

Eventos de código

on:
  push:
    branches: [main, develop]
    paths: ['src/**', 'package.json']  # Solo ejecutar cuando estos cambian
  pull_request:
    types: [opened, synchronize]

Programado (cron)

on:
  schedule:
    - cron: '0 6 * * 1'  # Cada lunes a las 6:00 UTC

Ejecución manual

on:
  workflow_dispatch:
    inputs:
      environment:
        description: 'Destino de despliegue'
        required: true
        type: choice
        options: [staging, production]

Esto añade un botón "Run workflow" en la interfaz de GitHub donde puedes seleccionar parámetros.

Workflows reutilizables

on:
  workflow_call:
    inputs:
      node-version:
        type: string
        default: '20'

Llámalo desde otro workflow con uses: ./.github/workflows/reusable.yml.

Jobs y steps

Jobs en paralelo

Los jobs se ejecutan en paralelo por defecto:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run lint

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm test

  build:
    runs-on: ubuntu-latest
    needs: [lint, test]  # Espera a que ambos pasen
    steps:
      - uses: actions/checkout@v4
      - run: npm run build

Estrategia de matriz: prueba en múltiples versiones

Ejecuta el mismo job en múltiples configuraciones:

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [18, 20, 22]
        os: [ubuntu-latest, windows-latest]
      fail-fast: false
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
      - run: npm ci
      - run: npm test

Esto crea 6 jobs en paralelo (3 versiones × 2 sistemas operativos).

Secrets y variables de entorno

Usar secrets

Almacena valores sensibles en Settings → Secrets and variables → Actions:

steps:
  - name: Deploy
    env:
      API_KEY: ${{ secrets.API_KEY }}
      DATABASE_URL: ${{ secrets.DATABASE_URL }}
    run: ./deploy.sh

Los secrets se enmascaran en los logs y nunca se exponen a los forks.

Variables de entorno

# A nivel de workflow
env:
  NODE_ENV: production

jobs:
  build:
    # A nivel de job
    env:
      CI: true
    steps:
      - name: Build
        # A nivel de step
        env:
          VITE_API_URL: https://api.example.com
        run: npm run build

Caché para compilaciones más rápidas

Sin caché, cada ejecución descarga todas las dependencias desde cero. El caché reduce los tiempos de compilación entre un 50 y un 80 %:

- uses: actions/setup-node@v4
  with:
    node-version: 20
    cache: npm  # Caché de npm integrado

# O caché manual para otras herramientas
- uses: actions/cache@v4
  with:
    path: ~/.cache/pip
    key: ${{ runner.os }}-pip-${{ hashFiles('requirements.txt') }}
    restore-keys: |
      ${{ runner.os }}-pip-

Artefactos: compartir datos entre jobs

Sube las salidas de compilación desde un job y descárgalas en otro:

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm run build
      - uses: actions/upload-artifact@v4
        with:
          name: dist
          path: dist/

  deploy:
    needs: build
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: dist
      - run: ./deploy.sh

Ejemplos de flujos de trabajo del mundo real

Build y push de Docker

name: Docker

on:
  push:
    tags: ['v*']

permissions:
  packages: write

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - uses: docker/build-push-action@v5
        with:
          push: true
          tags: ghcr.io/${{ github.repository }}:${{ github.ref_name }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

Despliegue a Cloudflare Pages

name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci && npm run build
      - uses: cloudflare/wrangler-action@v3
        with:
          apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
          command: pages deploy dist --project-name=my-site

Release con changelog

name: Release

on:
  push:
    tags: ['v*.*.*']

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
      - name: Generar changelog
        run: |
          git log $(git describe --tags --abbrev=0 HEAD^)..HEAD \
            --pretty=format:"- %s" > CHANGELOG.md
      - uses: softprops/action-gh-release@v2
        with:
          body_path: CHANGELOG.md
          generate_release_notes: true

Ejecución condicional

Controla cuándo se ejecutan los steps y los jobs:

steps:
  - name: Desplegar a producción
    if: github.ref == 'refs/heads/main'
    run: ./deploy-prod.sh

  - name: Desplegar a staging
    if: github.event_name == 'pull_request'
    run: ./deploy-staging.sh

  - name: Notificar en caso de fallo
    if: failure()
    run: curl -X POST ${{ secrets.SLACK_WEBHOOK }} -d '{"text":"¡La compilación falló!"}'

Buenas prácticas de seguridad

1. Fija las versiones de las actions al SHA

# ❌ Tag mutable — podría verse comprometido
- uses: actions/checkout@v4

# ✅ Fijado al SHA exacto del commit
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11

2. Usa permisos de mínimo privilegio

permissions:
  contents: read    # Solo lo necesario
  packages: write

3. Nunca imprimas secrets en pantalla

# ❌ NUNCA hagas esto
- run: echo ${{ secrets.API_KEY }}

# ✅ Usa variables de entorno
- env:
    API_KEY: ${{ secrets.API_KEY }}
  run: ./script-that-uses-api-key.sh

4. Limita los permisos para PRs de forks

on:
  pull_request_target:  # Se ejecuta en el contexto de la rama base
    types: [opened, synchronize]

Depurar workflows fallidos

  1. Revisa los logs — Haz clic en cualquier step fallido para ver la salida completa
  2. Añade logging de depuración — Establece el secret ACTIONS_STEP_DEBUG en true
  3. Usa act localmente — Ejecuta workflows en tu máquina con nektos/act
  4. Accede por SSH al runner — Usa mxschmitt/action-tmate para depuración interactiva

Crea workflows visualmente

¿No quieres escribir YAML a mano? Usa nuestro GitHub Actions Generator para construir workflows visualmente con plantillas para Node.js, Python, Docker, despliegues y más — y descarga YAML listo para producción.

Conclusión

GitHub Actions te ofrece CI/CD que vive dentro de tu repositorio:

  1. Empieza simple — Un archivo de workflow con build + test
  2. Añade caché — Reduce los tiempos de compilación con actions/cache o el caché de lenguaje integrado
  3. Usa la matriz — Prueba en múltiples versiones y sistemas operativos
  4. Protege los secrets — Nunca los escribas en el código; usa siempre secrets cifrados
  5. Automatiza todo — Releases, despliegues, análisis de seguridad, tareas programadas

El mejor pipeline CI/CD es el que se ejecuta en cada commit sin que tengas que pensar en ello. Configúralo una vez y deja que GitHub se encargue del resto.