GitHub Actions
GitHub Actions ist eine in GitHub integrierte Automatisierungsplattform, mit der Sie automatisierte Workflows direkt in Ihrem Coderepository definieren und ausführen können, ohne auf externe CI/CD-Tools angewiesen zu sein.
Häufige Anwendungsfälle sind: automatisches Ausführen von Tests nach einem Code-Push, automatisches Bereitstellen auf Servern nach dem Mergen von PRs und das zeitgesteuerte Ausführen von Daten-Scraping-Skripten.

GitHub Actions vsÖffentliche Repositories sind völlig kostenlos., private Repositories haben ein kostenloses Kontingent von 2,000 Minuten pro Monat.
Kernkonzepte
Bevor Sie die Konfigurationsdatei schreiben, müssen Sie die folgenden Kernkonzepte verstehen; die Beziehungen zwischen ihnen sind wie folgt:
仓库(Repository)
└── Workflow(工作流) ← 一个 .yml 文件 = 一个 Workflow
├── Event(触发事件) ← 什么情况下启动这个 Workflow,如 push、PR
└── Job(作业)× N ← 一个 Workflow 可以包含多个并行或串行的 Job
├── Runner(运行器) ← 执行 Job 的服务器,如 ubuntu-latest
└── Step(步骤)× N ← Job 内按顺序执行的一系列操作
├── Action ← 可复用的封装好的操作,如 actions/checkout
└── Run ← 直接执行 Shell 命令
| Konzepte | Beschreibung | Analogie |
|---|---|---|
| Workflow | Der gesamte automatisierte Workflow wird durch eine.ymlDatei, gespeichert in.github/workflows/unter dem Verzeichnis |
ein vollständiger Arbeitsplan. |
| Ereignis | Bedingungen, die den Workflow auslösen, wie z. B. Code-Push, PR-Erstellung, geplante Aufgaben usw. | Die Startbedingung des Plans. |
| Job(Aufgabe) | Eine unabhängige Aufgabeneinheit in einem Workflow. Jeder Job läuft auf einer unabhängigen virtuellen Maschine, und mehrere Jobs werden standardmäßig parallel ausgeführt. | Ein Abschnitt im Plan. |
| Schritt | Die kleinste Ausführungseinheit, die innerhalb eines Jobs sequenziell ausgeführt wird und entweder ein Shell-Befehl oder eine Action sein kann. | Jeder spezifische Schritt innerhalb eines Abschnitts. |
| Aktion | Wiederverwendbare paketierte Operationen, von GitHub offiziell, von Drittanbietern oder selbst geschrieben, überusesReferenz |
Vorgefertigte Tool-Vorlagen |
| Runner | Server, der Jobs ausführt. GitHub stellt drei gehostete Umgebungen bereit: Ubuntu, Windows und macOS. | Der Worker, der den Plan ausführt. |
Erstelle deinen ersten Workflow.
1. Verzeichnisstruktur
Alle Workflow-Dateien müssen im.github/workflows/Repository-Stammverzeichnis gespeichert werden, und die Dateinamen müssen mit.ymloder.yamlDer Dateiname kann angepasst werden:
your-repo/ ├── .github/ │ └── workflows/ │ ├── ci.yml ← 持续集成流程(如运行测试) │ ├── deploy.yml ← 部署流程 │ └── scheduled.yml ← 定时任务 ├── src/ ├── package.json └── README.md
Ein Repository kann mehrere Workflow-Dateien enthalten, die voneinander unabhängig sind und durch ihre jeweils definierten Ereignisse ausgelöst werden.
2. Der einfachste Workflow
Das folgende ist ein grundlegendes Beispiel: Jedes Mal, wenn Code in das Repository gepusht wird, wird eine Zeile "Hello, GitHub Actions!" ausgegeben:
Beispiel
name: Hello World # Name des Workflows, angezeigt auf der GitHub Actions-Seite
on: push # Auslöserbedingung: wird ausgelöst, wenn Code in einen beliebigen Branch gepusht wird
jobs: # Alle Jobs definieren
say-hello: # Job-ID (benutzerdefinierter Name, eindeutig innerhalb desselben Workflows)
name: Begrüßung ausgeben# Anzeigename des Jobs (optional; wenn leer, wird die Job-ID angezeigt)
runs-on: ubuntu-latest # Laufzeitumgebung angeben: die neueste von GitHub bereitgestellte virtuelle Ubuntu-Maschine verwenden
steps: # Alle Schritte unter diesem Job werden in der Reihenfolge ausgeführt
- name: printMessage# Der Name des Schritts (optional, wird verwendet, um diesen Schritt in Logs zu identifizieren)
run: echo "Hello, GitHub Actions!" # run: Shell-Befehle direkt ausführen
YAML-Dateien reagieren sehr empfindlich auf Einrückungen und müssenLeerzeichen-Einrückung verwenden, und die Tab-Taste darf nicht verwendet werden. Es wird empfohlen, VS Code zu verwenden und das YAML-Plugin zu installieren, das Formatfehler in Echtzeit erkennen kann.
Trigger-Ereignisse (on)
onDas Feld definiert, welche Ereignisse diesen Workflow auslösen. Es kann ein einzelnes Ereignis oder eine Kombination mehrerer Ereignisse sein.
1. Häufige Trigger-Ereignisse
| Ereignisse | Auslösezeitpunkt | Übliche Verwendungen |
|---|---|---|
push |
Wenn Code in das Repository gepusht wird. | Tests ausführen, Code-Prüfungen |
pull_request |
Wenn ein Pull Request erstellt oder aktualisiert wird. | Automatisierte Überprüfung und Tests vor dem PR-Merge. |
schedule |
Ausgelöst nach Zeitplan mithilfe eines Cron-Ausdrucks. | Geplante Backups, geplantes Daten-Scraping. |
workflow_dispatch |
Manuell auf der GitHub-Webseite auslösen | On-Demand-Deployment, manuelle Skriptausführung. |
release |
Beim Veröffentlichen einer neuen Version (Erstellen eines Releases) | Automatisches Paketieren und Veröffentlichen in der Produktion. |
workflow_call |
Wenn von anderen Workflows aufgerufen | Öffentliche Workflows wiederverwenden (z. B. öffentliche Test-Workflows) |
2. Branch- oder Pfadfilterung
Beispiel
on:
push:
branches:
- main # Nur auslösen, wenn in den main-Branch gepusht wird
- develop # Oder auslösen, wenn in den develop-Branch gepusht wird
- 'release/**' # Oder auslösen, wenn in einen beliebigen Branch gepusht wird, der mit release/ beginnt (** entspricht beliebigen Zeichen)
paths:
- 'src/**' # Weitere Filterung: Nur auslösen, wenn sich Dateien im Verzeichnis src/ ändern.
- 'package.json' # Oder auslösen, wenn sich die Datei package.json ändert
# Die beiden stehen in einer 'OR'-Beziehung; eines von beiden löst aus
pull_request:
branches:
- main # Nur bei PRs auslösen, deren Zielbranch main ist (d. h. PRs, die in main gemergt werden sollen)
types:
- opened # Wenn ein PR erstellt wird
- synchronize # Wenn ein neuer Commit zum PR gepusht wird
- reopened # Wenn ein PR erneut geöffnet wird
3. Zeitgesteuerte Auslöser (schedule)
Verwenden Sie einen Standard-Cron-Ausdruck, um die Ausführungszeit festzulegen; die Zeitzone ist UTC (Beijing-Zeit = UTC+8, Umrechnung erforderlich):
Beispiel
on:
schedule:
# Cron-Format: Minute Stunde Tag Monat Woche
- cron: '0 2 * * *' # Täglich einmal um 02:00 UTC ausführen (d. h. 10:00 Beijing-Zeit)
- cron: '0 9 * * 1' # Einmal jeden Montag um 09:00 UTC ausführen (d. h. 17:00 Pekinger Zeit)
- cron: '*/30 * * * *' # Alle 30 Minuten ausführen
# Schnellreferenz für gängige Cron-Ausdrücke:
# '0 0 * * *' Jeden Tag um Mitternacht (UTC 00:00)
# '0 * * * *' jede Stunde zur vollen Stunde
# '0 0 * * 0' jeden Sonntag um Mitternacht
# '0 0 1 * *' Mitternacht am 1. jedes Monats
4. Manuelle Auslösung (workflow_dispatch)
workflow_dispatchErmöglicht das manuelle Anklicken einer Schaltfläche auf der Registerkarte „Actions“ der GitHub-Webseite, um den Workflow zu starten, und Sie können auch Eingabeparameter definieren:
Beispiel
on:
workflow_dispatch:
inputs:
environment: # Name des Eingabeparameters (kann in Schritten über ${{ inputs.environment }} referenziert werden)
description: 'Deployment-Zielumgebung'# Parameterbeschreibung, angezeigt im Formular für die manuelle Auslösung
required: true # Ist es erforderlich?
default: 'staging' # Standardwert
type: choice # Parametertyp: choice (Dropdown-Auswahl)
options:
- staging # Optionale Werte
- production
run_tests:
description: 'Ob Tests ausgeführt werden sollen'
required: false
type: boolean # Parametertyp: Boolean (Kontrollkästchen)
default: true
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Bereitstellungsparameter anzeigen
run: |
echo "Zielumgebung: ${{ inputs.environment }}"
echo "Tests ausführen: ${{ inputs.run_tests }}"
Detaillierte Erklärung von Jobs und Steps
1. Grundstruktur eines Jobs
Beispiel
jobs:
build: # Job-ID, muss innerhalb desselben Workflows eindeutig sein
name: structurebuildProject# Anzeigename des Jobs (optional)
runs-on: ubuntu-latest # Laufzeitumgebung (erforderlich)
# Optional: Umgebungsvariablen für den gesamten Job festlegen, auf die alle Steps im Job zugreifen können
env:
NODE_ENV: production
APP_PORT: 8080
# Optional: Timeout in Minuten festlegen. Der Job wird nach Ablauf des Timeouts automatisch abgebrochen, um ein Hängen zu verhindern.
timeout-minutes: 30
steps:
# Schritt-Methode 1: Eine Action verwenden (mit uses referenzieren)
- name: Code auschecken
uses: actions/checkout@v4 # Verweis auf die offizielle checkout Action (@v4 gibt an, dass die Version v4 verwendet wird)
# Schritt-Syntax 2: Shell-Befehl ausführen (mit run angegeben)
- name: Node-Version ausgeben
run: node --version
# Schritt 3: Mehrzeilige Shell-Befehle ausführen (mit | für mehrere Zeilen)
- name: Abhängigkeiten installieren und Build erstellen
run: |
npm install
npm run build
echo "Build abgeschlossen"
2. Laufzeitumgebung (runs-on)
GitHub stellt die folgenden kostenlosen gehosteten Runner bereit, die du nach Bedarf auswählen kannst:
| Tags | Betriebssystem | Beschreibung |
|---|---|---|
ubuntu-latest |
Ubuntu (Neueste LTS) | Am häufigsten verwendet, schnell und bietet das großzügigste kostenlose Kontingent. Für vorrangige Verwendung empfohlen. |
ubuntu-22.04 |
Ubuntu 22.04 | Geben Sie eine feste Version an, um Inkompatibilitätsprobleme durch die neuesten Upgrades zu vermeiden. |
windows-latest |
Windows Server (Neueste) | Wird für Tests oder Builds verwendet, die eine Windows-Umgebung erfordern. |
macos-latest |
macOS (Neueste) | Wird für iOS-/macOS-App-Builds verwendet, verbraucht das kostenlose Kontingent am schnellsten (etwa 10-mal so viel wie das von Ubuntu). |
3. Abhängigkeiten zwischen Jobs (needs)
Standardmäßig werden mehrere Jobs parallel ausgeführt. Verwenden SieneedsSie können die Ausführungsreihenfolge von Jobs festlegen und so serielle Abhängigkeitsbeziehungen bilden:
Beispiel
jobs:
test: # Schritt 1: Tests ausführen
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm test
build: # Schritt 2: Das Projekt bauen
runs-on: ubuntu-latest
needs: test # build startet erst, nachdem der test-Job erfolgreich abgeschlossen wurde
steps:
- uses: actions/checkout@v4
- run: npm run build
deploy: # Schritt 3: Bereitstellung
runs-on: ubuntu-latest
needs: [test, build] # Deploy muss warten, bis sowohl test als auch build erfolgreich abgeschlossen sind
steps:
- run: echo Bereitstellung wird gestartet...
# Ausführungsreihenfolge: test → build → deploy (sequenziell)
# Wenn needs entfernt wird, werden die drei Jobs parallel ausgeführt.
4. Bedingte Ausführung (if)
DurchifSie können steuern, ob ein Job oder ein Step ausgeführt wird; dies wird häufig verwendet, um Branches zu unterscheiden, festzustellen, ob der vorherige Step erfolgreich war, usw.:
Beispiel
jobs:
deploy:
runs-on: ubuntu-latest
# if auf Job-Ebene geschrieben: Der gesamte Job wird nur ausgeführt, wenn in den main-Branch gepusht wird
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Bereitstellung in der Produktionsumgebung
run: ./deploy.sh
# if kann auch auf Step-Ebene geschrieben werden, um zu steuern, ob ein bestimmter Step ausgeführt wird
- name: Erfolgsbenachrichtigung senden
if: success() # success(): Wird nur ausgeführt, wenn alle oben genannten Steps erfolgreich sind
run: echo "Bereitstellung erfolgreich, Benachrichtigung senden"
- name: Fehlerbenachrichtigung senden
if: failure() # failure(): Wird nur ausgeführt, wenn ein beliebiger Step fehlschlägt
run: echo Bereitstellung fehlgeschlagen, Alarm senden
- name: Cleanup-Steps werden immer ausgeführt
if: always() # always(): Wird unabhängig von Erfolg oder Fehler ausgeführt (wird oft zum Aufräumen temporärer Dateien verwendet)
run: rm -rf ./tmp
Umgebungsvariablen und Secrets
1. Umgebungsvariablen (env)
Umgebungsvariablen können im Workflow auf drei Ebenen definiert werden, wobei der Geltungsbereich in dieser Reihenfolge abnimmt:
Beispiel
env:
APP_NAME: my-app
NODE_VERSION: '18'
jobs:
build:
runs-on: ubuntu-latest
# Ebene 2: Job-Ebene (nur Steps innerhalb des aktuellen Jobs haben Zugriff)
env:
BUILD_MODE: production
steps:
- name: Umgebungsvariablen anzeigen
# Ebene 3: Step-Ebene (nur der aktuelle Step hat Zugriff)
env:
STEP_VAR: hello
run: |
echo "Anwendungsname: $APP_NAME" # Zugriff auf Variable auf Workflow-Ebene
echo "Build-Modus: $BUILD_MODE" # Zugriff auf Variable auf Job-Ebene
echo "Step-Variable: $STEP_VAR" # Zugriff auf Variable auf Step-Ebene
echo "Node-Version: $NODE_VERSION"
2. Integrierte GitHub-Variablen (github-Kontext)
GitHub Actions bietet eine Reihe integrierter Kontextvariablen, auf die überall zugegriffen werden kann mittels${{ }}Syntaxreferenz:
Beispiel
steps:
- name: Häufige integrierte Variablen ausgeben
run: |
echo "Repository-Name: ${{ github.repository }}" # Zum Beispiel: your-user/your-repo
echo "Auslösendes Ereignis: ${{ github.event_name }}" # z. B. push, pull_request
echo "Aktueller Branch: ${{ github.ref_name }}" # z. B. main, develop
echo "Commit SHA:${{ github.sha }}" # aktueller Commit SHA-Hash-Wert
echo "Committer: ${{ github.actor }}" # Benutzername, der diesen Workflow ausgelöst hat
echo "Arbeitsverzeichnis: ${{ github.workspace }}" # Der Verzeichnispfad, in dem sich der Code nach dem Checkout befindet
echo "Lauf-ID:${{ github.run_id }}" # eindeutige ID des Workflow-Laufs
echo "Laufnummer:${{ github.run_number }}" # Laufnummer, wie oft dieser Workflow ausgeführt wurde
3. Secrets (Verwaltung sensibler Informationen)
Sensible Informationen wie Passwörter, API-Schlüssel, Serveradressen usw.können nicht direkt in die yml-Datei geschrieben werden.(Da der Code öffentlich ist), müssen sie in den Secrets des GitHub-Repositorys gespeichert werden.
Einrichtungsschritte: Gehe zur Repository-Seite →Einstellungen → Secrets und Variablen → Actions→ Klicke aufNeues Repository-SecretName und Wert eingeben und dann speichern.
Beispiel
steps:
# Im Step wird das konfigurierte Secret über ${{ secrets.secret_name }} referenziert
# Secret-Werte werden in Logs automatisch mit *** maskiert und nicht preisgegeben
- name: Auf Server bereitstellen
env:
SSH_KEY: ${{ secrets.SSH_PRIVATE_KEY }} # Privater SSH-Schlüssel des Servers
SERVER_IP: ${{ secrets.DEPLOY_SERVER_IP }} # Server-IP-Adresse
run: |
echo "$SSH_KEY" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh user@$SERVER_IP "cd /app && git pull && pm2 restart all"
# GitHub stellt GITHUB_TOKEN automatisch für Operationen in diesem Repository bereit (z. B. Code pushen, Releases erstellen)
# Muss nicht manuell erstellt werden, einfach direkt verwenden
- name: Änderungen ins Repository pushen
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add .
git commit -m "Automatisches Update [skip ci]"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # GitHub stellt automatisch bereit, keine manuelle Erstellung erforderlich
Einführung in gängige Actions
GitHub offiziell und die Community bieten eine große Anzahl sofort einsatzbereiter Actions, durchuses: action名称@版本Referenzen, können Sie vermeiden, gängige Operationen wiederholt zu schreiben.
1. actions/checkout (Code abrufen)
Fast der erste Schritt jedes Workflows ist das Abrufen des Repository-Codes mit der offiziellenactions/checkout:
Beispiel
steps:
# Die grundlegendste Verwendung: den neuesten Code des aktuellen Branches in das Arbeitsverzeichnis abrufen
- uses: actions/checkout@v4
# Erweiterte Verwendung: Anpassung durch Übergeben von Parametern mit 'with'
- uses: actions/checkout@v4
with:
ref: develop # Den angegebenen Branch abrufen (standardmäßig wird der Branch abgerufen, in dem das auslösende Ereignis liegt)
fetch-depth: 0 # Die vollständige Git-Historie abrufen (standardmäßig wird nur der neueste Commit abgerufen)
# Auf 0 setzen, um die gesamte Historie abzurufen, damit Befehle wie git log ordnungsgemäß funktionieren.
submodules: true # Auch Git-Submodule initialisieren und aktualisieren
2. actions/setup-node (Node.js-Umgebung konfigurieren)
Beispiel
steps:
- uses: actions/checkout@v4
- name: Node.js-Umgebung konfigurieren
uses: actions/setup-node@v4
with:
node-version: '20' # Node.js-Version angeben
# Nach Abschluss der Konfiguration können npm- und node-Befehle direkt verwendet werden
- run: node --version
- run: npm install
- run: npm test
3. actions/setup-python (Python-Umgebung konfigurieren)
Beispiel
steps:
- uses: actions/checkout@v4
- name: Python-Umgebung konfigurieren
uses: actions/setup-python@v5
with:
python-version: '3.11' # Python-Version angeben
- name: Abhängigkeiten installieren
run: pip install -r requirements.txt
- name: Tests ausführen
run: pytest tests/
4. actions/cache (Abhängigkeiten zwischenspeichern, um Builds zu beschleunigen)
Das Herunterladen von Abhängigkeiten bei jedem Workflow-Lauf kann langsam sein. Durch die Verwendung der Cache-Action können Abhängigkeiten zwischengespeichert und beim nächsten Lauf direkt verwendet werden, wodurch die Build-Zeit erheblich reduziert wird:
Beispiel
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: node_modules zwischenspeichern
uses: actions/cache@v4
with:
path: ~/.npm # Verzeichnis zum Zwischenspeichern angeben
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
# key: eindeutige Kennung für den Cache
# hashFiles('**/package-lock.json'): Hash-Wert basierend auf dem Inhalt der Lock-Datei generieren
# Wenn die Lock-Datei unverändert ist, ist der Schlüssel unverändert, und der Cache wird direkt getroffen; wenn sich die Lock-Datei ändert, werden die Abhängigkeiten neu installiert.
restore-keys: |
${{ runner.os }}-node-
# restore-keys: Fallback-Übereinstimmungsstrategie, wenn der Schlüssel nicht passt, wobei der zuletzt gültige Cache verwendet wird
- run: npm ci # npm ci ist für CI-Szenarien besser geeignet als npm install, schneller und strikter
- run: npm test
5. actions/upload-artifact / download-artifact (Dateien zwischen Jobs übertragen)
Verschiedene Jobs laufen auf unabhängigen virtuellen Maschinen, daher können Dateien nicht direkt gemeinsam genutzt werden. Mit Artefakten können Sie die Ausgabedateien eines Jobs an einen anderen Job übergeben:
Beispiel
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install && npm run build # Build-Artefakte werden in das Verzeichnis ./dist ausgegeben
- name: Build-Artefakte hochladen
uses: actions/upload-artifact@v4
with:
name: dist-files # Name des Artefakts (wird beim Herunterladen unter diesem Namen referenziert)
path: ./dist # Das Verzeichnis oder der Dateipfad zum Hochladen
retention-days: 7 # Aufbewahrungstage für Artefakte (max. 90 Tage)
deploy:
runs-on: ubuntu-latest
needs: build # Ausführen, nachdem der Build-Job abgeschlossen ist
steps:
- name: Build-Artefakte herunterladen
uses: actions/download-artifact@v4
with:
name: dist-files # Wie der Name beim Upload
path: ./dist # Verzeichnis zum lokalen Herunterladen
- name: DeploymentFile
run: rsync -avz ./dist/ user@server:/var/www/html/
Matrix-Builds (Matrix)
Matrix-Builds ermöglichen es Ihnen, eine einzelne Job-Konfiguration parallel in mehreren Umgebungen auszuführen, häufig verwendet für Kompatibilitätstests über Versionen und Betriebssysteme hinweg:
Beispiel
jobs:
test:
name: Node testen ${{ matrix.node-version }} auf ${{ matrix.os }}
runs-on: ${{ matrix.os }} # Laufzeitumgebung aus Matrix-Variablen auslesen
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest] # 3 Betriebssysteme
node-version: ['18', '20', '22'] # 3 Node-Versionen
# Die obigen Kombinationen erzeugen 3 × 3 = 9 parallele Jobs
fail-fast: false # Standardmäßig true: Alle verbleibenden Jobs abbrechen, wenn ein Job fehlschlägt.
# Auf false setzen: Selbst wenn eine Kombination fehlschlägt, werden andere Kombinationen weiter ausgeführt,
# Praktisch, um Testergebnisse für alle Umgebungen zu sehen
steps:
- uses: actions/checkout@v4
- name: Node.js konfigurieren ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }} # Matrixvariablen referenzieren
- run: npm ci
- run: npm test
Beispiel
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
node-version: ['18', '20']
exclude:
- os: windows-latest
node-version: '18' # Kombination Windows + Node 18 ausschließen
include:
- os: ubuntu-latest
node-version: '20'
experimental: true # Zusätzliche Variablen für bestimmte Kombinationen anhängen (können in Schritten über matrix.experimental referenziert werden)
Praktische Beispiele
Beispiel 1: CI für Node.js-Projekt (automatisierte Tests)
Jedes Mal, wenn Code gepusht oder ein PR erstellt wird, automatisch Abhängigkeiten installieren und Code-Prüfungen und Tests ausführen:
Beispiel
name: Node.js CI
auf:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
name: CodeChecksandTesting
runs-on: ubuntu-latest
steps:
- name: Code auschecken
uses: actions/checkout@v4
- name: Node.js-Umgebung konfigurieren
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm' # setup-node bietet integrierte Cache-Unterstützung, was prägnanter ist als die separate Verwendung der cache-Action
- name: Abhängigkeiten installieren
run: npm ci # npm ci installiert strikt gemäß package-lock.json,
# Für CI-Szenarien besser geeignet als npm install
- name: Code-Linting ausführen (ESLint)
run: npm run lint
- name: Unit-Tests ausführen
run: npm test -- --coverage # Außerdem einen Test-Coverage-Bericht generieren
- name: Coverage-Bericht hochladen
uses: actions/upload-artifact@v4
if: always() # Bericht unabhängig davon hochladen, ob der Test bestanden wird (um die Fehlerursachen leicht einsehen zu können)
with:
name: coverage-report
path: ./coverage
Beispiel 2: Python-Projekt-CI
Beispiel
name: Python CI
auf:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Python-Umgebung konfigurieren
uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip' # pip-Abhängigkeiten zwischenspeichern
- name: Abhängigkeiten installieren
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install flake8 pytest # Code-Linting- und Testwerkzeuge installieren
- name: Codeformatprüfung ausführen (flake8)
run: |
# Auf Syntaxfehler und undefinierte Variablen prüfen (E9, F63, F7, F82-Serie) und bei gefundenem Problem direkt mit einem Fehler beenden
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# Codestil prüfen (max. Zeilenlänge 120), nur die Anzahl der Probleme zählen, nicht mit Fehler beenden.
flake8 . --count --max-line-length=120 --statistics
- name: Tests ausführen
run: pytest tests/ -v # -v gibt detaillierte Testergebnisse aus
Beispiel 3: Docker-Image(s) erstellen und pushen
Beispiel
name: Docker-Image erstellen und pushen
auf:
push:
branches: [main]
tags:
- 'v*' # Auslösen beim Pushen von Tags, die mit v beginnen, wie v1.0.0
jobs:
docker:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Offizielle Docker-Metadata-Action verwenden, um Image-Tags automatisch zu generieren.
# Z. B. beim Pushen von Tag v1.2.3 automatisch mehrere Tags wie 1.2.3, 1.2, 1, latest generieren
- name: Docker-Metadaten extrahieren (Image-Tags usw.)
id: meta # Eine ID für diesen Schritt festlegen, damit nachfolgende Schritte auf dessen Ausgabe verweisen können.
uses: docker/metadata-action@v5
with:
images: your-dockerhub-username/your-image-name
- name: Bei Docker Hub anmelden
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} # Aus Sicherheitsgründen ein Zugriffstoken anstelle eines Passworts verwenden
- name: Image erstellen und pushen
uses: docker/build-push-action@v5
with:
context: . # Verzeichnis, in dem sich das Dockerfile befindet (aktuelles Verzeichnis)
push: true # true: Nach Abschluss des Builds in die Registry pushen
tags: ${{ steps.meta.outputs.tags }} # Verweis auf die vom meta-Schritt generierte Tag-Liste
labels: ${{ steps.meta.outputs.labels }} # Verweis auf die vom meta-Schritt generierten Tag-Informationen
Beispiel 4: Automatisches Deployment auf einen Server nach dem Build
Beispiel
name: Build und Deployment
auf:
push:
branches: [main] # Deployment nur bei Push auf den main-Branch ausgelöst
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Abhängigkeiten installieren und Build erstellen
run: |
npm ci
npm run build # Build-Artefakte werden in das ./dist-Verzeichnis ausgegeben
- name: Deployment auf Server via SSH
uses: appleboy/[email protected] # SSH-Action von Drittanbietern, SSH muss nicht manuell konfiguriert werden
with:
host: ${{ secrets.SERVER_HOST }} # Server-IP oder Domain
username: ${{ secrets.SERVER_USER }} # SSH-Login-Benutzername
key: ${{ secrets.SSH_PRIVATE_KEY }} # Inhalt des privaten SSH-Schlüssels (entspricht dem öffentlichen Schlüssel auf dem Server)
port: 22 # SSH-Port, Standard 22
script: |
# Die folgenden Befehle werden auf dem Remote-Server ausgeführt
cd /var/www/my-app
git pull origin main
npm ci --production
pm2 restart my-app # Node.js-Anwendung mit pm2 neu starten
echo "Bereitstellung abgeschlossen: $(date)"
Beispiel 5: Geplante Aufgabe (Datenbank automatisch sichern)
Beispiel
name: Geplante Datenbanksicherung
auf:
schedule:
- cron: '0 2 * * *' # Täglich um 02:00 UTC ausführen (10:00 Pekinger Zeit)
workflow_dispatch: # Unterstützt außerdem die manuelle Auslösung für temporäre Backups
jobs:
backup:
runs-on: ubuntu-latest
steps:
- name: Backup-Skript per SSH ausführen
uses: appleboy/[email protected]
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="/backup/db_$TIMESTAMP.sql"
# Datenbank-Backup durchführen
mysqldump -u root -p${{ secrets.DB_PASSWORD }} my_database > $BACKUP_FILE
# Backup-Dateien komprimieren
gzip $BACKUP_FILE
# Backup-Dateien löschen, die älter als 30 Tage sind, um zu verhindern, dass die Festplatte voll läuft
find /backup -name "*.sql.gz" -mtime +30 -delete
echo "Backup abgeschlossen: ${BACKUP_FILE}.gz"
Debug-Tipps
1. Debug-Logs aktivieren
Wenn ein Workflow-Lauf fehlschlägt, aber die Log-Informationen nicht ausreichen, können Sie den detaillierten Debug-Modus aktivieren. Vorgehensweise: Gehen Sie zum RepositoryEinstellungen → Secrets und Variablen → Actions, fügen Sie die folgenden zwei Secrets hinzu (setzen Sie beide Werte auftrue):
ACTIONS_RUNNER_DEBUGAusführliche Runner-Logs aktivierenACTIONS_STEP_DEBUG: Detailliertes Debug-Logging für jeden Step aktivieren.
2. Ausgeben von Kontextinformationen zur Unterstützung bei der Fehlerbehebung
Beispiel
steps:
- name: Alle Kontextinformationen ausgeben (zum Debuggen; bei der Fehlersuche hinzufügen, nach Behebung entfernen)
run: |
echo "=== github context ==="
echo '${{ toJson(github) }}' # toJson() wird das Objekt in einen formatierten JSON-String umwandeln.
echo "=== env context ==="
echo '${{ toJson(env) }}'
echo "=== job context ==="
echo '${{ toJson(job) }}'
3. Lokales Testen von Workflows (mit act)
Das Testen des Workflows nur durch jedes Mal Code pushen ist sehr ineffizient.actist ein Open-Source-Tool, das GitHub Actions lokal simulieren kann, was die Debugging-Effizienz erheblich verbessert:
# 安装 act(需要本地已安装 Docker) # macOS brew install act # Linux curl https://raw.githubusercontent.com/nektos/act/master/install.sh | sudo bash # 在仓库根目录运行所有 Workflow act # 只运行指定事件触发的 Workflow act push # 只运行指定的 Job act -j build
Beim Ausführen lokaler Tests,
actEs verwendet Docker-Container, um die GitHub-Laufzeitumgebung zu simulieren, aber einige Actions (wie z. B.actions/cache) können sich bei lokaler Simulation anders verhalten als in der echten Umgebung. Die endgültigen Ergebnisse richten sich danach, was tatsächlich auf GitHub ausgeführt wird.
Häufige Probleme und Hinweise
1. Berechtigungsproblem (Permission denied)
Wenn der Workflow Code in das Repository pushen oder Issues bearbeiten muss, müssen Sie die Berechtigungen explizit in der Konfigurationsdatei deklarieren:
Beispiel
permissions:
contents: write # Ermöglicht Lese-/Schreibzugriff auf Repository-Inhalte (Code, Dateien)
issues: write # Erlaubt das Erstellen und Ändern von Issues
pull-requests: write # Erlaubt Operationen an Pull Requests
# Prinzip der geringsten Berechtigung: nur die tatsächlich benötigten Berechtigungen gewähren, der Rest standardmäßig auf read oder none
2. Vermeidung von Workflow-Schleifen-Auslösern
Wenn der Workflow automatisch Code in das Repository pusht, kann er ein neues push-Ereignis auslösen, was zu einer Endlosschleife führt. Lösung: In der Commit-Nachricht des automatischen Commits fügen Sie[skip ci]Schlüsselwort hinzu, und GitHub überspringt den Workflow-Trigger für diesen Commit:
git commit -m "自动格式化代码 [skip ci]"
3. Escaping von YAML-Sonderzeichen
InrunIm Shell-Befehl des Feldes verwenden Sie${{ }}Ausdruck, wenn der Ausdruck einen Doppelpunkt (:) und andere YAML-Sonderzeichen, müssen Sie den gesamten Wert in Anführungszeichen setzen oder ihn stattdessen zuerst einer Umgebungsvariablen zuweisen und dann verwenden:
Beispiel
steps:
# Nicht empfohlen: Das direkte Einbetten komplexer Befehle in ${{ }}-Ausdrücke kann zu YAML-Parsingfehlern führen.
- run: echo ${{ github.event.pull_request.title }}
# Empfohlen: Weisen Sie den Wert zuerst einer Umgebungsvariablen zu und verwenden Sie dann die Umgebungsvariable in der Shell
- name: PR-Titel ausgeben
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: echo "PR-Titel: $PR_TITLE"
Für eine vollständigere Dokumentation lesen Sie bitte die offizielle Dokumentation:https://docs.github.com/zh/actions
Weitere Erweiterungen