{"id":4127,"date":"2025-05-12T07:00:00","date_gmt":"2025-05-12T05:00:00","guid":{"rendered":"https:\/\/www.my-it-brain.de\/wordpress\/?p=4127"},"modified":"2025-05-09T20:07:54","modified_gmt":"2025-05-09T18:07:54","slug":"codeberg-org-mit-forgejo-actions-runner-workflows-und-ich","status":"publish","type":"post","link":"https:\/\/www.my-it-brain.de\/wordpress\/codeberg-org-mit-forgejo-actions-runner-workflows-und-ich\/","title":{"rendered":"Codeberg.org mit Forgejo Actions, Runner, Workflows und ich"},"content":{"rendered":"\n<p>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\u00e4hrend Fragen nach dem Wie vorwiegend in den Verweisen im Text beantwortet werden.<\/p>\n\n\n\n<p>Der Artikel dient mir als Dokumentation und meinen Leser:innen zur Unterhaltung und zum Wissenstransfer.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Codeberg.org<\/h2>\n\n\n\n<p><a href=\"https:\/\/docs.codeberg.org\/getting-started\/what-is-codeberg\/\">Codeberg<\/a> ist eine demokratische, gemeinschaftsgetriebene, gemeinn\u00fctzige Softwareentwicklungsplattform, die von <a href=\"https:\/\/docs.codeberg.org\/getting-started\/what-is-codeberg\/#what-is-codeberg-e.v.%3F\">Codeberg e.V.<\/a> betrieben wird und sich um <a href=\"https:\/\/codeberg.org\">Codeberg.org<\/a>, eine auf <a href=\"https:\/\/forgejo.org\/\">Forgejo<\/a> basierende Software, dreht. Der Sitz des Vereins ist in Berlin. <a href=\"https:\/\/docs.codeberg.org\/getting-started\/faq\/#where-is-codeberg-hosted%3F\">Hier wird Codeberg.org auch gehosted<\/a>.<\/p>\n\n\n\n<p>Auf Codeberg k\u00f6nnt ihr eure eigenen Freie Software-Projekte entwickeln, zu anderen Projekten beitragen, inspirierende und n\u00fctzliche Freie Software durchst\u00f6bern, euer Wissen teilen oder euren Projekten mit Codeberg Pages ein Zuhause im Web geben, um nur einige Beispiele zu nennen.<\/p>\n\n\n\n<p><em>Die beiden vorstehenden Abschnitte wurden \u00fcbersetzt mit DeepL.com (kostenlose Version) und anschlie\u00dfend leicht angepasst und mit Links angereichert.<\/em><\/p>\n\n\n\n<p>Mit Codeberg.org werden keine kommerziellen Interessen verfolgt. Man ist hier (nur) Nutzer und\/oder Unterst\u00fctzer, jedoch nicht selbst ein Produkt. Mir gef\u00e4llt die <a href=\"https:\/\/docs.codeberg.org\/getting-started\/what-is-codeberg\/#our-mission\">Mission<\/a> des Projekts. Daher bin ich dazu \u00fcbergegangen, <a href=\"https:\/\/codeberg.org\/Tronde?tab=repositories\">einen Teil meiner Repositories<\/a> hier zu verwalten. Zwar bin ich kein Mitglied des Vereins, unterst\u00fctze diesen jedoch durch gelegentliche Spenden.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Actions, Runner und Workflows<\/h2>\n\n\n\n<p>Plattformen wie Codeberg.org, GitHub und GitLab unterst\u00fctzen Softwareentwicklungsprozesse durch <a href=\"https:\/\/de.wikipedia.org\/wiki\/CI\/CD\">CI\/CD<\/a>-Funktionalit\u00e4t.<\/p>\n\n\n\n<p>Ein <a href=\"https:\/\/forgejo.org\/docs\/latest\/admin\/runner-installation\/\">Forgejo-Runner<\/a> ist ein Dienst, der Workflows von einer Forgejo-Instanz abruft, sie ausf\u00fchrt, mit den Protokollen zur\u00fccksendet und schlie\u00dflich den Erfolg oder Misserfolg meldet.<\/p>\n\n\n\n<p>Dabei ist ein Workflow in der Forgejo-Terminologie eine <a href=\"https:\/\/de.wikipedia.org\/wiki\/YAML\">YAML<\/a>-Datei im Verzeichnis <code>.forgejo\/workflows<\/code> eines Repositories. Workflows umfassen einen oder mehrere <em>Jobs<\/em>, die wiederum aus einem oder mehreren <em>Steps<\/em> bestehen. Eine Action ist eine Funktion zur Erf\u00fcllung h\u00e4ufig ben\u00f6tigter Aufgaben, bspw. Quelltext auschecken, oder sich bei einer Container-Registry einloggen etc. Siehe f\u00fcr weitere Informationen <a href=\"https:\/\/forgejo.org\/docs\/v7.0\/user\/actions\/#hierarchy\">Abschnitt Hierarchy ff.<\/a> im <a href=\"https:\/\/forgejo.org\/docs\/v7.0\/user\/actions\/#top\">Forgejo Actions user guide<\/a>.<\/p>\n\n\n\n<p>Motiviert, meinen eigenen Forgejo-Runner zu installieren, haben mich zwei Blog-Artikel von meinem Arbeitskollegen <a href=\"https:\/\/jan.wildeboer.net\/about\/\">Jan Wildeboer<\/a>:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/jan.wildeboer.net\/2024\/08\/Running-a-runner-codeberg\/\">Running a runner for codeberg\/forgejo on RHEL9 as user<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/jan.wildeboer.net\/2024\/08\/be-a-builder-decentralisation\/\">Be a Builder of Decentralisation &#8211; codeberg, forgejo, runners<\/a><\/li>\n<\/ul>\n\n\n\n<p>Durch den Betrieb eigener Forgejo-Runner kann ich bereits vorhandene Rechenkapazit\u00e4t nutzen. Es fallen f\u00fcr mich und den Verein Codeberg e.V. dadurch keine zus\u00e4tzlichen Kosten an. F\u00fcr die Installation auf RHEL 9 bin ich dem <a href=\"https:\/\/forgejo.org\/docs\/latest\/admin\/runner-installation\/\">Forgejo Runner installation guide<\/a> gefolgt, da das in Jans Artikel erw\u00e4hnte Repository <code>ne0l\/forgejo<\/code> offensichtlich nicht mehr gepflegt wird und nur eine veraltete Version des Runner enth\u00e4lt.<\/p>\n\n\n\n<p>Ein Dankesch\u00f6n geht raus an Jan f\u00fcr unseren kurzen und produktiven Austausch dazu auf Mastodon.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wozu das Ganze?<\/h2>\n\n\n\n<p>Ich besch\u00e4ftige mich beruflich seit einiger Zeit mit dem <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/einfuehrung-in-den-rhel-image-mode\/\" data-type=\"post\" data-id=\"4032\">RHEL image mode<\/a> und m\u00f6chte demn\u00e4chst einen meiner KVM-<a href=\"https:\/\/de.wikipedia.org\/wiki\/Hypervisor\">Hypervisor<\/a> damit betreiben. Bis es soweit ist, arbeite ich eine Weile im \u201eJugend forscht\u201c-Modus und baue immer wieder neue Versionen meiner Container-Images. Der Ablauf ist dabei stets derselbe:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><code>Containerfile(5)<\/code> erstellen bzw. anpassen<\/li>\n\n\n\n<li>Container-Image mit <a href=\"https:\/\/docs.podman.io\/en\/latest\/markdown\/podman-build.1.html\">podman-build<\/a> erstellen<\/li>\n\n\n\n<li>Das erstellte Image mit <a href=\"https:\/\/docs.podman.io\/en\/latest\/markdown\/podman-push.1.html\">podman-push<\/a> in eine Container-Registry hochladen<\/li>\n\n\n\n<li>Das Deployment auf diversen Zielsystemen testen<\/li>\n<\/ol>\n\n\n\n<p>Dazu verwende ich das <a href=\"https:\/\/catalog.redhat.com\/software\/containers\/rhel9\/rhel-bootc\/6605573d4dbfe41c3d839c69\">RHEL 9 Bootc Base Image<\/a> aus der Registry <code>registry.redhat.io<\/code>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>The <code>rhel-bootc<\/code> and user-created containers based on <code>rhel-bootc<\/code> container image are subject to the <a href=\"https:\/\/www.redhat.com\/en\/about\/eulas\">Red Hat Enterprise Linux end user license agreement (EULA)<\/a>. You are not allowed to publicly redistribute these images.<\/p>\n<cite>Quelle: <a href=\"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\">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<\/a><\/cite><\/blockquote>\n\n\n\n<p>Um vorstehender Anforderung gerecht zu werden, speichere ich das erzeugte Container-Image in einem privaten Repository auf <a href=\"https:\/\/quay.io\">Quay.io<\/a>. Sowohl f\u00fcr <code>registry.redhat.io<\/code> als auch f\u00fcr <code>quay.io<\/code> ist ein Login erforderlich, bevor es losgehen kann.<\/p>\n\n\n\n<p>F\u00fcr 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.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Forgejo Workflow und Runner-Konfiguration<\/h2>\n\n\n\n<p>Im folgenden Codeblock findet ihr meinen Forgejo Workflow aus der Datei <code>.forgejo\/workflows\/build_image.yaml<\/code>, gefolgt von einer Beschreibung der einzelnen Schritte. Zur Erkl\u00e4rung der Begriffe <em>name, on, env, jobs, steps, run<\/em>, etc. siehe <a href=\"https:\/\/forgejo.org\/docs\/v7.0\/user\/actions\/#workflow-reference-guide\">Workflow reference guide<\/a>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>name: build_image\n\non:\n  push:\n    branches: main\n\nenv:\n  REPO_URL: https:\/\/codeberg.org\/Tronde\/rhel-bootc.git\n  REPO_NAME: rhel-bootc\n  IMAGE_NAME: quay.io\/rhn-support-jkastnin\/rhel-bootc:9.5\n\njobs:\n  build:\n    runs-on: podman\n    steps:\n      - run: dnf -y install git\n      - run: echo ${{ secrets.RH_REGISTRY_TOKEN }} | podman login -u ${{ secrets.RH_REGISTRY_USERNAME }} --password-stdin registry.redhat.io\n\n      - run: echo ${{ secrets.QUAY_ROBOT_TOKEN }} | podman login -u ${{ secrets.QUAY_USERNAME }} --password-stdin quay.io\n\n      - run: git clone ${{ env.REPO_URL }}\n      - run: podman build -f \/workspace\/Tronde\/rhel-bootc\/rhel-bootc\/Containerfile -t ${{ env.IMAGE_NAME }}\n      - run: podman push ${{ env.IMAGE_NAME }}<\/code><\/pre>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Der Workflow wird jedes Mal ausgef\u00fchrt, wenn ich einen Commit in den Branch <code>main<\/code> pushe<\/li>\n\n\n\n<li>Ich definiere einige Umgebungsvariablen, um bei \u00c4nderungen nicht alle Schritte im Workflow einzeln auf notwendige \u00c4nderungen pr\u00fcfen zu m\u00fcssen<\/li>\n\n\n\n<li>Mit `runs-on: podman` bestimme ich, dass der Workflow auf einem Runner mit dem Label <code>podman<\/code> ausgef\u00fchrt wird; der entsprechende Runner started dann einen rootless Podman-Container, in dem die folgenden Schritte innerhalb von rootful Podman ausgef\u00fchrt werden (nested Podman bzw. Podman in Podman)<\/li>\n\n\n\n<li>Git wird installiert<\/li>\n\n\n\n<li>Anmeldung an <code>registry.redhat.io<\/code> erfolgt<\/li>\n\n\n\n<li>Anmeldung an <code>quay.io<\/code> erfolgt<\/li>\n\n\n\n<li>Das Git-Repository wird geklont, um es auf dem Runner verf\u00fcgbar zu haben<\/li>\n\n\n\n<li>Der Runner baut ein Container-Image (Erinnerung an mich selbst: Ersetze den hardcodierten Pfad durch eine Variable)<\/li>\n\n\n\n<li>Das erstellte Image wird in die Registry gepusht<\/li>\n<\/ol>\n\n\n\n<p>Damit mein Runner den obigen Workflow ausf\u00fchren kann, existiert auf diesem die Konfigurationsdatei <code>\/etc\/forgejo-runner\/config.yml<\/code>, welche ich mit dem Kommando <code>forgejo-runner generate-config &gt; config.yml<\/code> erstellt und anschlie\u00dfend angepasst habe. Der folgende Codeblock zeigt nur die Abschnitte, die ich manuell angepasst habe.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\u2026\n  fetch_interval: 20s\n\u2026\n  labels: &#91;\n    \"rhel-9-ubi:docker:\/\/registry.access.redhat.com\/ubi9\/ubi\",\n    \"podman:docker:\/\/registry.access.redhat.com\/ubi9\/podman\",\n    \"ubuntu-latest:docker:\/\/ghcr.io\/catthehacker\/ubuntu:act-latest\",\n    \"act-runner:docker:\/\/node:20-bullseye\",\n    \"centos-stream-9:docker:\/\/quay.io\/centos\/centos:stream9\"]\n\u2026\n  privileged: true\n\u2026<\/code><\/pre>\n\n\n\n<p>Ich greife mal die Zeile <code>podman:docker:\/\/registry.access.redhat.com\/ubi9\/podman<\/code> heraus:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>podman:<\/code> am Beginn der Zeile beinhaltet das Label, welches im Worflow mit <code>runs-on<\/code> verwendet wird<\/li>\n\n\n\n<li>Mit dem Rest der Zeile wird bestimmt, in welchem Container-Image der Workflow ausgef\u00fchrt wird<\/li>\n\n\n\n<li>Ich habe mich f\u00fcr <code>ubi9\/podman<\/code> entschieden, weil\n<ul class=\"wp-block-list\">\n<li>ich bei Red Hat arbeite und daher<\/li>\n\n\n\n<li>mit den Prozessen zur Erstellung unserer Images vertraut bin,<\/li>\n\n\n\n<li>wodurch sich ein gewisses Vertrauen gebildet hat.<\/li>\n\n\n\n<li>Ich vertraue unseren Images mehr, als jenen, die irgendein Unbekannter gebaut hat und deren Inhalt ich nicht kenne (man kann den Inhalt aber selbstverst\u00e4ndlich \u00fcberpr\u00fcfen)<\/li>\n\n\n\n<li>und ich so pr\u00fcfen konnte, ob sich ein Image mit \u201eunseren\u201c Werkzeugen bauen l\u00e4st (nicht, dass ich daran gezweifelt h\u00e4tte).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Die Angabe von <code>privileged: true<\/code> ist erforderlich, wenn man innerhalb des Containers ebenfalls mit <code>podman<\/code> oder <code>docker<\/code> arbeiten m\u00f6chte.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Entscheidungen<\/h2>\n\n\n\n<p>Meinem weiter oben abgebildeten Workflow ist zu entnehmen, dass ich auf die Verwendung von Forgejo Actions verzichtet habe. Das hat folgende Gr\u00fcnde:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>F\u00fcr die Verwendung ist <code>node<\/code> auf dem Runner erforderlich<\/li>\n\n\n\n<li><code>node<\/code> ist im Image <code>ubi9\/podman<\/code> standardm\u00e4\u00dfig nicht installiert<\/li>\n\n\n\n<li><a href=\"https:\/\/de.wikipedia.org\/wiki\/Node.js\">Node.js<\/a> ist f\u00fcr mich das Tor zur H\u00f6lle und ich vermeide dessen Nutzung wenn m\u00f6glich<\/li>\n\n\n\n<li>Die Nutzung ist keine Voraussetzung, da ich mein Ziel auch so ohne Mehraufwand erreicht habe<\/li>\n<\/ul>\n\n\n\n<p>Sobald die Workflows l\u00e4nger und komplexer werden, mag sich meine Einstellung zu Actions \u00e4ndern.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Zusammenfassung<\/h2>\n\n\n\n<p>Ich habe gelernt:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Forgejo Runner zu installieren und zu konfigurieren<\/li>\n\n\n\n<li>Wie Forgejo Workflows funktionieren und auf Codeberg.org genutzt werden k\u00f6nnen<\/li>\n\n\n\n<li>Wie ich mir damit zuk\u00fcnftig die Arbeit in anderen Projekten erleichtern kann<\/li>\n\n\n\n<li>Was f\u00fcr gro\u00dfartige Open Source Projekte <a href=\"https:\/\/codeberg.org\">Codeberg.org<\/a> und <a href=\"https:\/\/forgejo.org\">Forgejo<\/a> sind<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>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\u00e4hrend Fragen nach dem Wie vorwiegend in den Verweisen im Text beantwortet werden. Der Artikel dient mir als Dokumentation und meinen<span class=\"continue-reading\"> <a href=\"https:\/\/www.my-it-brain.de\/wordpress\/codeberg-org-mit-forgejo-actions-runner-workflows-und-ich\/\">[Weiterlesen&#8230;]<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_metis_text_type":"standard","_metis_text_length":8859,"_post_count":0,"footnotes":""},"categories":[1],"tags":[667,881,430,305,883,882],"class_list":["post-4127","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-codeberg","tag-forgejo","tag-osbn","tag-planet","tag-runner","tag-workflow"],"public_identification_id":"a371d3c28b3d49e48d12f80c3ef3e99d","private_identification_id":"ac2952562e7048338745c6d29ca72236","_links":{"self":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/4127","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/comments?post=4127"}],"version-history":[{"count":5,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/4127\/revisions"}],"predecessor-version":[{"id":4133,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/posts\/4127\/revisions\/4133"}],"wp:attachment":[{"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/media?parent=4127"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/categories?post=4127"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.my-it-brain.de\/wordpress\/wp-json\/wp\/v2\/tags?post=4127"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}