04. | Viele Pipelines triggern

Zum Wochenende und rechtzeitig zum zweiten Advent möchte ich ein kleines Pythonskript teilen, das mir die Arbeit mit GitLab sehr erleichtert hat. Seine Funktion lässt sich vielleicht mit einer weihnachtlichen Analogie am besten erklären: Das Skript kann quasi alle Kerzen des Weihnachtsbaums gleichzeitig anzünden!

Pipelines in GitLab triggern

Für die Produktion der Artikel des Journals kommunikation@gesellschaft in den Formaten HTML und PDF wurde jeder Beitrag als eigenes GitLab-Projekt angelegt.1 Damit wird jeder Artikel in einer eigenen Pipeline mit Docker produziert, was viele Vorteile hat. Wenn sich jedoch etwas Grundlegendes ändert, das sich auf alle Beiträge auswirkt, dann muss jede Pipeline neu getriggert werden. Eine solche Änderung kann bspw. im Template erfolgen oder auch in der Darstellung und Verarbeitung der Metadaten. Das kann bei vielen Pipelines dann schon lästig werden, wenn diese manuell im Browser getriggert werden müssen. Auftritt Python!

Die GitLab-API mit Python ansprechen

Zum Glück gibt es ein mächtiges und gut gepflegtes Python-Package, um die GitLab-API anzusprechen und u.a. Pipelines automatisiert zu triggern. Mein Skript, das davon Gebrauch macht, sieht wie folgt aus:

#!/usr/bin/env python3

# This script triggers the pipelines of all
# projects in a given group.
# Triggers were manually defined, just one per
# project, so the first trigger is the only one.

# batch_wait_time is an arbitrary value due to
# experiences with download times in the pipelines.

import gitlab
import time

# Load configuration from a local file
# This way you do not have to check in
# credentials to version control
gl = gitlab.Gitlab.from_config('myconfig')

# The group in GitLab that contains the projects
# with pipelines you want to trigger
parent_group_id = 1234
# Branch of which you want to trigger the pipeline
branch = "01-iteration"
# Arbitray seconds to wait between triggers
batch_wait_time = 10

group = gl.groups.get(parent_group_id)
# Get all projects belonging to the group
projects = group.projects.list(all=True)

for p in projects:
    # for manageable_projects refer to https://python-gitlab.readthedocs.io/en/stable/gl_objects/groups.html#examples
    manageable_project = gl.projects.get(p.id, lazy=True)

    try:
        # Try to get the first existing trigger if any
        first_trigger = manageable_project.triggers.list()[0]
        # Trigger the pipeline!
        token = first_trigger.token
        pipeline = manageable_project.trigger_pipeline(branch, token)
        print(f"Triggering pipeline for {first_trigger.description}")
        time.sleep(batch_wait_time)
    except IndexError:
        print(f"No trigger defined for {manageable_project.id}!")

Hervorzuheben ist, dass die Projekte, deren Pipelines getriggert werden sollen, alle in ein und derselben Gruppe liegen müssen.


  1. Wie das genau funktioniert und wie das Journal in GitLab abgebildet ist, werde ich in einem anderen Beitrag noch genau erläutern. ↩︎

Avatar
Axel Dürkop
Teamleiter, Systemarchitekt und technische Umsetzung

Ähnliches