Blog

Verwendung dynamischer Pipelines in GitLab

Jeffrey Zaayman

Jeffrey Zaayman

Aktualisiert Oktober 15, 2025
5 Minuten

Dynamische Pipelines in GitLab sind eine Teilmenge der Child-Pipelines. Sie haben dieselben Funktionen wie Child-Pipelines - der Unterschied besteht darin, wie Sie die Datei erstellen.

Einer der schwierigsten Aspekte beim Schreiben von Pipelines ist die Berücksichtigung von Permutationen. Oft wiederholen Sie dieselben Arbeitsabläufe mit nur geringen Unterschieden. Das ist besonders frustrierend, wenn Sie viele verschiedene Umgebungen ansteuern müssen.

Wir alle sind es gewohnt, unsere Workflow-Dateien zu erstellen und sie dann in die Versionskontrolle einzuchecken. Sie sind feststehende Gebilde, die wir unter Berücksichtigung aller Variationen erstellen müssen. Aber das muss nicht so sein - wir können Workflow-Dateien bei Bedarf erstellen. Mit dynamischen Pipelines ist genau das möglich.

Im ersten Beispiel wird ein bash Skript verwendet, um die dynamischen Pipeline-Dateien zu erzeugen. Spätere Beispiele werden ein Python-Skript verwenden.

Ein grundlegendes Beispiel

Im Folgenden finden Sie eine kleine Einführung in die Erstellung einer dynamischen Pipeline.

Den Quellcode finden Sie im Referenz-Repository.

Wir definieren alles in .gitlab-ci.yml:

create-dynamic-pipeline-file:
  script: |
    cat <<EOF > dynamic-pipeline.yml
    dynamic-job:
      script:
      - echo "This job is created dynamically"
    EOF
  artifacts:
    paths:
    - dynamic-pipeline.yml

trigger-dynamic-pipeline:
  needs: [create-dynamic-pipeline-file]
  trigger:
    include:
    - artifact: dynamic-pipeline.yml
      job: create-dynamic-pipeline-file

In dem Auftrag create-dynamic-pipeline-file verwendet script hier die Dokumentennotation, um einen einfachen Auftrag zu erstellen. Das Ergebnis wird in eine Datei ausgegeben und als Artefakt gespeichert.

Der Auftrag trigger-dynamic-pipeline hängt von dem vorherigen Auftrag ab und löst die Child-Pipeline aus. Dies ist fast identisch mit dem Beispiel der Child-Pipeline.

Beachten Sie, dass Sie den Namen des erstellenden Auftrags zweimal angeben müssen. Einmal für needs und ein weiteres Mal, um dem Trigger mitzuteilen, von welchem Auftrag die Pipeline stammt.

Pipeline-Ausgabe mit dem Ausdruck

Dynamische Child-Pipeline-Ausgabe

Die Ausgabe der Child-Pipeline ist das, was wir angegeben haben.

Basis-Beispiel-Downstream

Die dynamisch erstellte Pipeline-Datei ist zu einer untergeordneten Pipeline geworden

Die Pipeline-Ansicht ist fast dieselbe wie beim Auslösen einer regulären untergeordneten Pipeline - mit dem Zusatz, dass zuerst der Auftrag erstellt wird.

Eine dynamische Pipeline auf Python-Basis

In diesem nächsten Beispiel wird Python verwendet, um die Child-Pipeline-Datei zu erstellen.

Den Quellcode finden Sie im Referenz-Repository.

Auch hier beginnen wir mit .gitlab-ci.yml:

default:
  image: python:3.7

create-file-job:
  script: |
    pip install -r requirements.txt
    python generate_pipeline.py
  artifacts:
    paths:
    - dynamic-pipeline.yml

trigger-dynamic-pipeline:
  needs: [create-file-job]
  trigger:
    include:
    - artifact: dynamic-pipeline.yml
      job: create-file-job

Dies ist der Code für die Python-Datei generate_pipeline.py, die den Pipeline-Code erstellt:

import yaml


pipeline = {
    "dynamic-pipeline": {
        "script": [
            "echo Hello World!"
        ]
    }
}

with open("dynamic-pipeline.yml", "w") as f:
    f.write(yaml.dump(pipeline, default_flow_style=False))

Beachten Sie, dass durch die Verwendung einer Sprache mit mehr Funktionen die YAML-Struktur in einer anderen Form als Text definiert werden kann. Das macht die programmatische Bearbeitung von YAML viel einfacher.

Umgekehrt wird dadurch die Fehlersuche in Ihrem endgültigen Pipeline-Code erschwert.

Und schließlich brauchen wir requirements.txt:

PyYAML

Wenn Sie unseren Code pushen, erhalten Sie die folgende Ausgabe:

Pipeline-Ausgabe mit

Ausgabe der mit Python generierten dynamischen Pipeline

Wenn Sie den Großteil Ihrer Pipeline-Erstellung in ein Skript verlagern, können Sie Funktionen, Variablen, Schleifen und andere Programmiertricks verwenden, um die Komplexität zu verringern.

Übergabe von Argumenten an den Pipeline-Generator

Die Definition komplexer Pipelines in statischen Dateien bedeutet in der Regel die Erstellung komplizierter Regeln. Child-Pipelines nehmen uns einen Teil dieser Last ab, aber Sie müssen immer noch alles vordefinieren. Ein Skript, das den minimal notwendigen Pipeline-Code generiert, ist die bessere Lösung. Durch die Verwendung von Variablen haben Sie eine genaue Kontrolle darüber, was Ihr Skript ausgibt.

Den Quellcode finden Sie im Referenz-Repository.

Erweitern wir generate_pipeline.py und lassen Sie es ein paar Argumente aufnehmen:

import yaml
import argparse


parser = argparse.ArgumentParser()
parser.add_argument("--filename", help="Name of the file to write to")
parser.add_argument("--environment", help="The environment to deploy to", default="dev")
args = parser.parse_args()

pipeline = {}

pipeline["dynamic-pipeline"] = {
    "script": [
        "echo Hello World!"
    ]
}

environment = {
    "needs": ["dynamic-pipeline"],
    "script": [
        f"echo Deploying to {args.environment}"
    ]
}

pipeline[f"deploy-to-{args.environment}"] = environment

print(pipeline)

with open(args.filename, "w") as f:
    f.write(yaml.dump(pipeline, default_flow_style=False, sort_keys=False))

Beachten Sie, dass Python ab Version 3.7 die Reihenfolge der Wörterbuchschlüssel beibehält(siehe hier).

Wir können Variablen verwenden, um die Namen der Aufträge zu überarbeiten und die endgültige Datei zu erstellen.

Jetzt übergibt die Datei .gitlab-ci.yml Argumente an das Skript:

default:
  image: python:3.7

variables:
  PIPELINE_FILE: dynamic-pipeline.yml
  ENVIRONMENT: test

create-file-job:
  script: |
    pip install -r requirements.txt
    python generate_pipeline.py --filename=$PIPELINE_FILE --environment=$ENVIRONMENT
    cat $PIPELINE_FILE
  artifacts:
    paths:
    - $PIPELINE_FILE

trigger-dynamic-pipeline:
  needs: [create-file-job]
  trigger:
    include:
    - artifact: $PIPELINE_FILE
      job: create-file-job

In diesem Fall sind die Argumente Dateiname und Zielumgebung Variablen. Diese können aus der GUI oder sogar aus einer vorgelagerten Pipeline stammen. Je nach Ihren Bedürfnissen muss die generierte Pipeline nur den wichtigsten Code enthalten. Sie müssen auch keine verschlungenen Regeln schreiben.

Pipeline-Ansicht mit Anzeige des erstellten Auftrags und der dynamischen untergeordneten Pipeline-Aufträge

Die dynamische Child-Pipeline, einschließlich Abhängigkeiten

Beachten Sie, dass wir sogar Abhängigkeiten zwischen den dynamischen Aufträgen einrichten können.

Pipeline-Ausgabe druckt

Die Ausgabe des Auftrags 'deploy-to-test'.

Anhand der Ausgabe sehen wir, dass der Auftrag entsprechend den Variablen auf die 'Test'-Umgebung abzielt.

Fazit

Wenn Sie Ihre Pipeline mit Code generieren, heben Sie Ihre Builds auf die nächste Stufe. Oft ist die Diskrepanz zwischen dem Schreiben von Code und dem Schreiben von YAML-Pipelines ziemlich groß. Wenn Sie sich jemals gewünscht haben, Ihre Pipelines als Code schreiben zu können, sind dynamische Pipelines die Antwort.

Verfasst von

Jeffrey Zaayman

Contact

Let’s discuss how we can support your journey.