In dieser Dokumentation wird der folgende CI/CD-Prozess für ein Java-Maven-Projekt als Beispiel verwendet: CI/CD-Pipeline Diagramm

1. Grundlegende Funktionsweise von GitHub Actions

github actions easy explanation

GitHub Actions ist ein CI/CD-Tool (Continuous Integration / Continuous Deployment), das es ermöglicht, Workflows zur Automatisierung von Aufgaben zu erstellen und auszuführen.

1.1. Ablauf

  1. Event: Ein Workflow startet, wenn ein bestimmtes Ereignis eintritt, z.B. ein Push in ein Repository, das Erstellen eines Pull Requests oder ein manuell ausgelöster Workflow. Dieses Ereignis fungiert als Auslöser für die Aktionen, die folgen.

  2. Runner: Ein "Runner" ist die Umgebung, in der die Aktionen ausgeführt werden. GitHub Actions stellt Runner in der Cloud zur Verfügung, aber es ist auch möglich, eigene Runner zu verwenden. Jeder Runner führt eine Job-Gruppe aus, die aufeinanderfolgende Schritte enthalten kann.

  3. Jobs:

    • Ein Workflow kann aus mehreren Jobs bestehen, die entweder parallel oder nacheinander ausgeführt werden können.

  4. Steps:

    • Jeder Job besteht aus mehreren Steps.

    • Ein Step kann eine Aktion sein (vorgefertigte Funktionen, z.B. Actions aus dem Marketplace) oder ein Skript, das spezifische Befehle ausführt.

2. Grundlegender Skript Aufbau

Bei GitHub Actions ist es wichtig auf richtige Einrückungen zu achten!
example.yaml
name: example GitHub action

on: push (1)

jobs: (2)
  example-job-1:
    name: job 1
    runs-on: ubuntu-24.04 (3)
    steps: (4)
      - name: step 1
        run: echo "Hello, World!" #bash code 1

      - uses: actions/checkout@v4 (5)

      - name: step 3
        run: | (6)
          cp ./somedir/ .
          dir
1 Das Event, oder die Events die diesen Workflow triggern.
2 Ein Skript besteht aus einem oder mehreren "Jobs", die Parallel, auf eigenen Umgebungen laufen.
3 Dieser "Job" läuft auf einer Umgebung mit dem Betriebssystem "ubuntu 24.04". Weiter Umgebungen sind:
4 Steps sind Actions/Code-Snippets die von oben nach unten, nacheinander ausgeführt werden.
5 uses:
  • Anstatt eine Funktion manuell zu schreiben, ermöglicht uses die Integration von bestehenden GitHub Actions (entweder aus dem GitHub Marketplace oder einem öffentlichen Repository) direkt im Workflow.

  • Das Format von uses ist owner/repo@version.

  • Weitere Informationen und Beispiele befinden sich im Kapitel: Uses

6 Hier wird run: | verwendet, wodurch jede Zeile als separater Befehl in der Shell-Konsole behandelt wird.
  • Weitere Informationen befinden sich im Kapitel: Run

Die Workflow-Dateien im Format .yaml müssen im Verzeichnis .github/workflows des Repositories abgelegt sein.

3. Events

Eine GitHub Action kann durch unterschiedliche Events ausgelöst werden:

example.yaml
name: example GitHub action

on:
  push: (1)
    paths: (2)
      - 'vehicle/**'
      - '.GitHub/workflows/build.yaml'
    branches: (3)
      - main
  pull_request: (4)
    branches:
      - main
  workflow_run: (5)
    workflows: [ "build vehicle and publish Docker image to ghcr.io" ] (6)
    branches:
      - main
    types: (7)
      - completed
  workflow_dispatch: (8)

jobs:
  ...
1 Löst den Workflow bei einem git push-Ereignis aus.
2 Spezifiziert, dass es nur ausgeführt wird, wenn sich etwas in den angegebenen Pfaden verändert hat.
3 Spezifiziert, dass es nur ausgeführt wird, wenn das Event (in diesem Fall "push") auf dem Main-branch passiert.
4 Löst den Workflow aus, wenn ein Pull-Request Ereignis auftritt.
5 Löst den Workflow aus, wenn ein Workflow-Ereignis, bei einem angegebenen Workflow, auftritt.
6 Der Name des Workflows, dessen Ereignisse überwacht werden. Dieser Name entspricht dem Wert, der im oberen Abschnitt des Skripts mit dem Schlüssel name: festgelegt wurde.
7 Es wird ausschließlich auf das Ereignis completed gewartet, d.h. der Workflow wird nur fortgesetzt, wenn der andere Workflow abgeschlossen ist.
8 Dies ermöglicht das manuelle Auslösen eines GitHub Workflows über die GitHub-Benutzeroberfläche.
Screenshot der GitHub-Benutzeroberfläche zum manuellen Starten des Workflows
github screenshot workflow dispatch

4. Jobs

example.yaml
...

jobs:
  job-1:
    name: job 1
    runs-on: ubuntu-24.04
    permissions: (1)
      packages: write
    env: (2)
      JAVA_VERSION: '21'
      JAVA_DISTRIBUTION: 'temurin'

    steps:
      ...
  job-2: (3)
    name: job 2
    runs-on: ubuntu-24.04
    env:
      K8S_DEPLOYMENT_NAME: 'appsrv'

    if: ${{ GitHub.event_name == 'workflow_dispatch' || GitHub.event.workflow_run.conclusion == 'success' }} (4)
    steps:
      ...
1 Mehr dazu im Kapitel: Permissions
2 Mehr dazu im Kapitel: Umgebungsvariablen
3 Eine GitHub Action kann mehrere Jobs enthalten, die parallel ausgeführt werden.
4 Wenn eine GitHub Action durch das workflow_run Event gestartet wird, kann man mithilfe dieser If-Bedingung festlegen, unter welchen Bedingungen er starten soll.
  • Hierbei startet es, wenn eine von zwei Bedingungen erfüllt ist:

    • Entweder wird er durch workflow_dispatch automatisch gestartet.

    • Oder der vorherige Workflow wurde fehlerfrei abgeschlossen.

4.1. GitHub Token

Das GitHub_TOKEN ist ein temporäres Authentifizierungstoken, das in GitHub Actions verwendet wird, um auf das Repository und GitHub-APIs zuzugreifen.Es ermöglicht das Durchführen von Aktionen wie Code-Pushes oder Release-Verwaltung, welche Berechtigungen benötigen.Die Berechtigungen des Tokens müssen angepasst werden, um nur den minimal erforderlichen Zugriff zu gewähren.

4.2. Permissions

Sie können die Berechtigungen anpassen, die dem GitHub_TOKEN standardmäßig zugewiesen sind, um nur den minimal erforderlichen Zugriff zu gewähren, indem Sie Zugriffe hinzufügen oder entfernen.

4.2.1. Es gibt mehrere Berechtigungsstufen für jede Ressource:

  • read: Zugriff nur zum Lesen.Der Workflow kann Daten aus der Ressource abrufen, aber keine Änderungen vornehmen.

  • write: Erlaubt dem Workflow, Änderungen an der Ressource vorzunehmen (z. B. Pushen von Paketen oder Ändern von Repositories).

  • none: Entzieht dem Workflow die Berechtigung für die Ressource.

4.2.2. Beispiele

  • actions

    • Ermöglicht einer Action, die den GITHUB_TOKEN verwendet, mit GitHub Actions zu arbeiten. Zum Beispiel erlaubt die actions:write einer Action, einen Workflow-Run abzubrechen.

  • contents

    • Ermöglicht einer Action, die den GITHUB_TOKEN verwendet, mit dem Inhalt des Repositories zu arbeiten. Zum Beispiel erlaubt contents: read einer Action, die Commits aufzulisten, und contents: write ermöglicht es der Action, einen Release zu erstellen.

  • packages

    • Ermöglicht einer Action, die den GITHUB_TOKEN verwendet, mit GitHub Packages zu arbeiten. Zum Beispiel erlaubt packages: write einer Action, Pakete auf GitHub Packages hochzuladen und zu veröffentlichen.

      • GitHub Packages ist eine Plattform zum zentralen Hosting und Verwalten von Softwarepaketen und Containern.

      • GitHub Packages ermöglicht, Pakete privat oder öffentlich zu hosten und sie als Abhängigkeiten in Projekten zu nutzen.

      • Sie unterstützt DevOps-Workflows und gängige Paketmanager wie npm, Maven, Docker und NuGet.

      • GitHub Packages - GitHub Docs

  • pages

    • Ermöglicht einer Action, die den GITHUB_TOKEN verwendet, mit GitHub Pages zu arbeiten. Zum Beispiel erlaubt pages: write einer Action, einen Build für GitHub Pages anzufordern.

      • GitHub Pages sind öffentliche Webseiten, die direkt über GitHub gehostet und veröffentlicht werden.

      • GitHub Pages eignet sich zur Präsentation von Open-Source-Projekten, zum Hosting eines Blogs oder anderem.

      • GitHub Pages - GitHub Docs

Alle Berechtigungen sind hier zu finden: GitHub Token Berechtigungen - GitHub Docs

5. Steps

example.yaml
...
- uses: actions/checkout@v4

- uses: actions/setup-java@v4
  with:
    java-version: ${{ env.JAVA_VERSION }}
    distribution: ${{ env.JAVA_DISTRIBUTION }}

- name: Build vehicle project with maven
  working-directory: ${{ env.PROJECT_LOCATION }}
  run: | # multi line string operator
    mvn clean package
    dir
...

Innerhalb eines Jobs gibt es Steps, die in der Reihenfolge ausgeführt werden, in der sie im YAML definiert sind. Ein Step kann eine Action (uses) oder ein Befehl (run) sein.

5.1. Erklärung der häufigsten Schritte:

5.1.1. uses

  • Anstatt eine Funktion manuell zu schreiben, ermöglicht uses die Integration von bestehenden GitHub Actions (entweder aus dem GitHub Marketplace oder einem öffentlichen Repository) direkt im Workflow.

  • Das Format von uses ist owner/repo@version.

Beispiel
- uses: actions/checkout@v4
  • Checkout:

    • Diese Aktion führt ein Checkout Ihres Repositories im Verzeichnis $GITHUB_WORKSPACE durch, sodass Ihr Workflow darauf zugreifen kann.

    • Standardmäßig wird nur ein einzelner Commit abgerufen, der dem Ref/SHA entspricht, der den Workflow ausgelöst hat. Um die gesamte Historie aller Branches und Tags abzurufen, setzen Sie fetch-depth: 0.

      • In GitHub Actions repräsentiert github.ref den Git-Referenznamen (z. B. einen Branch oder Tag), der das aktuelle Ereignis ausgelöst hat. Zum Beispiel kann dies ein Branch wie refs/heads/main oder ein Tag wie refs/tags/v1.0 sein.

      • github.sha ist der Hash-Wert des Commits, der das Ereignis ausgelöst hat. Es handelt sich dabei um eine eindeutige Kennung des spezifischen Commits im Repository, der den Workflow gestartet hat.

5.1.2. run (Befehlsausführung)

  • Dies ermöglicht es, beliebige Shell-Befehle auszuführen, z.B. zum Installieren von Abhängigkeiten oder zum Erstellen des Projekts.

- run: |
    mvn clean package
    dir
Hier wird der Maven-Befehl clean package ausgeführt, um das Projekt zu bauen und schließlich wird der Inhalt des aktuellen Verzeichnisses aufgelistet.
  • run: | wird verwendet, damit jede Zeile als separater Befehl in der Shell-Konsole behandelt wird.

  • Unterschiede:

    • run: …​ führt einen einzelnen Befehl aus.

    • run: | …​ wird verwendet, um mehrere Befehle als zusammenhängendes Skript auszuführen, wobei jede Zeile als separater Befehl behandelt wird.

5.1.3. with (Parameter)

  • Viele GitHub Actions akzeptieren Parameter, die mit with angegeben werden. Diese Parameter steuern, wie die Action ausgeführt wird.

- uses: actions/setup-java@v4
  with:
    java-version: 17
  • Dieser Schritt richtet eine Java-Umgebung mit der Java-Version 17 ein.

5.1.4. if (Bedingte Ausführung)

  • Du kannst Bedingungen definieren, um festzulegen, ob ein Schritt ausgeführt wird, basierend auf dem Status eines vorherigen Schritts oder Ereignissen im Workflow.

- name: Run tests
  if: success()
  run: ./run-tests.sh

6. Umgebungsvariablen

GitHub Actions stellt eine Reihe von vorgegebenen Umgebungsvariablen zur Verfügung, die wichtige Informationen über das Repository, den Workflow und den Benutzer liefern, der den Workflow ausgelöst hat. Diese Variablen können innerhalb eines Workflows verwendet werden, um dynamische Daten zu verwalten und in verschiedenen Schritten des Workflows zu nutzen.

  • Umgebungsvariablen werden von Betriebssystemen oder Programmen verwendet, um Konfigurationen, Pfade oder andere Einstellungen bereitzustellen, die für die Ausführung von Programmen erforderlich sind.

  • Umgebungsvariablen können systemweit oder benutzerspezifisch definiert werden und bieten eine flexible Möglichkeit, Werte wie Datenbankverbindungen, API-Schlüssel oder Verzeichnispfade zu verwalten.

6.1. Verwendung

Die Verwendung von Umgebungsvariablen erfolgt durch Anwendung des folgenden Formats: ${{ <quelle>.<variablenname> }}

Beispiel
- name: Echo env
  run: echo ${{ env.JAVA_VERSION }}

6.2. Wichtige vorgegebene GitHub-Umgebungsvariablen

  • github.repository Diese Variable enthält den Namen des GitHub-Repositories, auf dem der Workflow ausgeführt wird, im Format owner/repository.

  • github.sha Diese Variable enthält den vollständigen Commit-Hash des aktuellen Runs.

  • github.event_name Diese Variable zeigt den Namen des Ereignisses, das den Workflow ausgelöst hat, wie z.B. push, pull_request oder workflow_dispatch.

  • github.actor Diese Variable enthält den Benutzernamen des GitHub-Benutzers, der den Workflow ausgelöst hat.

  • github.workflow Diese Variable enthält den Namen des aktuellen Workflows, der ausgeführt wird.

  • github.run_id Diese Variable enthält die eindeutige ID des aktuellen Workflow-Runs.

  • github.ref Diese Variable zeigt den Git-Referenznamen, wie einen Branch oder Tag, der den Workflow ausgelöst hat.

Screenshot mit Beispielen für mögliche Werte der Variablen
github screenshot logged environment variables

Diese Umgebungsvariablen bieten eine einfache Möglichkeit, Kontextinformationen über den Workflow und das Repository zu erhalten, die dann in verschiedenen Workflow-Schritten weiterverwendet werden können. Sie sind besonders nützlich für Automatisierungsaufgaben wie Deployments, Tests und Benachrichtigungen.

Weitere Umgebungsvariablen: Github Context - GitHub Docs

7. GitHub Secrets

GitHub Secrets sind sichere Umgebungsvariablen, die in GitHub Actions verwendet werden, um vertrauliche Daten wie API-Schlüssel, Tokens oder Passwörter zu speichern. Diese Secrets werden verschlüsselt gespeichert und können nur während der Ausführung von GitHub Actions verwendet werden, um sicherzustellen, dass vertrauliche Informationen nicht im Klartext im Repository oder in Logs erscheinen.

Beispiel
- name: Log in to GitHub Container Registry
  run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin

7.1. Beispiele für GitHub Secrets

Einige häufige Beispiele für Secrets, die in GitHub Actions verwendet werden, sind:

  • API-Schlüssel für externe Dienste

  • Zugangstokens für GitHub oder andere Systeme

  • Datenbankpasswörter

  • SSH-Schlüssel für den Zugriff auf Server

  • secrets.GITHUB_TOKEN: GitHub Token Kapitel

7.2. Einrichten von GitHub Secrets

Um ein Secret in GitHub zu erstellen, gehe zu den Repository-Einstellungen und wähle die Option "Secrets". Hier kannst du neue Secrets hinzufügen, die dann in deinen Workflows verwendet werden können.

8. Concurrency

BeispielCode
name: my concurrency

on:
  push:
    branches:
      - main

concurrency:
  group: production (1)
  cancel-in-progress: true (2)

jobs:
  my-job:
    name: my job
    runs-on: ubuntu-24.04
    steps:
      ...
1 Gruppe die man mit irgendeinem beliebigen String füllen kann.
2 Hiermit wird die derzeit laufende GitHub Action abgebrochen, bevor die nächste gestartet wird. Es können jedoch Probleme auftreten, wenn der Prozess während der Ausführung abgebrochen wird.

8.1. Beispiel

BeispielCode
name: my concurrency

on:
  push:
    branches:
      - main

concurrency:
  group: production

jobs:
  my-job:
    name: my job
    runs-on: ubuntu-24.04
    steps:
      ...

In GitHub Actions, die concurrency-Einstellung ermöglicht es dir, die gleichzeitige Ausführung von Workflows zu steuern, um zu verhindern, dass mehrere Instanzen eines Workflows gleichzeitig laufen, was in einigen Fällen zu Problemen führen könnte. Sie wird mit einer Gruppenzuordnung kombiniert, die hilft, verschiedene Workflows zu organisieren und Konflikte zu vermeiden.

VP7DJiCm383lVWfh757t09k4rbO8E23nSqGxUAbfewLEbJY8lJrX6stPOOT4rcVhYnrlebBGr3k8Uoi31UhH 7xmmgBlUd2CWOsIj8u1gCqKFvx9oXR4QqxQjbEu yeyOectMELJGqV3m8AaA4p17L0xXaWzezfyaJHuV1WonoD iFgOTb0QjLuYHXFia9N SoenNamAWSKSe0q 3KlWB1AlKsjlIOG3bbky6SXn6vXbxQpmQWgNE  QjVAtdk5ib1K 2Ru4dnCnNaYhNwcL SaNk3dP6eeTdtqP hVL98OTDnUg af e 5AXw 94mESDb4qnUAu0ImNC4R57wn6M4smNi2iD1HtqyzDrNDUZRoUypm9m8QbIRtx0G00