Workflows ohne Actions sind wie Programmiersprachen ohne Bibliotheken – technisch vollständig, praktisch ineffizient. Jeder Workflow könnte reine Shell-Scripts verwenden, jeder Task ließe sich von Grund auf neu implementieren. Aber warum sollten wir das tun? Das Action-Ökosystem von GitHub ist eine der zentralen Stärken von GitHub Actions: ein Marktplatz mit tausenden vorgefertigten Bausteinen, die von einfachem Code-Checkout bis zu komplexen Cloud-Deployments reichen.
Doch dieses Ökosystem ist kein unkritischer Self-Service-Laden. Actions sind ausführbarer Code, der in unseren Workflows läuft – oft mit Zugriff auf Secrets, mit Schreibrechten im Repository, mit der Möglichkeit, unsere Build-Artefakte zu manipulieren. Die Entscheidung, eine Action zu nutzen, ist immer ein Abwägen: Zeitersparnis und Wartbarkeit gegen Kontrolle und Sicherheitsrisiko. Eine gut gewählte Action beschleunigt die Entwicklung. Eine schlecht gewählte Action wird zur Liability.
Dieses Kapitel navigiert durch das Action-Ökosystem: Welche Arten von Actions existieren und wann ist welche die richtige Wahl? Wie finden wir vertrauenswürdige Actions? Wie versionieren wir sie sicher? Und wann sollten wir den Aufwand investieren, eine eigene Action zu schreiben?
GitHub Actions kennt drei fundamentale Typen, die sich in Ausführungsumgebung, Portabilität und Komplexität unterscheiden. Diese Unterscheidung ist nicht nur technisch relevant – sie bestimmt, in welchen Szenarien eine Action einsetzbar ist und welche Wartungslast sie mit sich bringt.
Eine Docker Container Action packt ihren Code zusammen mit der kompletten Laufzeitumgebung in ein Container-Image. Der Workflow startet den Container, übergibt Inputs als Umgebungsvariablen, führt das Entrypoint-Script aus und liest die Outputs. Die Isolation ist komplett – die Action bringt ihr eigenes Betriebssystem, ihre eigenen Tools, ihre eigenen Library-Versionen mit.
# action.yml einer Docker Container Action
name: 'Python Linter'
description: 'Runs pylint with specific Python version'
inputs:
target-version:
description: 'Python version to use'
required: true
default: '3.11'
runs:
using: 'docker'
image: 'Dockerfile'
args:
- ${{ inputs.target-version }}Das Dockerfile definiert die Umgebung:
FROM python:3.11-slim
RUN pip install pylint==2.17.0
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]Der Vorteil liegt auf der Hand: Absolute Reproduzierbarkeit. Egal auf welchem Runner die Action läuft – sie bringt ihre Umgebung mit. Ein Python-Linter kann exakt Python 3.11 verlangen, ein C++-Compiler kann GCC 12 mit spezifischen Flags voraussetzen, ein Legacy-Tool kann auf Debian 9 laufen. Die Action definiert ihre Welt selbst.
Der Preis ist Performance. Bei jeder Ausführung muss GitHub den Container starten – Image pullen (oder aus Cache laden), Container hochfahren, Volume-Mounts einrichten. Das dauert Sekunden bis Minuten, abhängig von Image-Größe und Cache-Status. Für kurze Tasks ist der Overhead proportional hoch. Eine Action, die drei Sekunden Arbeit in einem 30-Sekunden-Container-Start verpackt, hat ein ungünstiges Verhältnis.
Die zweite Einschränkung ist Plattform-Kompatibilität: Docker Container Actions laufen nur auf Linux-Runnern. Windows- und macOS-Runner unterstützen sie nicht. Wer cross-platform CI/CD betreibt, muss entweder auf Docker Actions verzichten oder getrennte Workflows für unterschiedliche Plattformen bauen.
Einsatzgebiet: Actions mit komplexen Abhängigkeiten, die nicht einfach auf dem Runner installierbar sind. Build-Tools mit spezifischen Compiler-Versionen, Datenbank-Migrationstools, die bestimmte Client-Libraries brauchen, oder Legacy-Software, die nur in kontrollierten Umgebungen läuft.
JavaScript Actions sind Node.js-Scripts, die direkt auf dem Runner ausgeführt werden. Sie nutzen die bereits installierte Node.js-Runtime (aktuell Node 20 auf GitHub-hosted Runners) und können auf das Dateisystem, die GitHub API und externe Services zugreifen. Keine Container, keine Virtualisierung, keine Startup-Latenz.
# action.yml einer JavaScript Action
name: 'Issue Labeler'
description: 'Automatically labels issues based on content'
inputs:
github-token:
description: 'GitHub token for API access'
required: true
label-mapping:
description: 'JSON mapping of keywords to labels'
required: true
runs:
using: 'node20'
main: 'dist/index.js'Die Action selbst ist TypeScript oder JavaScript, kompiliert und
gebundelt in eine einzelne index.js:
const core = require('@actions/core');
const github = require('@actions/github');
async function run() {
try {
const token = core.getInput('github-token');
const mapping = JSON.parse(core.getInput('label-mapping'));
const octokit = github.getOctokit(token);
// Action-Logik hier
// ...
core.setOutput('labels-added', labelsAdded);
} catch (error) {
core.setFailed(error.message);
}
}
run();Das @actions/core und @actions/github
Package sind Teil des GitHub Actions Toolkit – offiziell unterstützte
Libraries für Input/Output-Handling, Logging, API-Zugriff und
Fehlerbehandlung. Sie abstrahieren die Low-Level-Mechanismen
(Umgebungsvariablen, Ausgabe-Files, HTTP-Requests) in eine saubere
API.
JavaScript Actions starten in Millisekunden. Der Runner hat Node.js bereits geladen, das Script wird direkt ausgeführt. Für häufig aufgerufene Actions – Code-Checkout, Artifact-Upload, Cache-Restore – ist das der entscheidende Unterschied zu Container-Actions.
Die Cross-Platform-Unterstützung ist natürlich gegeben, solange das
Script reine Node.js-APIs nutzt. Syscalls, Binaries oder
plattformspezifische Tools brechen die Portabilität. Eine Action, die
grep oder sed aufruft, läuft nicht auf
Windows. Eine Action, die PowerShell-Cmdlets nutzt, nicht auf Linux. Der
Lowest Common Denominator ist Node.js selbst – File I/O, HTTP,
String-Processing, JSON-Parsing. Alles andere muss bedingt implementiert
werden.
Einsatzgebiet: API-Interaktionen (GitHub, externe Services), File-Processing, Workflow-Logik, Cache- und Artifact-Handling. Alles, wo Geschwindigkeit zählt und die Abhängigkeiten sich in npm-Packages ausdrücken lassen.
Composite Actions sind der dritte Typ – eigentlich kein Code, sondern eine Liste von Steps. Sie bündeln mehrere Workflow-Steps in eine wiederverwendbare Einheit. Eine Composite Action ist selbst ein Mini-Workflow.
# action.yml einer Composite Action
name: 'Setup Node.js Project'
description: 'Install dependencies and cache them'
inputs:
node-version:
description: 'Node.js version'
required: true
default: '20'
working-directory:
description: 'Project directory'
required: false
default: '.'
outputs:
cache-hit:
description: 'Whether cache was hit'
value: ${{ steps.cache-deps.outputs.cache-hit }}
runs:
using: 'composite'
steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
- name: Cache dependencies
id: cache-deps
uses: actions/cache@v3
with:
path: ${{ inputs.working-directory }}/node_modules
key: npm-${{ hashFiles(format('{0}/package-lock.json', inputs.working-directory)) }}
- name: Install dependencies
if: steps.cache-deps.outputs.cache-hit != 'true'
shell: bash
working-directory: ${{ inputs.working-directory }}
run: npm ciDiese Action kombiniert drei Steps: Node.js-Setup,
Dependency-Caching, und npm ci. Jeder Workflow, der
Node.js-Projekte baut, kann sie nutzen statt die drei Steps zu
wiederholen. Das ist DRY-Prinzip auf Workflow-Ebene.
Composite Actions können andere Actions aufrufen – sowohl Marketplace-Actions als auch weitere Composite Actions. Sie können Shell-Commands ausführen, Outputs definieren, Conditions nutzen. Was sie nicht können: Jobs definieren. Eine Composite Action ist immer ein Fragment innerhalb eines Jobs, keine Job-Orchestrierung.
Ein subtiler Punkt: Composite Actions laufen nicht in Isolation. Die Steps werden direkt im Kontext des aufrufenden Jobs ausgeführt. Umgebungsvariablen, die in der Composite Action gesetzt werden, bleiben nach der Action bestehen. Dateien, die sie erstellt, liegen im Workspace. Das ist anders als bei Docker/JavaScript Actions, wo Inputs und Outputs explizit gekapselt sind.
Einsatzgebiet: Wiederkehrende Step-Sequenzen, die in mehreren Workflows gebraucht werden. Setup-Routinen (Language Runtime + Dependencies), Deployment-Workflows (Build + Test + Deploy), Notification-Patterns (Slack/Email bei Success/Failure).
| Action-Typ | Startup-Zeit | Plattformen | Isolation | Komplexität | Typischer Einsatz |
|---|---|---|---|---|---|
| Docker Container | Hoch (10–60s) | Nur Linux | Vollständig | Hoch | Build-Tools, Legacy-Software |
| JavaScript | Niedrig (<1s) | Cross-Platform | Prozess-Ebene | Mittel | API-Calls, File-Ops |
| Composite | Keine | Wie Steps | Keine | Niedrig | Step-Sequenzen |
Der GitHub Marketplace ist der primäre Katalog für Actions – über 20.000 Actions von Community, Partnern und GitHub selbst. Die Herausforderung ist nicht, Actions zu finden, sondern die richtigen Actions zu finden. Popularity ist kein Qualitätsindikator, Sternezahl keine Sicherheitsgarantie.
Der Workflow-Editor in GitHub bietet eine integrierte Marketplace-Sidebar. Während wir eine Workflow-Datei bearbeiten, können wir nach Actions suchen, Kategorien durchstöbern und Actions direkt per Click einfügen. Die Editor-Integration zeigt Verwendungsbeispiele und kopiert die korrekte Syntax – inklusive aktueller Version.
Dieser Weg ist bequem für bekannte Actions, aber limitiert für Discovery. Die Suche ist Keyword-basiert, Filterung rudimentär. Für gezieltes Suchen – etwa “alle Python-Testing-Tools mit über 1000 Stars” – braucht es die volle Marketplace-Website.
Nicht jede Action mit 10k Stars ist vertrauenswürdig. Nicht jede Action mit 100 Stars ist unsicher. Die Bewertung erfordert mehrere Dimensionen:
Verified Creator Badge: Actions mit dem Badge “Verified creator” stammen von Organisationen, die GitHub als Partner verifiziert hat. Das ist kein Persilschein – auch verifizierte Creator können Bugs oder Security-Issues haben – aber es signalisiert, dass hinter der Action eine bekannte Entität steht, kein anonymer Account. Microsoft, HashiCorp, AWS, Google Cloud – die großen Cloud-Provider haben diesen Badge. Ihre Actions sind intensiv genutzt und geprüft.
Maintenance-Frequenz: Wann war der letzte Commit? Sind Issues offen ohne Antworten? Werden Security-Advisories bearbeitet? Eine Action, die seit zwei Jahren nicht mehr angefasst wurde, ist entweder perfekt (unwahrscheinlich) oder abandoned (wahrscheinlich). Aktive Maintenance zeigt sich in regelmäßigen Updates, Changelog-Pflege und Issue-Response.
Abhängigkeiten und Komplexität: Eine JavaScript
Action mit 200 npm-Dependencies ist eine größere Attack-Surface als eine
mit 5. Jede Dependency ist ein potentielles Supply-Chain-Risiko. Tools
wie npm audit oder GitHub’s Dependency Graph zeigen
Vulnerabilities. Eine Action mit bekannten CVEs in Dependencies sollte
gemieden oder geforkt und gefixt werden.
Source Code Audit: Für kritische Actions – alles mit
Secret-Zugriff, API-Calls zu externen Services, oder Schreibrechten im
Repository – lohnt sich ein Blick in den Code. Ist er verständlich?
Macht er, was er vorgibt zu machen? Sendet er Daten an unerwartete
Hosts? Ein curl https://suspicious-domain.com im
Entrypoint-Script ist ein Red Flag.
Community-Signale: GitHub Stars sind ein schwaches Signal, aber nicht bedeutungslos. Eine Action mit 50k Stars und 500 Forks ist battle-tested. Eine Action mit 20 Stars und 1 Fork ist ein Experiment. Besser als Stars sind Issues und Discussions – zeigen sie konstruktive Problembeschreibungen und Lösungen? Oder unbeantwortete Bugs und Frustration?
GitHub selbst maintained einen Satz von Core-Actions unter dem
actions/-Namespace:
actions/checkout@v4 – Repository-Code auscheckenactions/setup-node@v4 – Node.js installierenactions/cache@v3 – Dependencies cachenactions/upload-artifact@v4 – Build-Artefakte
speichernactions/download-artifact@v4 – Artefakte
herunterladenDiese Actions sind der Gold-Standard: gut dokumentiert, intensiv getestet, regelmäßig aktualisiert, mit Backward-Compatibility-Garantien. Wenn eine Aufgabe durch eine offizielle Action abdeckbar ist, gibt es wenig Grund, nach Alternativen zu suchen.
Actions werden über Git-Refs referenziert – Tags, Branches oder Commit-SHAs. Die Wahl ist nicht trivial. Sie bestimmt das Trade-off zwischen Stabilität, Sicherheit und Convenience.
# Möglichkeiten:
- uses: actions/checkout@v4 # Tag (Major Version)
- uses: actions/checkout@v4.1.2 # Tag (Exakte Version)
- uses: actions/checkout@main # Branch
- uses: actions/checkout@a1b2c3d... # Commit SHA (full length)Tags sind die häufigste Versionierungsmethode. Action-Maintainer
folgen typischerweise Semantic Versioning: v1,
v1.2, v1.2.3. Der Tag v4 ist ein
“floating tag” – er zeigt immer auf den neuesten v4.x.x-Release. Ein
Update von v4.1.0 auf v4.1.1 bewegt den v4-Tag.
Das hat Vorteile: Workflows bekommen automatisch Bugfixes und
Minor-Updates. Der Maintainer kann einen kritischen Security-Fix
releasen, den v4-Tag updaten, und alle Workflows, die
@v4 nutzen, bekommen den Fix beim nächsten Lauf.
Das hat auch Risiken: Tags sind mutable. Ein Maintainer (oder ein Angreifer mit Repo-Zugriff) kann einen Tag auf einen anderen Commit zeigen lassen. Der Workflow ändert sich nicht, aber die Action, die er ausführt, tut es. Bei vertrauenswürdigen Actions ist das akzeptabel. Bei unbekannten Third-Party-Actions ist es ein Risiko.
Best Practice: Major-Version-Tags (@v4) für etablierte,
vertrauenswürdige Actions. Exakte Tags (@v4.1.2) für
Actions, wo man Updates kontrolliert auslösen will.
Ein Commit-SHA ist unveränderlich. Der Workflow ruft exakt den Code auf, der zu diesem Zeitpunkt im Repository lag. Kein Maintainer, kein Angreifer kann das ändern, ohne eine SHA-1-Collision zu erzeugen (praktisch unmöglich).
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11Das ist die sicherste Variante für Third-Party-Actions. GitHub empfiehlt sie explizit für kritische Workflows. Der Preis ist Wartung: Updates müssen manuell gezogen werden. Ein Security-Fix in der Action erfordert, dass wir den neuen SHA in unseren Workflow einpflegen. Ohne Automatisierung wird das schnell vergessen.
Ein Kompromiss: Dependabot. Es kann Action-Updates automatisch als Pull Requests vorschlagen – selbst für SHA-gepinnte Actions. Wir reviewen den PR, prüfen das Changelog, mergen. So bleibt die Kontrolle, ohne die Übersicht zu verlieren.
Wichtig: Wenn wir SHAs nutzen, müssen wir verifizieren, dass der SHA aus dem Action-Repository stammt, nicht aus einem Fork. Ein Angreifer könnte einen Fork mit malicious Code erstellen und dessen SHA angeben. GitHub zeigt im Marketplace immer das Quell-Repository – ein Abgleich stellt sicher, dass wir die richtige Action referenzieren.
Branch-Referenzen (@main, @develop) sind
die instabilste Variante. Sie zeigen auf den aktuellen HEAD des Branches
– der sich mit jedem Push ändert. Für Production-Workflows ungeeignet.
Für Entwicklung und Testing durchaus nützlich: Wir können die neueste
Development-Version einer Action testen, bevor sie getagged ist.
# Entwicklungs-Workflow, nicht Production
- uses: user/experimental-action@mainDependabot kann nicht nur Application-Dependencies updaten, sondern
auch Actions. In der .github/dependabot.yml
konfiguriert:
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"Dependabot scannt alle Workflows, findet Action-Referenzen und erstellt PRs bei Updates. Das funktioniert sowohl für Tags als auch für SHAs. Bei SHA-Pinning ist es besonders wertvoll – ohne es wären manuelle SHA-Updates eine Sisyphus-Arbeit.
Eine Third-Party-Action hat potentiell vollen Zugriff auf den
Workflow-Kontext: Secrets, Repository-Inhalte, das
GITHUB_TOKEN. Eine kompromittierte oder malicious Action
kann Secrets exfiltrieren, Code manipulieren, oder API-Calls im Namen
des Repositories machen. Die Security-Implikationen sind real.
Angriffsvektoren für Actions:
Maintainer-Kompromittierung: Der ursprünglich vertrauenswürdige Maintainer wird gehackt, sein Account übernommen. Der Angreifer veröffentlicht eine neue Version mit Backdoor.
Dependency-Injection: Eine JavaScript Action nutzt eine npm-Dependency, die selbst kompromittiert wird. Der Angriff kommt durch die Hintertür.
Typosquatting: Ein Angreifer erstellt eine
Action mit ähnlichem Namen wie eine populäre Action.
actions/chekout statt actions/checkout. Ein
Tippfehler im Workflow ruft die malicious Action auf.
Social Engineering: Eine Action wirbt mit attraktivem Feature-Set, ist aber von Anfang an als Datenexfiltration konzipiert.
Principle of Least Privilege für GITHUB_TOKEN: Das automatische Token sollte minimale Permissions haben. GitHub erlaubt, Default-Permissions auf read-only zu setzen und pro Job zu erhöhen:
permissions:
contents: read
jobs:
build:
permissions:
contents: read
packages: write
# ...Eine Action, die nur Code bauen soll, braucht keine
write-Permissions. Eine Action, die Releases erstellen
soll, braucht sie gezielt für diesen Job.
Secrets nur wo nötig: Nicht jeder Job braucht jedes Secret. Environment-Level-Secrets sind nur verfügbar, wenn der Job explizit das Environment referenziert:
jobs:
deploy:
environment: production
steps:
- uses: third-party/deploy-action@v1
with:
api-key: ${{ secrets.PROD_API_KEY }}Ein Angreifer, der einen normalen Job kompromittiert, kommt nicht an Production-Secrets.
Action Source Code Review für kritische Pfade: Für Actions, die mit Produktionssystemen interagieren oder hochsensible Secrets nutzen, lohnt sich ein Code-Audit. Bei JavaScript Actions: Dependencies prüfen. Bei Docker Actions: Dockerfile und Entrypoint-Script analysieren. Bei Composite Actions: die genutzten Actions rekursiv prüfen.
Fork und Self-Host bei hohem Risiko: Wenn eine benötigte Action nicht vertrauenswürdig genug ist, aber die Funktionalität gebraucht wird: Forken, auditieren, in eigenes Organisations-Repository kopieren, und diese Version nutzen. Updates müssen manuell gepullt werden, aber die Kontrolle ist vollständig.
Workflow-Dateien sind Code. Sie sollten denselben Review-Prozess
durchlaufen. GitHub’s CODEOWNERS-Feature erlaubt, dass Changes in
.github/workflows/ einen designated Reviewer erfordern:
# .github/CODEOWNERS
.github/workflows/* @security-team @platform-team
Niemand kann mehr unkontrolliert Actions ändern oder neue hinzufügen. Jede Action-Änderung wird reviewt – und damit potentiell malicious Actions abgefangen.
Die Frage stellt sich bei jedem nicht-trivialen Task: Gibt es eine Action dafür, oder bauen wir unsere eigene?
Standard-Tasks: Code-Checkout, Language-Setup,
Artifact-Handling, Cache-Management – das sind gelöste Probleme. Die
offiziellen GitHub Actions (actions/*) sind optimiert,
getestet, und über Millionen von Workflows bewährt. Selbst die simpelste
eigene Implementation wird nicht besser sein.
Cloud-Provider-Integration: AWS, Azure, GCP bieten
offizielle Actions für ihre Services.
aws-actions/configure-aws-credentials,
azure/login, google-github-actions/auth – sie
kennen die Eigenheiten ihrer Plattformen, implementieren Best Practices
(OIDC statt langlebige Credentials), und werden synchron zu
API-Änderungen aktualisiert.
Community-Lösungen für Commodity-Tasks: Linting,
Formatierung, Security-Scanning – Tools wie super-linter,
reviewdog, oder trufflesecurity/trufflehog
sind gut maintained und feature-rich. Sie neu zu implementieren bindet
Ressourcen ohne Mehrwert.
Komplexität außerhalb unserer Core-Kompetenz: Eine Action für Kubernetes-Deployments mit Helm, Canary-Strategies und Rollback-Logic zu schreiben, ist ein eigenes Projekt. Wenn es bewährte Actions gibt, nutzen wir sie.
Domänenspezifische Logik: Business-Rules, die nur in unserem Kontext Sinn ergeben. Ein Approval-Workflow, der gegen unser Ticketing-System prüft. Eine Notification-Logic, die interne Slack-Channels und Oncall-Rotations berücksichtigt. Eine Deployment-Strategie, die unsere spezifische Infrastruktur kennt. Das sind keine generischen Problems – eine Marketplace-Action wird sie nicht abdecken.
Security und Compliance: Wenn regulatorische Anforderungen Auditing, Isolation oder spezifische Kryptographie verlangen, ist eine eigene Action die sichere Wahl. Wir kontrollieren den Code, wir reviewen jede Änderung, wir wissen, was sie tut.
Performance-kritische Operationen: Eine JavaScript Action, die unsere spezifische Build-Cache-Strategie implementiert und damit 5 Minuten pro Build spart, amortisiert sich schnell. Marketplace-Actions sind generisch – unsere eigene kann auf unseren Use Case optimieren.
Keine passende Action trotz Suche: Manchmal gibt es einfach nichts. Ein Legacy-Tool, ein proprietäres System, eine neue Technologie. Dann bleibt nur DIY.
Wiederkehrende Step-Sequenzen: Wenn dieselben 5-10 Steps in 10 Workflows kopiert werden, ist eine Composite Action die DRY-Lösung. Sie ist schnell geschrieben, braucht keine externe Dependencies, und bleibt in unserer Kontrolle.
| Kriterium | Bestehende Action | Eigene Action |
|---|---|---|
| Task-Typ | Standard, generisch | Domänenspezifisch, proprietär |
| Verfügbarkeit | Gute Action existiert | Keine passende gefunden |
| Sicherheit | Vertrauenswürdiger Maintainer | Volle Kontrolle nötig |
| Wartung | Extern maintained | Team-Kapazität vorhanden |
| Komplexität | Hoch, außerhalb Expertise | Überschaubar, im Skill-Set |
| Time-to-Market | Sofort einsetzbar | Entwicklungsaufwand akzeptabel |
Organisationen mit vielen Repositories haben oft ähnliche Anforderungen: Node.js-Setup mit spezifischer Version, AWS-Auth mit bestimmten Roles, Docker-Build mit Standard-Tags. Statt in jedem Repository die gleichen Actions mit den gleichen Parametern zu konfigurieren, erstellen wir Composite Actions als Wrapper:
# .github/actions/setup-node-standard/action.yml in Org-Repository
name: 'Standard Node.js Setup'
description: 'Company-standard Node setup with caching'
runs:
using: 'composite'
steps:
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Configure npm registry
shell: bash
run: |
echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
- run: npm ci
shell: bashJedes Projekt nutzt diese Action:
- uses: my-org/github-actions/.github/actions/setup-node-standard@v1Ein Update der Node-Version oder der npm-Config geschieht zentral. Alle Projekte bekommen es beim nächsten Action-Update.
Nicht jede wiederverwendbare Logic braucht ein separates Repository. Für Workflows innerhalb eines Repositories können wir Actions lokal definieren:
my-repo/
├── .github/
│ ├── workflows/
│ │ └── ci.yml
│ └── actions/
│ └── custom-deploy/
│ └── action.yml
Im Workflow referenzieren wir mit relativem Pfad:
- uses: ./.github/actions/custom-deploy
with:
environment: stagingDas hält alles in einem Repository, vereinfacht Versionierung (Action und Workflow-Changes sind derselbe Commit), und vermeidet Overhead für kleine, repo-spezifische Automationen.
Ein dependabot.yml mit Auto-Merge für Action-Updates mag
effizient klingen, ist aber riskant:
# NICHT empfohlen ohne Manual Review
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"
open-pull-requests-limit: 10
# Auto-merge ohne Review? Gefährlich!Ein Breaking Change in einer Action, ein Bug in einem neuen Release, oder schlimmer – eine kompromittierte Version – wird direkt in Production merged. Dependabot-PRs sollten reviewed werden, mindestens bei Major-Updates und bei Third-Party-Actions.
15 verschiedene Node.js-Setup-Actions im selben Mono-Repo, weil jedes Team “seine eigene Variante” wollte, sind Wartungs-Albtraum. Konsolidierung und Parametrisierung statt Duplikation:
# Statt 15 Actions mit hardcoded Versionen
- uses: ./.github/actions/setup-node
with:
version: ${{ matrix.node }} # ParametrisiertEine Action, eine Source of Truth, ein Update-Pfad.
Die Versuchung ist groß: Komplexe Bash-Scripts in eine Action auslagern und das Problem als “gelöst” betrachten. Aber eine Action ist kein Magic-Black-Box. Wenn ein 300-Zeilen-Shell-Script in eine Composite Action gepackt wird, ist es immer noch ein 300-Zeilen-Shell-Script – nur schlechter debuggable, weil nicht direkt im Workflow sichtbar.
Actions sind für Wiederverwendung und Abstraktion sinnvoll. Für einmalige, workflow-spezifische Logic ist ein gut dokumentierter Step besser als eine verschleiernde Action.
Actions sind keine statischen Dependencies. Sie entwickeln sich, bekommen Updates, werden deprecated. Ein professioneller Umgang bedeutet:
Dieser Lifecycle-Ansatz macht Actions zu First-Class-Dependencies, nicht zu Fire-and-Forget-Tools. Das erhöht Aufwand, aber auch Zuverlässigkeit und Sicherheit.