GitHub Actions ermöglicht CI/CD direkt in GitHub-Repositories. Workflows werden in YAML definiert und bei Events wie Push oder Pull Request ausgeführt.
Grundlagen
Workflow-Struktur
# .github/workflows/ci.yml
name: CI Pipeline
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
run: npm testKonzepte
| Begriff | Beschreibung | |---------|--------------| | Workflow | Automatisierter Prozess | | Job | Gruppe von Steps | | Step | Einzelne Aktion | | Action | Wiederverwendbare Einheit | | Runner | Ausführungsumgebung |
Trigger (Events)
Push und Pull Request
on:
push:
branches: [main, develop]
paths:
- 'src/**'
- 'package.json'
pull_request:
branches: [main]Scheduled (Cron)
on:
schedule:
- cron: '0 6 * * *' # Täglich um 06:00 UTCManual (workflow_dispatch)
on:
workflow_dispatch:
inputs:
environment:
description: 'Deploy environment'
required: true
default: 'staging'
type: choice
options:
- staging
- productionRelease
on:
release:
types: [published]Jobs und Steps
Mehrere Jobs
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
build:
runs-on: ubuntu-latest
needs: test # Wartet auf test-Job
steps:
- uses: actions/checkout@v4
- run: npm run build
deploy:
runs-on: ubuntu-latest
needs: [test, build] # Wartet auf beide
steps:
- run: echo "Deploying..."Matrix-Builds
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [16, 18, 20]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm testBedingte Ausführung
jobs:
deploy:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- run: echo "Deploying to production"
test:
runs-on: ubuntu-latest
steps:
- run: echo "Always runs"
- run: echo "Only on failure"
if: failure()
- run: echo "Always, even on cancel"
if: always()Umgebungsvariablen
Definition
env:
NODE_ENV: production
jobs:
build:
runs-on: ubuntu-latest
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
steps:
- name: Print env
run: echo $NODE_ENV
env:
STEP_VAR: valueGitHub Context
steps:
- name: Info
run: |
echo "Repository: ${{ github.repository }}"
echo "Branch: ${{ github.ref_name }}"
echo "SHA: ${{ github.sha }}"
echo "Actor: ${{ github.actor }}"
echo "Event: ${{ github.event_name }}"Secrets
Secrets verwenden
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy
run: |
echo "${{ secrets.SSH_KEY }}" > key.pem
chmod 600 key.pem
ssh -i key.pem user@server deploy.sh
env:
API_KEY: ${{ secrets.API_KEY }}GITHUB_TOKEN
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Create Release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}Beliebte Actions
Checkout
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Vollständige Historie
submodules: trueSetup Node.js
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'Setup Python
- uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'Docker Build & Push
- uses: docker/setup-buildx-action@v3
- 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 }}:latestCache
- uses: actions/cache@v4
with:
path: ~/.npm
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-Praktische Workflows
Node.js CI
name: Node.js CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Run linter
run: npm run lint
- name: Run tests
run: npm test
- name: Build
run: npm run build
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: build
path: dist/Docker Deploy
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: |
user/app:latest
user/app:${{ github.sha }}
- name: Deploy to server
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USERNAME }}
key: ${{ secrets.SSH_KEY }}
script: |
docker pull user/app:latest
docker-compose up -dRelease Workflow
name: Release
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: npm run build
- name: Create Release
uses: softprops/action-gh-release@v1
with:
files: |
dist/*.js
dist/*.css
generate_release_notes: truePull Request Checks
name: PR Check
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check PR title
run: |
if [[ ! "${{ github.event.pull_request.title }}" =~ ^(feat|fix|docs|style|refactor|test|chore): ]]; then
echo "PR title must follow conventional commits"
exit 1
fi
- name: Run tests
run: npm test
- name: Comment on PR
uses: actions/github-script@v7
if: failure()
with:
script: |
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: '❌ Tests failed. Please check the logs.'
})Environments
Environment definieren
jobs:
deploy-staging:
runs-on: ubuntu-latest
environment: staging
steps:
- run: echo "Deploying to staging"
deploy-production:
runs-on: ubuntu-latest
environment:
name: production
url: https://example.com
needs: deploy-staging
steps:
- run: echo "Deploying to production"Mit Approval
GitHub → Repository → Settings → Environments → production
→ Required reviewers hinzufügenSelf-hosted Runners
Runner installieren
# Download
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64.tar.gz -L https://github.com/actions/runner/releases/download/v2.311.0/actions-runner-linux-x64-2.311.0.tar.gz
tar xzf ./actions-runner-linux-x64.tar.gz
# Konfigurieren (URL und Token von GitHub)
./config.sh --url https://github.com/user/repo --token TOKEN
# Als Service installieren
sudo ./svc.sh install
sudo ./svc.sh startSelf-hosted Runner verwenden
jobs:
build:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4
- run: ./build.shReusable Workflows
Caller Workflow
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
call-deploy:
uses: ./.github/workflows/reusable-deploy.yml
with:
environment: production
secrets:
ssh_key: ${{ secrets.SSH_KEY }}Reusable Workflow
# .github/workflows/reusable-deploy.yml
name: Reusable Deploy
on:
workflow_call:
inputs:
environment:
required: true
type: string
secrets:
ssh_key:
required: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to ${{ inputs.environment }}
run: deploy.sh
env:
SSH_KEY: ${{ secrets.ssh_key }}Zusammenfassung
| Event | Beschreibung | |-------|--------------| | push | Bei Push | | pull_request | Bei PR | | schedule | Zeitgesteuert | | workflow_dispatch | Manuell | | release | Bei Release |
| Action | Verwendung | |--------|------------| | actions/checkout | Repository klonen | | actions/setup-node | Node.js einrichten | | actions/cache | Cache verwalten | | docker/build-push-action | Docker Build |
| Context | Beispiel | |---------|----------| | github.ref | refs/heads/main | | github.sha | Commit-SHA | | github.actor | Username | | secrets.NAME | Secret-Wert |
Fazit
GitHub Actions bietet CI/CD direkt in GitHub integriert. Die YAML-Syntax ist gut lesbar, und der Marketplace bietet tausende fertige Actions. Matrix-Builds ermöglichen paralleles Testen verschiedener Konfigurationen. Mit Environments und Approvals wird auch komplexes Deployment Management möglich. Für Projekte auf GitHub ist es oft die einfachste CI/CD-Lösung.