Fortgeschrittenes CI/CD für JavaScript-Projekte mit GitHub Actions
Die Automatisierung von Build, Test und Deployment (CI/CD) ist ein wesentlicher Bestandteil der modernen JavaScript-Entwicklung. Wenn Sie die grundlegenden GitHub Actions-Pipelines bereits beherrschen, ist es Zeit, auf die nächste Stufe zu gehen. In diesem Artikel behandeln wir fortgeschrittene Techniken: Caching von Abhängigkeiten, Matrix-Builds, parallele Aufgabenausführung, sicheres Arbeiten mit Secrets und automatisches Deployment auf VPS und in Docker. Alle Beispiele sind auf Node.js-Projekte ausgerichtet.
1. Optimierung der Build-Zeit: Caching und bedingte Ausführungen
Eines der Hauptprobleme grundlegender Pipelines ist die lange Installation von node_modules bei jedem Durchlauf. GitHub Actions ermöglicht das Caching von Abhängigkeiten, was die Ausführungszeit um das 2- bis 4-fache verkürzt.
Verwenden Sie die Aktion actions/cache zum Caching von node_modules oder ~/.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 ciFortgeschrittene Tipps:
- Verwenden Sie
hashFiles('package-lock.json')zur präzisen Invalidierung des Caches bei Änderungen der Abhängigkeiten. - Cachen Sie für Monorepos jedes Paket separat mit
path: packages/*/node_modules. - Fügen Sie bedingte Ausführungen hinzu (
if: github.ref == 'refs/heads/main'), damit aufwändige Aufgaben (z. B. der Build der Produktionsversion) nur bei Pushes in den main-Branch ausgeführt werden.
2. Matrix-Builds und parallele Aufgaben
Die Matrix-Strategie ermöglicht es, denselben Workflow mit verschiedenen Parametern auszuführen. Dies ist unverzichtbar für Tests mit mehreren Node.js-Versionen oder Betriebssystemen.
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 testFür die parallele Ausführung unabhängiger Aufgaben (z. B. Linting, Unit-Tests, Integrationstests) verwenden Sie separate Jobs. Diese werden gleichzeitig ausgeführt und blockieren sich nicht gegenseitig:
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] # wartet auf Abschluss von lint und unit runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - run: npm ci - run: npm run test:integrationWichtig: Verwenden Sie needs, um die Ausführungsreihenfolge abhängiger Aufgaben festzulegen. Das spart Zeit und Ressourcen.
3. Fortgeschrittenes Deployment: Docker und VPS mit Artefakten
Nach erfolgreichen Tests muss die Anwendung bereitgestellt werden. Wir betrachten zwei gängige Szenarien: Deployment als Docker-Image und auf einem VPS.
3.1. Erstellen und Veröffentlichen eines Docker-Images
jobs: build-and-push: needs: [test] runs-on: ub