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: trueruns: 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.
Hinterlasse einen Kommentar