Reusable Workflows habe ich hier im Juli schon behandelt. Die kleinere Einheit daneben ist die Composite Action: ein Bündel aus Steps, das sich wie eine einzelne Action aufrufen lässt. Beide Mechanismen sind wiederverwendbar, beide stehen in YAML, und trotzdem lösen sie unterschiedliche Probleme. Wer sie verwechselt, baut entweder Workflows, die niemand warten will, oder Actions, die heimlich ganze Pipelines sind.

Was eine Composite Action ist

Eine Composite Action ist eine action.yml mit runs.using: composite. Sie enthält Steps, keine Jobs. Sie läuft immer im Job des Aufrufers, auf dessen Runner und in dessen Kontext. Ein typisches Beispiel ist ein Toolchain-Setup, das in jedem Repository gleich aussieht:

name: "Setup Node with Cache"
description: "Node einrichten, Dependencies cachen und installieren"
inputs:
node-version:
description: "Node-Version"
required: false
default: "22"
runs:
using: "composite"
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ inputs.node-version }}
cache: npm
- run: npm ci
shell: bash

Im Workflow wird daraus ein einziger Step:

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: my-org/setup-node-cache@v1
with:
node-version: "22"
- run: npm test

Der Unterschied zum Reusable Workflow

Ein Reusable Workflow arbeitet auf Job-Ebene. Er bringt eigene Jobs mit, entscheidet über runs-on, kann eine Matrix aufspannen und bekommt Secrets nur über explizite Übergabe oder secrets: inherit. Er ist damit das Werkzeug, um eine ganze CI-Stufe zu standardisieren, inklusive Runner-Wahl und Permissions.

Eine Composite Action entscheidet nichts davon. Sie kennt keinen Runner, setzt keine Permissions und hat keinen Zugriff auf den Secrets-Kontext. Sie bekommt Inputs, führt Steps aus und gibt Outputs zurück. Daraus folgt die Faustregel, die sich bei mir bewährt hat: alles, was Infrastruktur entscheidet, gehört in den Workflow. Alles, was Handgriffe bündelt, gehört in die Action.

Wann das Step-Bündel die bessere Wahl ist

Die Composite Action gewinnt immer dann, wenn dieselbe Sequenz von Steps in Jobs mit unterschiedlichen Rahmenbedingungen laufen soll. Der eine Job läuft auf Ubuntu, der andere auf einem Self-hosted Runner, der dritte in einer Matrix über drei Node-Versionen. Ein Reusable Workflow müsste all das selbst abbilden. Die Composite Action ist davon unabhängig, weil der Aufrufer die Kontrolle behält.

Typische Kandidaten sind Toolchain-Setups mit Cache, der Login gegen eine Registry, das Erzeugen einer SBOM nach dem Build oder das Einsammeln von Testberichten. Kurz: wiederkehrende Handgriffe, die für sich genommen keine Pipeline sind. Sobald dagegen Runner-Wahl, Permissions oder die Job-Struktur Teil der Wiederverwendung sein sollen, ist der Reusable Workflow das richtige Werkzeug. Beides zusammen funktioniert auch: ein zentraler Reusable Workflow, der intern Composite Actions nutzt, ist ein sauberes Muster.

Die Stolperfallen

Drei Dinge kosten beim ersten Bau einer Composite Action regelmäßig Zeit. Erstens: jeder run-Step braucht ein explizites shell-Attribut, sonst bricht die Action beim Parsen ab. In Workflows ist das optional, in Composite Actions Pflicht.

Zweitens: Secrets müssen als Input hereingereicht werden, der secrets-Kontext existiert innerhalb der Action nicht.

inputs:
registry-token:
description: "Token für ghcr.io"
required: true
runs:
using: "composite"
steps:
- run: echo "${{ inputs.registry-token }}" | docker login ghcr.io -u $GITHUB_ACTOR --password-stdin
shell: bash

Drittens: mitgelieferte Skripte liegen nicht im Workspace des Aufrufers, sondern im Verzeichnis der Action. Der Pfad dorthin ist github.action_path:

    - run: "${{ github.action_path }}/scripts/check.sh"
      shell: bash

Versioniert wird wie bei jeder Action über Tags. Ein gepflegter Major-Tag wie v1, der auf den letzten kompatiblen Stand zeigt, erspart den Aufrufern ständige Updates. Wer die Action extern bezieht, pinnt sie besser auf einen Commit-Hash, das hatte ich im Juni im Beitrag zum Absichern von GitHub Actions ausführlicher.

Fazit

Composite Actions und Reusable Workflows konkurrieren nicht, sie schneiden auf verschiedenen Ebenen. Das Step-Bündel für Handgriffe, der Workflow für Struktur und Rechte. Wer diese Grenze sauber zieht, bekommt Pipelines, die sich lesen lassen und deren Bausteine einzeln testbar bleiben. Warum solche standardisierten Bausteine auch über die reine Technik hinaus interessant sind, etwa als Grundlage für nachvollziehbare Delivery-Prozesse, dazu schreibe ich drüben auf digital-business.blog.

2 Antworten zu „Composite Actions richtig schneiden: wann ein Step-Bündel besser ist als ein Workflow“

  1. […] Zwei verwandte Themen aus dieser Serie: wie ein Reusable Workflow überhaupt sauber gebaut wird, steht im Post Reusable Workflows in GitHub Actions sauber bauen. Die Abgrenzung zu Composite Actions steht in Composite Actions richtig schneiden. […]

  2. […] du auf digital-business.blog. Wie du Composite Actions von Reusable Workflows abgrenzt, liest du im Post vom 17.08.. Wie du Secrets aus Build-Layern heraushältst, im Post vom 14.08.. Wie ephemere Runner die […]

Hinterlasse einen Kommentar

Diese Seite verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden..