# Gitea Actions Runner — Setup Diese Anleitung beschreibt, wie der Gitea Actions Runner auf einem IDF-Server installiert und registriert wird. Der Runner ist der Dienst, der die Release-Workflows aus diesem Repo ausführt. Ohne laufenden Runner bleiben Tag-Pushes ohne Wirkung — die Runs hängen unendlich in der Queue. **Wichtig:** Diese Anleitung ist die verbindliche SSOT für das Runner-Setup. Bei jedem Server-Wechsel wird sie von vorn abgearbeitet — es gibt keine versteckten Artefakte außerhalb von Git, nur die hier beschriebenen Schritte. ## Was der Runner ist und was er nicht ist Der Runner ist ein einzelnes ausführbares Binary (`act_runner`), das sich beim IDF-Gitea-Server anmeldet und Jobs aus der Queue abarbeitet. Er ist kein WordPress-, PHP- oder Plesk-Tool, sondern ein unabhängiger Dienst, der nebenher läuft. Technisch ist er vergleichbar mit einem Cron-Daemon, der auf Arbeit wartet. Der Runner **baut** die Plugin-ZIPs und legt sie als Gitea-Release-Assets ab. Er **verteilt** nichts an Kunden — das ist Aufgabe des Master-Key-Plugins. ## Voraussetzungen in Gitea Damit der Runner Reusable-Workflows aus `idf-ci` lesen kann, muss das Repo für ihn erreichbar sein. Der beim Job generierte Token ist nur für das aufrufende Plugin-Repo gültig und kann kein anderes privates Repo klonen. **Daher: `ideenfabrik/idf-ci` muss auf Sichtbarkeit „Public" (oder „Limited", falls in der Gitea-Version verfügbar) stehen.** - **Public** — lesbar für alle, die die Gitea-Instanz erreichen. - **Limited** — lesbar für alle eingeloggten Gitea-User. In neueren Gitea-Versionen verfügbar. Für unseren Fall äquivalent zu Public, weil der Runner eh mit Token angemeldet ist. - **Private** — funktioniert nicht, weil der Job-Token keinen Repo-übergreifenden Lesezugriff hat. **Zusätzlich:** Gitea-weite Einstellung `REQUIRE_SIGNIN_VIEW` muss auf `false` stehen. Sonst überschreibt sie die per-Repo-Sichtbarkeit und erzwingt Login auch für Public-Repos. Bei Docker-Setups wird die `app.ini` oft aus Environment-Variablen regeneriert — Änderungen direkt in der Datei gehen beim Container-Neustart verloren. Korrekter Weg: Environment-Variable setzen: ``` GITEA__service__REQUIRE_SIGNIN_VIEW=false ``` Je nach Setup in der `docker-compose.yml`, im systemd-Unit oder in der Plesk-Gitea-Extension. Container neu starten. ### Ist das ein Sicherheitsproblem? Das Risiko ist niedrig, weil das Repo ausschließlich CI-Baustoff enthält: - Keine Access-Tokens, API-Keys oder Passwörter (Secrets werden zur Laufzeit injiziert, nie committet) - Keine Plugin-Quellcodes, keine Business-Logik, keine Kundendaten - Kein Zugriff auf Produktions-Systeme Öffentlich lesbar sind nur: der Release-Workflow (Bau-Logik), die Doku und das Caller-Template. Standard-CI-Praxis, wie bei vielen Open-Source-Projekten. Falls der Gitea-Server aus dem Internet erreichbar ist, bedeutet „Public" tatsächlich weltweit lesbar. Ist der Gitea-Server nur intern/VPN-gebunden erreichbar, ist „Public" effektiv identisch mit „intern lesbar". Im Zweifel: Sichtbarkeit auf „Limited" setzen, dann muss man wenigstens angemeldet sein, um zu lesen. ### Umstellung der Repo-Sichtbarkeit 1. Repo öffnen: https://git.ihre-ideenfabrik.de/ideenfabrik/idf-ci 2. Settings → ganz runterscrollen → „Danger Zone" 3. **Change Visibility** → Public (oder Limited, falls verfügbar) 4. Bestätigen Einmalige Aktion pro Instanz. ## Voraussetzungen auf dem Server - Linux (Debian/Ubuntu; der IDF-Plesk-Host reicht) - Outbound-HTTPS zu `git.ihre-ideenfabrik.de` und zu `github.com` (für standard Gitea-/GitHub-Actions wie `actions/checkout`) - **Node.js 20 (LTS) oder neuer** — zahlreiche Actions (`actions/checkout`, viele weitere) sind JavaScript-basiert und benötigen Node zur Ausführung. Installation (Debian/Ubuntu): ```bash curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash - sudo apt install -y nodejs ``` Prüfen: `node --version` (mindestens `v20.x`). - Standard-Tools verfügbar: `bash`, `python3`, `zip`, `unzip`, `rsync`, `curl`, `jq`, `git` Falls einzelne Tools fehlen: `sudo apt install -y python3 zip unzip rsync curl jq git` - systemd (Standard bei Debian/Ubuntu) - Root-Shell-Zugang ## Installation ### 1. Binary herunterladen Aktuelle stabile Version (beim Schreiben dieser Doku: `v0.2.11`) von https://gitea.com/gitea/act_runner/releases holen: ```bash sudo mkdir -p /opt/act_runner cd /opt/act_runner sudo curl -L -o act_runner \ https://gitea.com/gitea/act_runner/releases/download/v0.2.11/act_runner-0.2.11-linux-amd64 sudo chmod +x act_runner ``` Architektur-Variante: bei ARM-Servern `linux-arm64` statt `linux-amd64` wählen. ### 2. Konfigurationsdatei erzeugen und Labels eintragen ```bash sudo ./act_runner generate-config | sudo tee config.yaml > /dev/null ``` **Wichtig:** `act_runner` akzeptiert Labels **nur aus der Config**, nicht als CLI-Flag beim Registrieren. Die Default-Labels zeigen auf Docker-Images, die wir nicht brauchen. Ersetze sie durch Host-Modus-Labels: ```bash sudo nano /opt/act_runner/config.yaml ``` Im Block `runner:` den vorhandenen `labels:`-Block **vollständig ersetzen** durch: ```yaml labels: - "self-hosted:host" - "linux:host" - "x64:host" ``` Suffix `:host` = Jobs laufen direkt auf dem Host, ohne Docker. Damit sparen wir uns Docker als weitere Abhängigkeit. Speichern und verlassen. Andere Default-Werte in `config.yaml` können bleiben. Bei Bedarf später anpassen: `runner.capacity` für parallele Jobs (Default 1 ist für den Anfang ok). ### 3. Registrierungstoken in Gitea holen Organisation-scoped Runner (empfohlen, läuft für alle IDF-Repos): 1. In Gitea einloggen als Admin. 2. Navigation: Organization **ideenfabrik** → Settings → **Actions** → **Runners**. 3. Button **„Create new Runner"**. 4. Registrierungstoken kopieren. Token ist einmalig — für eine zweite Registrierung einen neuen generieren. Alternativ: Instance-weit unter Site Administration → Actions → Runners (dann verfügbar für alle Organisationen). ### 4. Runner registrieren ```bash sudo /opt/act_runner/act_runner register \ --config /opt/act_runner/config.yaml \ --instance https://git.ihre-ideenfabrik.de \ --token \ --name idf-plesk-runner \ --no-interactive ``` Kein `--labels`-Flag — die Labels kommen aus der Config (siehe Schritt 2). Falls versehentlich mitgegeben, erscheint die Warnung `Labels from command will be ignored, use labels defined in config file.` Nach erfolgreicher Registrierung liegt eine Datei `.runner` im Arbeitsverzeichnis — die ist der Runner-State, nicht weiterkopieren oder committen. ### 5. systemd-Service anlegen ```bash sudo tee /etc/systemd/system/act_runner.service > /dev/null <<'EOF' [Unit] Description=Gitea Actions Runner (IDF) After=network.target [Service] Type=simple WorkingDirectory=/opt/act_runner ExecStart=/opt/act_runner/act_runner daemon --config /opt/act_runner/config.yaml Restart=always RestartSec=5 User=root Group=root [Install] WantedBy=multi-user.target EOF sudo systemctl daemon-reload sudo systemctl enable act_runner sudo systemctl start act_runner ``` ### 6. Verifikation ```bash sudo systemctl status act_runner ``` Erwartete Zeile: `Active: active (running)`. In Gitea prüfen: 1. Organization **ideenfabrik** → Settings → **Actions** → **Runners**. 2. Der neue Runner taucht mit Status **Online** auf. 3. In der Labels-Spalte müssen `self-hosted`, `linux`, `x64` stehen. Wenn stattdessen `ubuntu-latest` o. Ä. dort stehen, wurde ohne die Labels aus Schritt 2 registriert → Schritt 2 prüfen und bei Runs-Hängen neu registrieren (siehe Troubleshooting). ### 7. Pilot-Test Einen Plugin-Repo mit Caller-Workflow nehmen (z. B. `idf-post-prefix`), Tag `v` pushen, unter **Actions** im Repo prüfen, ob der Run durchläuft. Bei Erfolg entsteht ein Gitea-Release mit ZIP-Asset. ## Laufender Betrieb - **Logs:** `sudo journalctl -u act_runner -f` (tail-folgen) oder `journalctl -u act_runner --since '1 hour ago'`. - **Runner-Update:** neues `act_runner`-Binary herunterladen, ersetzen, `sudo systemctl restart act_runner`. - **Label-Änderung:** Labels in `config.yaml` anpassen, Service neu starten (`sudo systemctl restart act_runner`). Der Daemon sendet die aktualisierten Labels beim nächsten Handshake an Gitea. - **Neu-Registrierung (z. B. nach kaputtem State):** `sudo rm /opt/act_runner/.runner`, neuen Token aus Gitea holen, Schritt 4 erneut ausführen, Service neu starten. - **Deregistrierung:** Runner in Gitea-UI löschen, `.runner`-Datei auf dem Server entfernen, Service stoppen. ## Server-Wechsel — Checkliste Wenn der IDF-Server gewechselt wird (neuer Plesk-Host o. ä.): 1. Diese Anleitung auf dem neuen Server von Schritt 1 an durchlaufen. 2. In Schritt 3 einen **neuen** Registrierungstoken erzeugen — alte Tokens nicht wiederverwenden. 3. Optional: den alten Runner in der Gitea-UI deaktivieren, damit er nicht doppelt zieht. 4. Nach Verifikation (Schritt 6 + 7): alte Server-Installation zurückbauen. Damit ist das komplette Build-System portabel: die Bauanleitung lebt in diesem Repo (`release-plugin.yml`), der Runner wird pro Server neu aufgesetzt nach genau dieser Anleitung. Keine versteckten Scripts außerhalb von Git. ## Troubleshooting **Warnung `Labels from command will be ignored` beim Registrieren.** Du hast `--labels …` als CLI-Flag gesetzt, aber `act_runner` nimmt Labels nur aus der Config. Schritt 2 durchgehen, Labels in `config.yaml` eintragen. Dann `sudo rm /opt/act_runner/.runner`, neuen Token holen, Registrierung ohne `--labels`-Flag erneut ausführen. **Run bricht ab mit `Unable to clone … authentication required`.** Entweder `idf-ci` steht auf Private, oder Gitea-weit ist `REQUIRE_SIGNIN_VIEW = true` aktiv. Abschnitt „Voraussetzungen in Gitea" durchgehen. Bei Docker-Setup die Environment-Variable `GITEA__service__REQUIRE_SIGNIN_VIEW=false` setzen und Container neu starten. Danach den Run über den Re-run-Button in der Gitea-Actions-UI neu starten. **Run bricht ab mit `Cannot find: node in PATH`.** Node.js ist nicht installiert oder nicht im PATH. Abschnitt „Voraussetzungen auf dem Server" durchgehen und Node 20 LTS installieren. Nach `sudo apt install -y nodejs` läuft der nächste Re-run. **Runs hängen auf `queued`, Runner steht aber auf Online.** Label-Mismatch. Der Workflow schreibt `runs-on: self-hosted`, der Runner muss dasselbe Label anbieten. In der Gitea-UI die Labels des Runners prüfen — stehen dort nicht `self-hosted, linux, x64`, liegt es an Schritt 2. **Runner zeigt `offline` nach systemd-Start.** `sudo journalctl -u act_runner --since '5 min ago'` lesen. Häufige Ursachen: Token abgelaufen, DNS funktioniert nicht, `git.ihre-ideenfabrik.de` nicht erreichbar. **Pre-Flight-Check im Workflow schlägt fehl mit „Tool nicht gefunden".** Das System-Paket fehlt auf dem Host. `sudo apt install -y python3 zip unzip rsync curl jq git` nachinstallieren. **Release-Anlage schlägt fehl mit 401/403.** `secrets: inherit` im Caller-Workflow prüfen und sicherstellen, dass der Runner vom Repo aus `GITEA_TOKEN` bzw. `github.token` bekommt. Alternativ Access-Token als Secret im Repo/Org setzen.