Conceptos

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.

evergreen#ci-cd#automation#github#devops

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 build

Triggers 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.sh

Matrix 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 test

Secrets 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-output

Reusable 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: bash

Seguridad

# 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 contents

Costos y límites

PlanMinutos/mesStorage
Free2,000500 MB
Team3,0002 GB
Enterprise50,00050 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 logsecho $SECRET los expone. GitHub los enmascara pero no confiar ciegamente.
  • Tags mutables en actions@v4 puede 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

Conceptos