Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7334bd587a | ||
|
|
0f7062b0c4 | ||
|
|
6c8f3f2d21 | ||
|
|
1eb87ecac6 | ||
|
|
64d20da165 | ||
|
|
1858bfc10f | ||
|
|
d8d768d876 |
@@ -0,0 +1,114 @@
|
|||||||
|
name: Reusable Deploy via rsync
|
||||||
|
|
||||||
|
# Wiederverwendbarer Deploy-Workflow fuer IDF-Projekte.
|
||||||
|
# Repository-Pfad: ideenfabrik/idf-ci/.gitea/workflows/deploy-rsync.yml
|
||||||
|
#
|
||||||
|
# Aufruf aus einem Caller-Repo:
|
||||||
|
#
|
||||||
|
# jobs:
|
||||||
|
# deploy:
|
||||||
|
# uses: ideenfabrik/idf-ci/.gitea/workflows/deploy-rsync.yml@v1
|
||||||
|
# with:
|
||||||
|
# ssh_host: ${{ vars.SSH_HOST }}
|
||||||
|
# ssh_user: ${{ vars.SSH_USER }}
|
||||||
|
# deploy_path: ${{ vars.DEPLOY_PATH }}
|
||||||
|
# ref: ${{ github.event.inputs.ref || github.ref }}
|
||||||
|
# extra_excludes: |
|
||||||
|
# kiosk-config.php
|
||||||
|
# kiosk-config.example.php
|
||||||
|
# secrets: inherit
|
||||||
|
#
|
||||||
|
# Caller-Repo muss hinterlegen:
|
||||||
|
# Secret SSH_PRIVATE_KEY private Key fuer den Deploy-User
|
||||||
|
# Variable SSH_HOST Host/IP des Live-Servers
|
||||||
|
# Variable SSH_USER SSH-Login-User
|
||||||
|
# Variable DEPLOY_PATH Zielpfad auf dem Server
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
ssh_host:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: 'Ziel-Host fuer rsync ueber SSH'
|
||||||
|
ssh_user:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: 'SSH-Login-User'
|
||||||
|
deploy_path:
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
description: 'Zielpfad auf dem Server'
|
||||||
|
ref:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
description: 'Branch/Tag zum Deployen (default: github.ref)'
|
||||||
|
extra_excludes:
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
default: ''
|
||||||
|
description: 'Zusaetzliche rsync --exclude Patterns, eine pro Zeile'
|
||||||
|
secrets:
|
||||||
|
SSH_PRIVATE_KEY:
|
||||||
|
required: true
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: self-hosted
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ inputs.ref || github.ref }}
|
||||||
|
|
||||||
|
- name: Verify rsync + ssh available
|
||||||
|
run: |
|
||||||
|
command -v rsync >/dev/null || { echo "::error::rsync ist auf dem Runner nicht installiert"; exit 1; }
|
||||||
|
command -v ssh >/dev/null || { echo "::error::ssh ist auf dem Runner nicht installiert"; exit 1; }
|
||||||
|
rsync --version | head -1
|
||||||
|
ssh -V
|
||||||
|
|
||||||
|
- name: Setup SSH key
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
chmod 700 ~/.ssh
|
||||||
|
KEY_FILE="$HOME/.ssh/id_ed25519_deploy_${{ github.run_id }}"
|
||||||
|
printf '%s\n' "${{ secrets.SSH_PRIVATE_KEY }}" > "$KEY_FILE"
|
||||||
|
chmod 600 "$KEY_FILE"
|
||||||
|
echo "DEPLOY_KEY_FILE=$KEY_FILE" >> "$GITHUB_ENV"
|
||||||
|
ssh-keyscan -H "${{ inputs.ssh_host }}" >> ~/.ssh/known_hosts 2>/dev/null
|
||||||
|
|
||||||
|
- name: Deploy via rsync
|
||||||
|
env:
|
||||||
|
EXTRA_EXCLUDES: ${{ inputs.extra_excludes }}
|
||||||
|
run: |
|
||||||
|
# Standard-Excludes -- gilt fuer alle Deploys
|
||||||
|
BASE_EXCLUDES=(
|
||||||
|
--exclude='.git/'
|
||||||
|
--exclude='.gitea/'
|
||||||
|
--exclude='.gitignore'
|
||||||
|
--exclude='CHANGELOG.md'
|
||||||
|
--exclude='README.md'
|
||||||
|
)
|
||||||
|
|
||||||
|
# Caller-spezifische Excludes (multiline -> array)
|
||||||
|
EXTRA=()
|
||||||
|
while IFS= read -r line; do
|
||||||
|
line="${line#"${line%%[![:space:]]*}"}"
|
||||||
|
line="${line%"${line##*[![:space:]]}"}"
|
||||||
|
[ -n "$line" ] && EXTRA+=( "--exclude=$line" )
|
||||||
|
done <<<"$EXTRA_EXCLUDES"
|
||||||
|
|
||||||
|
rsync -avz "${BASE_EXCLUDES[@]}" "${EXTRA[@]}" \
|
||||||
|
-e "ssh -i $DEPLOY_KEY_FILE -o StrictHostKeyChecking=yes" \
|
||||||
|
./ \
|
||||||
|
"${{ inputs.ssh_user }}@${{ inputs.ssh_host }}:${{ inputs.deploy_path }}/"
|
||||||
|
|
||||||
|
- name: Cleanup deploy key
|
||||||
|
if: always()
|
||||||
|
run: rm -f "$DEPLOY_KEY_FILE"
|
||||||
|
|
||||||
|
- name: Done
|
||||||
|
run: |
|
||||||
|
echo "Deployed ${{ github.ref_name }} to ${{ inputs.deploy_path }} on ${{ inputs.ssh_host }}"
|
||||||
@@ -22,6 +22,7 @@ name: Release Plugin
|
|||||||
# generiert und ist nur im fertigen ZIP vollständig.
|
# generiert und ist nur im fertigen ZIP vollständig.
|
||||||
#
|
#
|
||||||
# Trigger im aufrufenden Repo: push eines Tags der Form v<MAJOR>.<MINOR>.<PATCH>.
|
# Trigger im aufrufenden Repo: push eines Tags der Form v<MAJOR>.<MINOR>.<PATCH>.
|
||||||
|
# Ausführung auf dem IDF-Runner (self-hosted, Host-Modus).
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_call:
|
workflow_call:
|
||||||
@@ -43,7 +44,7 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
runs-on: ubuntu-latest
|
runs-on: self-hosted
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout Tag
|
- name: Checkout Tag
|
||||||
@@ -167,10 +168,11 @@ jobs:
|
|||||||
version = os.environ["VERSION"]
|
version = os.environ["VERSION"]
|
||||||
with open("CHANGELOG.md", encoding="utf-8") as f:
|
with open("CHANGELOG.md", encoding="utf-8") as f:
|
||||||
content = f.read()
|
content = f.read()
|
||||||
# "## v<version>" optional gefolgt von " — Datum" und beliebigem Suffix,
|
# "## v<version>" gefolgt von beliebigem Rest der Zeile (auch "— Datum"),
|
||||||
# Inhalt bis zum nächsten "## v<x.y.z>" oder einer "---"-Trennzeile oder EOF.
|
# Inhalt ab nächster Zeile bis zum nächsten "## v<x.y.z>" oder "---" oder EOF.
|
||||||
|
# [^\n]* statt .*, damit die erste Zeile nicht mit DOTALL bis EOF gefressen wird.
|
||||||
pat = re.compile(
|
pat = re.compile(
|
||||||
r"^##\s+v" + re.escape(version) + r"(?:\s+.*)?$\n(.*?)(?=^##\s+v\d|^---\s*$|\Z)",
|
r"^##\s+v" + re.escape(version) + r"[^\n]*\n(.*?)(?=^##\s+v\d|^---\s*$|\Z)",
|
||||||
re.MULTILINE | re.DOTALL,
|
re.MULTILINE | re.DOTALL,
|
||||||
)
|
)
|
||||||
m = pat.search(content)
|
m = pat.search(content)
|
||||||
@@ -228,9 +230,10 @@ jobs:
|
|||||||
readme_path = pathlib.Path(sys.argv[1])
|
readme_path = pathlib.Path(sys.argv[1])
|
||||||
changelog_path = pathlib.Path(sys.argv[2])
|
changelog_path = pathlib.Path(sys.argv[2])
|
||||||
|
|
||||||
# CHANGELOG.md parsen: Einträge "## v<x.y.z> — <Datum?>" bis zum nächsten "## v…" oder "---" oder EOF
|
# CHANGELOG.md parsen: Einträge "## v<x.y.z> — <Datum?>" bis zum nächsten "## v…" oder "---" oder EOF.
|
||||||
|
# [^\n]* für die erste Zeile, damit DOTALL nicht greedy über Zeilen frisst.
|
||||||
entry_pat = re.compile(
|
entry_pat = re.compile(
|
||||||
r"^##\s+v(\d+\.\d+\.\d+)(?:\s+—\s+(\S+))?(?:\s+.*)?$\n(.*?)(?=^##\s+v\d|^---\s*$|\Z)",
|
r"^##\s+v(\d+\.\d+\.\d+)(?:\s+—\s+(\S+))?[^\n]*\n(.*?)(?=^##\s+v\d|^---\s*$|\Z)",
|
||||||
re.MULTILINE | re.DOTALL,
|
re.MULTILINE | re.DOTALL,
|
||||||
)
|
)
|
||||||
content = changelog_path.read_text(encoding="utf-8")
|
content = changelog_path.read_text(encoding="utf-8")
|
||||||
|
|||||||
@@ -0,0 +1,218 @@
|
|||||||
|
# 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 <TOKEN_AUS_SCHRITT_3> \
|
||||||
|
--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<X.Y.Z>` 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.
|
||||||
Reference in New Issue
Block a user