Normale Ansicht

Received today — 12. Mai 2025

Codeberg.org mit Forgejo Actions, Runner, Workflows und ich

12. Mai 2025 um 05:00

In diesem Artikel halte ich fest, was es mit den genannten Begriffen auf sich hat und was ich in den vergangenen Tagen mit ihnen angestellt habe. Dabei gehe ich auch auf das Warum ein, während Fragen nach dem Wie vorwiegend in den Verweisen im Text beantwortet werden.

Der Artikel dient mir als Dokumentation und meinen Leser:innen zur Unterhaltung und zum Wissenstransfer.

Codeberg.org

Codeberg ist eine demokratische, gemeinschaftsgetriebene, gemeinnützige Softwareentwicklungsplattform, die von Codeberg e.V. betrieben wird und sich um Codeberg.org, eine auf Forgejo basierende Software, dreht. Der Sitz des Vereins ist in Berlin. Hier wird Codeberg.org auch gehosted.

Auf Codeberg könnt ihr eure eigenen Freie Software-Projekte entwickeln, zu anderen Projekten beitragen, inspirierende und nützliche Freie Software durchstöbern, euer Wissen teilen oder euren Projekten mit Codeberg Pages ein Zuhause im Web geben, um nur einige Beispiele zu nennen.

Die beiden vorstehenden Abschnitte wurden übersetzt mit DeepL.com (kostenlose Version) und anschließend leicht angepasst und mit Links angereichert.

Mit Codeberg.org werden keine kommerziellen Interessen verfolgt. Man ist hier (nur) Nutzer und/oder Unterstützer, jedoch nicht selbst ein Produkt. Mir gefällt die Mission des Projekts. Daher bin ich dazu übergegangen, einen Teil meiner Repositories hier zu verwalten. Zwar bin ich kein Mitglied des Vereins, unterstütze diesen jedoch durch gelegentliche Spenden.

Actions, Runner und Workflows

Plattformen wie Codeberg.org, GitHub und GitLab unterstützen Softwareentwicklungsprozesse durch CI/CD-Funktionalität.

Ein Forgejo-Runner ist ein Dienst, der Workflows von einer Forgejo-Instanz abruft, sie ausführt, mit den Protokollen zurücksendet und schließlich den Erfolg oder Misserfolg meldet.

Dabei ist ein Workflow in der Forgejo-Terminologie eine YAML-Datei im Verzeichnis .forgejo/workflows eines Repositories. Workflows umfassen einen oder mehrere Jobs, die wiederum aus einem oder mehreren Steps bestehen. Eine Action ist eine Funktion zur Erfüllung häufig benötigter Aufgaben, bspw. Quelltext auschecken, oder sich bei einer Container-Registry einloggen etc. Siehe für weitere Informationen Abschnitt Hierarchy ff. im Forgejo Actions user guide.

Motiviert, meinen eigenen Forgejo-Runner zu installieren, haben mich zwei Blog-Artikel von meinem Arbeitskollegen Jan Wildeboer:

Durch den Betrieb eigener Forgejo-Runner kann ich bereits vorhandene Rechenkapazität nutzen. Es fallen für mich und den Verein Codeberg e.V. dadurch keine zusätzlichen Kosten an. Für die Installation auf RHEL 9 bin ich dem Forgejo Runner installation guide gefolgt, da das in Jans Artikel erwähnte Repository ne0l/forgejo offensichtlich nicht mehr gepflegt wird und nur eine veraltete Version des Runner enthält.

Ein Dankeschön geht raus an Jan für unseren kurzen und produktiven Austausch dazu auf Mastodon.

Wozu das Ganze?

Ich beschäftige mich beruflich seit einiger Zeit mit dem RHEL image mode und möchte demnächst einen meiner KVM-Hypervisor damit betreiben. Bis es soweit ist, arbeite ich eine Weile im „Jugend forscht“-Modus und baue immer wieder neue Versionen meiner Container-Images. Der Ablauf ist dabei stets derselbe:

  1. Containerfile(5) erstellen bzw. anpassen
  2. Container-Image mit podman-build erstellen
  3. Das erstellte Image mit podman-push in eine Container-Registry hochladen
  4. Das Deployment auf diversen Zielsystemen testen

Dazu verwende ich das RHEL 9 Bootc Base Image aus der Registry registry.redhat.io.

The rhel-bootc and user-created containers based on rhel-bootc container image are subject to the Red Hat Enterprise Linux end user license agreement (EULA). You are not allowed to publicly redistribute these images.

Quelle: https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/using_image_mode_for_rhel_to_build_deploy_and_manage_operating_systems/introducing-image-mode-for-rhel_using-image-mode-for-rhel-to-build-deploy-and-manage-operating-systems#introducing-image-mode-for-rhel_using-image-mode-for-rhel-to-build-deploy-and-manage-operating-systems

Um vorstehender Anforderung gerecht zu werden, speichere ich das erzeugte Container-Image in einem privaten Repository auf Quay.io. Sowohl für registry.redhat.io als auch für quay.io ist ein Login erforderlich, bevor es losgehen kann.

Für mich bot sich hier die Gelegenheit, die Nutzung von Forgejo Workflows zu lernen und damit den Ablauf zur Erstellung meines RHEL Bootc Images zu automatisieren.

Forgejo Workflow und Runner-Konfiguration

Im folgenden Codeblock findet ihr meinen Forgejo Workflow aus der Datei .forgejo/workflows/build_image.yaml, gefolgt von einer Beschreibung der einzelnen Schritte. Zur Erklärung der Begriffe name, on, env, jobs, steps, run, etc. siehe Workflow reference guide.

name: build_image

on:
  push:
    branches: main

env:
  REPO_URL: https://codeberg.org/Tronde/rhel-bootc.git
  REPO_NAME: rhel-bootc
  IMAGE_NAME: quay.io/rhn-support-jkastnin/rhel-bootc:9.5

jobs:
  build:
    runs-on: podman
    steps:
      - run: dnf -y install git
      - run: echo ${{ secrets.RH_REGISTRY_TOKEN }} | podman login -u ${{ secrets.RH_REGISTRY_USERNAME }} --password-stdin registry.redhat.io

      - run: echo ${{ secrets.QUAY_ROBOT_TOKEN }} | podman login -u ${{ secrets.QUAY_USERNAME }} --password-stdin quay.io

      - run: git clone ${{ env.REPO_URL }}
      - run: podman build -f /workspace/Tronde/rhel-bootc/rhel-bootc/Containerfile -t ${{ env.IMAGE_NAME }}
      - run: podman push ${{ env.IMAGE_NAME }}
  1. Der Workflow wird jedes Mal ausgeführt, wenn ich einen Commit in den Branch main pushe
  2. Ich definiere einige Umgebungsvariablen, um bei Änderungen nicht alle Schritte im Workflow einzeln auf notwendige Änderungen prüfen zu müssen
  3. Mit `runs-on: podman` bestimme ich, dass der Workflow auf einem Runner mit dem Label podman ausgeführt wird; der entsprechende Runner started dann einen rootless Podman-Container, in dem die folgenden Schritte innerhalb von rootful Podman ausgeführt werden (nested Podman bzw. Podman in Podman)
  4. Git wird installiert
  5. Anmeldung an registry.redhat.io erfolgt
  6. Anmeldung an quay.io erfolgt
  7. Das Git-Repository wird geklont, um es auf dem Runner verfügbar zu haben
  8. Der Runner baut ein Container-Image (Erinnerung an mich selbst: Ersetze den hardcodierten Pfad durch eine Variable)
  9. Das erstellte Image wird in die Registry gepusht

Damit mein Runner den obigen Workflow ausführen kann, existiert auf diesem die Konfigurationsdatei /etc/forgejo-runner/config.yml, welche ich mit dem Kommando forgejo-runner generate-config > config.yml erstellt und anschließend angepasst habe. Der folgende Codeblock zeigt nur die Abschnitte, die ich manuell angepasst habe.

…
  fetch_interval: 20s
…
  labels: [
    "rhel-9-ubi:docker://registry.access.redhat.com/ubi9/ubi",
    "podman:docker://registry.access.redhat.com/ubi9/podman",
    "ubuntu-latest:docker://ghcr.io/catthehacker/ubuntu:act-latest",
    "act-runner:docker://node:20-bullseye",
    "centos-stream-9:docker://quay.io/centos/centos:stream9"]
…
  privileged: true
…

Ich greife mal die Zeile podman:docker://registry.access.redhat.com/ubi9/podman heraus:

  • podman: am Beginn der Zeile beinhaltet das Label, welches im Worflow mit runs-on verwendet wird
  • Mit dem Rest der Zeile wird bestimmt, in welchem Container-Image der Workflow ausgeführt wird
  • Ich habe mich für ubi9/podman entschieden, weil
    • ich bei Red Hat arbeite und daher
    • mit den Prozessen zur Erstellung unserer Images vertraut bin,
    • wodurch sich ein gewisses Vertrauen gebildet hat.
    • Ich vertraue unseren Images mehr, als jenen, die irgendein Unbekannter gebaut hat und deren Inhalt ich nicht kenne (man kann den Inhalt aber selbstverständlich überprüfen)
    • und ich so prüfen konnte, ob sich ein Image mit „unseren“ Werkzeugen bauen läst (nicht, dass ich daran gezweifelt hätte).

Die Angabe von privileged: true ist erforderlich, wenn man innerhalb des Containers ebenfalls mit podman oder docker arbeiten möchte.

Entscheidungen

Meinem weiter oben abgebildeten Workflow ist zu entnehmen, dass ich auf die Verwendung von Forgejo Actions verzichtet habe. Das hat folgende Gründe:

  • Für die Verwendung ist node auf dem Runner erforderlich
  • node ist im Image ubi9/podman standardmäßig nicht installiert
  • Node.js ist für mich das Tor zur Hölle und ich vermeide dessen Nutzung wenn möglich
  • Die Nutzung ist keine Voraussetzung, da ich mein Ziel auch so ohne Mehraufwand erreicht habe

Sobald die Workflows länger und komplexer werden, mag sich meine Einstellung zu Actions ändern.

Zusammenfassung

Ich habe gelernt:

  • Forgejo Runner zu installieren und zu konfigurieren
  • Wie Forgejo Workflows funktionieren und auf Codeberg.org genutzt werden können
  • Wie ich mir damit zukünftig die Arbeit in anderen Projekten erleichtern kann
  • Was für großartige Open Source Projekte Codeberg.org und Forgejo sind
Received before yesterday
❌