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

# .github/workflows/hello.yml

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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

# Ebene 1: Workflow-Ebene (für alle Jobs und Steps zugänglich)
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

span style="color: #0053A6;">
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

# Erweiterte Verwendung: exclude verwenden, um bestimmte unerwünschte Kombinationen auszuschließen, und include verwenden, um spezielle Konfigurationen anzuhängen
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

# .github/workflows/ci.yml
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

# .github/workflows/python-ci.yml
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

# .github/workflows/docker.yml
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

# .github/workflows/deploy.yml
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

# .github/workflows/backup.yml
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 aktivieren
  • ACTIONS_STEP_DEBUG: Detailliertes Debug-Logging für jeden Step aktivieren.

2. Ausgeben von Kontextinformationen zur Unterstützung bei der Fehlerbehebung

Beispiel

span style="color: #0053A6;">
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

# Berechtigungen auf oberster Workflow-Ebene oder auf Job-Ebene festlegen
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

span style="color: #0053A6;">
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