In den früheren Beiträgen „Migration von Bitbucket-Repositorys und Pipelines zu GitHub Actions “ und „Sichere Aktualisierung von Abhängigkeiten während der Migration von Bitbucket zu GitHub“ haben wir erläutert , wie Repositorys von Bitbucket Cloud zu GitHub migriert wurden und wie Projektabhängigkeiten sicher aktualisiert wurden , um sicherzustellen, dass die Builds weiterhin zuverlässig laufen. Nachdem die Versionskontrolle und die Abhängigkeiten nun eingerichtet sind, besteht der nächste Schritt der Migration darin, die CI/CD-Ebene selbst zu modernisieren.
Dieser Artikel befasst sich mit der Modernisierung von Continuous-Integration-Workflows durch die Umsetzung bestehender Bash-Skripte und Jenkins-Pipelines in GitHub Actions, wodurch ein einheitliches, wartungsfreundliches Automatisierungsmodell entsteht.

Von Jenkins und Bash zu einem einheitlichen CI-Workflow
In diesem Projekt wurde eine der Pipelines mithilfe eines Bash-Skripts implementiert, mit Jenkins den Build-Prozess koordiniert und ausführt. Das Ziel der Migration bestand darin, die bestehende Skriptlogik und das Pipeline-Verhalten in einen GitHub-Actions-Workflow zu übertragen, ohne das Build-Ergebnis zu verändern.
Nachfolgend finden Sie ein Beispiel für das ursprüngliche „build.sh“-Skript:
#!/bin/bash
set -e
set -x
branch=$1
commit=$2
# Clean previous builds
make -f docker.mk cleanup DOWNLOAD_DIR=/path/to/downloads
# Run the build
make -f docker.mk DOWNLOAD_DIR=/path/to/downloads
# Copy build artifacts
mkdir -p output/${branch}_${commit}
cp build/* output/${branch}_${commit}/
# Publish build artifacts to a remote server
pscp -i /path/to/private_key -P REMOTE_PORT -q -r output/${branch}_${commit} REMOTE_USER@REMOTE_HOST:REMOTE_PATH
Dieses Skript fasst die zentrale Build-Logik zusammen: das Löschen früherer Ergebnisse, das Ausführen des Builds und das Sammeln der Artefakte in einem strukturierten Ausgabeverzeichnis.
Konfiguration der Jenkins-Pipeline
Die Jenkins-Pipeline, die für die Ausführung dieses Skripts zuständig war, wurde wie folgt definiert:
import java.text.SimpleDateFormat;
def builders = [:]
builders['linux-builder'] = {
node('linux-node') {
build_project()
}
}
parallel builders
void build_project() {
stage('Build') {
def scmVars = checkout scm
def commit = scmVars.GIT_COMMIT.take(8)
sh "./build.sh ${scmVars.GIT_BRANCH} ${commit}"
}
}
Jenkins übernahm das Auschecken des Repositorys, extrahierte die Metadaten zu Zweig und Commit und führte das Bash-Skript auf einem bestimmten Build-Knoten aus.
Das Verhalten von Jenkins auf GitHub Actions abbilden
Um diese Konfiguration zu migrieren, wird unter .github/workflows/ eine Workflow-Datei definiert. Diese Datei legt fest, wann die Pipeline ausgeführt wird, welcher Runner sie ausführt und welche Schritte erforderlich sind.
In der Jenkins-Konfiguration wurden Pipelines über Bitbucket-Webhooks ausgelöst und konnten auf bestimmte Zweige beschränkt werden. Dieses Verhalten wird in GitHub Actions mithilfe von zweigbasierten Auslösern abgebildet:
on:
push:
branches:
- main
- 'release/*'
workflow_dispatch:
Diese Konfiguration stellt sicher, dass der Workflow bei Pushes in die angegebenen Zweige automatisch ausgeführt wird, während „workflow_dispatch“ eine manuelle Ausführung ermöglicht, ähnlich wie die „Build Now“-Funktion von Jenkins.
Auswahl der Ausführungsumgebung
In GitHub Actions wird die Ausführungsumgebung mithilfe des Schlüsselworts „runs-on“ definiert:
runs-on: [self-hosted, us-east-1, X64, yocto]
Dadurch wird GitHub Actions angewiesen, den Job auf einem selbst gehosteten Runner auszuführen, der diesen Tags entspricht (siehe unseren ausführlichen Leitfaden zur Bereitstellung selbst gehosteter GitHub-Runner auf Kubernetes). Konzeptionell entspricht dies direkt dem Knoten „linux-node“ in Jenkins, wodurch sichergestellt wird, dass der Build auf dem entsprechenden Rechner ausgeführt wird.
Code auschecken und Metadaten anzeigen
In Jenkins wurden das Auschecken des Repositorys und die Extraktion der Metadaten wie folgt durchgeführt:
def scmVars = checkout scm
In GitHub Actions wird dies mithilfe der „Checkout“-Aktion und integrierter Kontextvariablen erreicht:
- name: Checkout repository
uses: actions/checkout@v4
env:
DOWNLOAD_DIR: /path/to/downloads
BRANCH: ${{ github.ref_name }}
Das Repository wird in den Ordner $GITHUB_WORKSPACE ausgecheckt, während die Informationen zu Branch und Commit über ${{ github.ref_name }} und ${{ github.sha }} bereitgestellt werden. Dadurch stehen dieselben Eingaben zur Verfügung, die zuvor an das Bash-Skript in Jenkins übergeben wurden.
Durch die Verwendung des Schlüsselworts „run“ können Shell-Befehle unverändert ausgeführt werden, was die Migration unkompliziert und risikoarm macht.
Umgang mit Build-Artefakten
Um Build-Ergebnisse zu erfassen, bietet GitHub Actions eine integrierte Aktion zum Hochladen von Artefakten:
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: output/**
In der ursprünglichen Jenkins-Konfiguration wurden Artefakte mithilfe von Tools wie pscp auf einen Remote-Server hochgeladen. Mit GitHub Actions werden Artefakte direkt in GitHub gespeichert, wodurch externe Server überflüssig werden und die Artefakte gleichzeitig vom Workflow-Lauf aus leicht zugänglich bleiben.
Endgültiger GitHub-Actions-Workflow
Der vollständig migrierte Workflow sieht wie folgt aus:
name: Build Pipeline
on:
push:
branches:
- main
- 'release/*'
workflow_dispatch:
env:
DOWNLOAD_DIR: /path/to/downloads
BRANCH: ${{ github.ref_name }}
jobs:
build:
runs-on: [self-hosted, us-east-1, X64, yocto]
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Clean build
run: make -f docker.mk cleanup DOWNLOAD_DIR=$DOWNLOAD_DIR
- name: Build project
run: make -f docker.mk DOWNLOAD_DIR=$DOWNLOAD_DIR
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: build-artifacts
path: output/**
Die wichtigsten Erkenntnisse aus der Migration
Beim Umstieg von einer auf Jenkins und Bash basierenden Umgebung auf GitHub Actions geht es nicht darum, Skripte Zeile für Zeile zu kopieren. Stattdessen liegt der Schwerpunkt darauf, die Pipeline-Logik und die Ergebnisse zu bewahren, um saubere Builds, korrekte Artefakte und eine zuverlässige Ausführung zu gewährleisten – und gleichzeitig die Wartbarkeit zu verbessern und den Betriebsaufwand zu reduzieren.
Wie geht es weiter auf dem Weg zur Migration?
Nachdem die CI-Workflows modernisiert und unter GitHub Actions konsolidiert wurden, besteht der letzte Schritt darin, die nativen Bitbucket-Pipelines zu migrieren. Der nächste Artikel befasst sich mit der Umsetzung von YAML-basierten Bitbucket-Pipelines in GitHub-Actions-Workflows, womit die Umstellung auf eine vollständig standardisierte CI/CD-Plattform abgeschlossen wird.
Seid gespannt auf den nächsten Teil der Serie.
Weitere Blogbeiträge findest duhier.