CI/CD Avanzado para JavaScript: GitHub Actions en la práctica

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

CI/CD Avanzado para proyectos JavaScript con GitHub Actions



La automatización de la compilación, las pruebas y el despliegue (CI/CD) es una parte esencial del desarrollo moderno en JavaScript. Si ya dominas los pipelines básicos de GitHub Actions, es hora de pasar al siguiente nivel. En este artículo, analizaremos técnicas avanzadas: caché de dependencias, compilaciones matriciales, ejecución paralela de tareas, trabajo seguro con secretos y despliegue automático en VPS y Docker. Todos los ejemplos están orientados a proyectos Node.js.



1. Optimización del tiempo de compilación: caché y ejecuciones condicionales



Uno de los principales problemas de los pipelines básicos es la larga instalación de node_modules en cada ejecución. GitHub Actions permite almacenar en caché las dependencias, lo que reduce el tiempo de ejecución entre 2 y 4 veces.



Utiliza la acción actions/cache para almacenar en caché node_modules o ~/.npm:



name: CI Pipelineon: [push, pull_request]

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

- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'

- name: Cache node_modules uses: actions/cache@v3 id: npm-cache with: path: node_modules key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }} restore-keys: | ${{ runner.os }}-node-

- name: Install dependencies if: steps.npm-cache.outputs.cache-hit != 'true' run: npm ci


Consejos avanzados:

  • Usa hashFiles('package-lock.json') para invalidar con precisión la caché al cambiar las dependencias.
  • Para monorepositorios, almacena en caché cada paquete por separado con path: packages/*/node_modules.
  • Añade ejecuciones condicionales (if: github.ref == 'refs/heads/main') para que las tareas pesadas (por ejemplo, la compilación de la versión de producción) se ejecuten solo en los pushes a la rama main.


2. Compilaciones matriciales y tareas paralelas



La estrategia matricial permite ejecutar un mismo workflow con diferentes parámetros. Es indispensable para probar en múltiples versiones de Node.js o sistemas operativos.



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


Para la ejecución paralela de tareas independientes (por ejemplo, linting, pruebas unitarias, pruebas de integración), utiliza jobs separados. Se ejecutan simultáneamente y no se bloquean entre sí:



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

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

integration-tests: needs: [lint, unit-tests] # espera a que lint y unit terminen runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test:integration


Importante: Usa needs para definir el orden de ejecución de las tareas dependientes. Esto ahorra tiempo y recursos.



3. Despliegue avanzado: Docker y VPS usando artefactos



Después de las pruebas exitosas, es necesario desplegar la aplicación. Consideremos dos escenarios populares: despliegue en una imagen Docker y en un VPS.



3.1. Compilación y publicación de una imagen Docker



jobs:  build-and-push:    needs: [test]    runs-on: ub                

Blogs

Book Recommendations