CI fuer Gitea Actions: Build und Tests auf Linux plus Waechter gegen Rueckfaelle
Die Plattformneutralitaet war nach dem WinForms-Ausbau eine Momentaufnahme: eine einzige net10.0-windows-Zeile oder ein "using System.Drawing" genuegt, und der Linux-Build ist kaputt, ohne dass es auf einer Windows-Maschine auffaellt - dort baut es weiter. Genau das faengt die CI ab, und zwar auf Linux. .gitea/workflows/ci.yml, zwei Jobs auf ubuntu-latest: - build-test: restore, build, die 476 Tests (brauchen keine DB, laufen gegen EF-InMemory), Linux-Publish. Der Publish ist kein Selbstzweck - dort faellt auf, wenn ein Paket doch windows-only ist. Anschliessend wird geprueft, dass die Executable, appsettings.json, setup.json und libSkiaSharp.so wirklich im Ergebnis liegen. - guard: keine windows-TFMs, kein UseWindowsForms/UseWPF, keine windows-only using-Direktiven, keine versionierten Secret-Dateien, keine anfaelligen Pakete. Alle Waechter sind in beide Richtungen gegengeprueft: sie schlagen bei simulierten Regressionen an (windows-TFM, UseWindowsForms, using System.Drawing, getrackte packager.config.json samt dc_sub_-Token, Newtonsoft 11.0.2) und schweigen beim Ist-Zustand. Die Namespace-Pruefung trifft bewusst nur echte using-Direktiven: im Bestand steht an vielen Stellen erklaert, WARUM System.Drawing nicht verwendet wird, und das darf keinen Fehlalarm ausloesen. Der Schwachstellen-Check ist Punkt 1 der wiederkehrenden Audit-Checkliste aus dem Sicherheitskonzept - laeuft ab jetzt bei jedem Push statt quartalsweise von Hand. Er wuerde zum Beispiel anschlagen, wenn der Newtonsoft-Pin im Core faellt. Bewusst kein -warnaserror: die 15 vorhandenen Warnungen muessten erst weg, sonst ist die CI ab dem ersten Tag rot und wird ignoriert. WICHTIG - die CI laeuft noch nicht: auf der Gitea-Instanz ist kein Actions-Runner registriert (auf Repo-, Benutzer- und Instanzebene geprueft, ueberall 0). has_actions ist true, es fehlt nur der Runner. Einrichtung Schritt fuer Schritt in docs/LEITFADEN-CI.md Abschnitt 3. .gitattributes neu: erzwingt LF fuer .yml/.sh/.service. Entwickelt wird mit autocrlf=true auf Windows, ausgefuehrt auf Linux - ein Shell-Skript mit CRLF scheitert dort mit irrefuehrenden Meldungen. Bisher gab es keine .gitattributes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
# Leitfaden: Continuous Integration
|
||||
|
||||
**Stand: 22.08.2026** · Workflow: [`.gitea/workflows/ci.yml`](../.gitea/workflows/ci.yml)
|
||||
|
||||
> **Status: Der Workflow liegt, der Runner fehlt noch.** Gitea 1.26.2 hat Actions aktiviert
|
||||
> (`has_actions: true`), aber auf der Instanz ist **kein einziger Runner registriert** — geprüft
|
||||
> auf Repo-, Benutzer- und Instanzebene. Bis Abschnitt 3 erledigt ist, passiert bei einem Push
|
||||
> nichts. Der Workflow ist dann sofort lauffähig, ohne weitere Änderung.
|
||||
|
||||
---
|
||||
|
||||
## 1. Warum überhaupt
|
||||
|
||||
PolyTrader soll auf einem Linux-Server laufen. Der plattformneutrale Zustand wurde am
|
||||
22.08.2026 mit dem WinForms-Ausbau hergestellt — und er **driftet ohne Wächter wieder weg**.
|
||||
Eine einzige `net10.0-windows`-Zeile oder ein `using System.Drawing` genügt, und der
|
||||
Linux-Build ist kaputt, ohne dass es auf einer Windows-Entwicklermaschine auffällt: dort baut
|
||||
es weiter.
|
||||
|
||||
Genau deshalb läuft die CI **auf Linux**. Sie ist kein Selbstzweck, sondern die einzige
|
||||
Instanz, die den mühsam hergestellten Zustand verteidigt.
|
||||
|
||||
## 2. Was geprüft wird
|
||||
|
||||
Zwei Jobs, beide auf `ubuntu-latest`:
|
||||
|
||||
### `build-test` — Build & Tests
|
||||
|
||||
| Schritt | Zweck |
|
||||
|---|---|
|
||||
| `dotnet restore` | Der lokale Feed `lib/nuget` (Deploymentcenter-SDK) ist relativ eingebunden und liegt im Repo — nichts einzurichten |
|
||||
| `dotnet build -c Release` | Baut alle 7 Projekte |
|
||||
| `dotnet test` | Die 476 Tests. Brauchen **keine Datenbank** — sie laufen gegen EF-InMemory |
|
||||
| `dotnet publish -r linux-x64` | Kein Selbstzweck: hier fällt auf, wenn ein Paket doch windows-only ist |
|
||||
| Publish-Prüfung | Erwartet `PolyTrader.App.Avalonia`, `appsettings.json`, `setup.json` und `libSkiaSharp.so` — ohne die native Skia-Bibliothek wäre Avalonia auf Linux nicht lauffähig |
|
||||
|
||||
### `guard` — Plattformneutralität & Hygiene
|
||||
|
||||
| Prüfung | Schlägt fehl bei |
|
||||
|---|---|
|
||||
| Zielframeworks | irgendeinem `<TargetFramework>…-windows` in einer `.csproj` |
|
||||
| WinForms/WPF | `<UseWindowsForms>true` oder `<UseWPF>true` |
|
||||
| Namespaces | echten `using System.Windows.Forms;` / `using System.Drawing;`-Direktiven in `src/` oder `tests/` |
|
||||
| Secret-Dateien | `deploy/packager.config.json`, `appsettings.Local.json`, `master.key`, `openrouter.key`, `.gitea-token` oder `server_settings.xml` **versioniert**; oder einem Deploymentcenter-Token im Klartext |
|
||||
| Schwachstellen | `dotnet list package --vulnerable --include-transitive` findet etwas |
|
||||
|
||||
**Zur Namespace-Prüfung:** Sie trifft bewusst nur echte `using`-Direktiven, keine Kommentare.
|
||||
Im Bestand steht an vielen Stellen erklärt, *warum* `System.Drawing` nicht verwendet wird —
|
||||
das darf keinen Fehlalarm auslösen. Beide Richtungen sind gegengeprüft.
|
||||
|
||||
**Zum Schwachstellen-Check:** Das ist Punkt 1 der wiederkehrenden Audit-Checkliste aus
|
||||
[`sicherheit/SICHERHEITSKONZEPT.md`](./sicherheit/SICHERHEITSKONZEPT.md) — läuft ab jetzt bei
|
||||
jedem Push statt quartalsweise von Hand. Er würde zum Beispiel anschlagen, wenn der
|
||||
`Newtonsoft.Json`-Pin im Core entfernt wird: Nethereum 6.1.0 löst dann transitiv auf 11.0.2
|
||||
auf (GHSA-5crp-9r3c-p9vr, Schweregrad hoch).
|
||||
|
||||
> Die Warnungen des Builds (aktuell 15) lassen die CI **nicht** fehlschlagen. `-warnaserror`
|
||||
> wäre hier verfrüht: die vorhandenen Warnungen müssten erst abgearbeitet werden, sonst ist
|
||||
> die CI ab dem ersten Tag rot und wird ignoriert.
|
||||
|
||||
## 3. Runner einrichten (einmalig)
|
||||
|
||||
Ohne Runner führt Gitea den Workflow nicht aus. Der Runner ist ein eigenes Programm
|
||||
(`act_runner`), das sich beim Gitea-Server meldet und Jobs abholt. Er läuft sinnvollerweise
|
||||
**auf dem Gitea-Host** (`192.168.178.10`) oder jeder anderen Maschine im selben Netz, die
|
||||
Docker hat.
|
||||
|
||||
### 3.1 Registrierungstoken holen
|
||||
|
||||
In der Weboberfläche: **Repo → Einstellungen → Actions → Runner → „Runner erstellen"**.
|
||||
Dort steht ein Token der Form `…`. Alternativ instanzweit unter
|
||||
**Website-Verwaltung → Actions → Runner**, wenn der Runner mehreren Repos dienen soll —
|
||||
für den Anfang genügt der Repo-Runner.
|
||||
|
||||
### 3.2 Runner per Docker starten
|
||||
|
||||
```bash
|
||||
docker run -d --restart always \
|
||||
--name gitea-runner \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v /opt/gitea-runner:/data \
|
||||
-e GITEA_INSTANCE_URL=http://192.168.178.10:8418 \
|
||||
-e GITEA_RUNNER_REGISTRATION_TOKEN=<TOKEN_AUS_3.1> \
|
||||
-e GITEA_RUNNER_NAME=polytrader-runner \
|
||||
-e GITEA_RUNNER_LABELS=ubuntu-latest:docker://catthehacker/ubuntu:act-latest \
|
||||
gitea/act_runner:latest
|
||||
```
|
||||
|
||||
**Das `GITEA_RUNNER_LABELS`-Feld ist der kritische Teil.** Es bildet `runs-on: ubuntu-latest`
|
||||
aus dem Workflow auf ein Container-Image ab. Fehlt das Label, bleibt der Job auf
|
||||
„warten auf Runner" stehen, ohne Fehlermeldung. Das Image `catthehacker/ubuntu:act-latest`
|
||||
bringt Node mit, das `actions/checkout` und `actions/setup-dotnet` benötigen.
|
||||
|
||||
Der Mount von `docker.sock` ist nötig, weil der Runner die Job-Container selbst startet.
|
||||
|
||||
### 3.3 Prüfen
|
||||
|
||||
```bash
|
||||
curl -s -H "Authorization: token $(cat ~/.gitea-token)" http://192.168.178.10:8418/api/v1/repos/Richard/PolyTraderSharp/actions/runners
|
||||
```
|
||||
|
||||
Steht dort `"total_count": 0`, hat sich der Runner nicht registriert — dann in die Logs sehen:
|
||||
`docker logs gitea-runner`.
|
||||
|
||||
Danach den Workflow von Hand anstoßen: **Repo → Actions → CI → „Run workflow"**
|
||||
(`workflow_dispatch` ist im Workflow vorgesehen). Der erste Lauf dauert länger, weil das
|
||||
.NET-SDK heruntergeladen wird.
|
||||
|
||||
## 4. Wenn kein Internetzugang besteht
|
||||
|
||||
`actions/setup-dotnet` lädt das SDK von Microsoft. Ist der Runner offline, gibt es zwei Wege:
|
||||
|
||||
1. **Container-Image mit SDK** statt `setup-dotnet` — im Workflow je Job ergänzen:
|
||||
```yaml
|
||||
container:
|
||||
image: mcr.microsoft.com/dotnet/sdk:10.0
|
||||
```
|
||||
Dann muss das `setup-dotnet`-Steps-Paar entfallen. **Achtung:** Dieses Image bringt kein
|
||||
Node mit; `actions/checkout` braucht es. Entweder ein eigenes Image bauen
|
||||
(`dotnet/sdk:10.0` + `nodejs`) oder auschecken per `git clone` statt per Action.
|
||||
2. **SDK im Runner-Image vorinstallieren** und `setup-dotnet` weglassen.
|
||||
|
||||
Weg 1 mit eigenem Image ist der sauberere, sobald das Netz wirklich zu ist.
|
||||
|
||||
## 5. Was die CI (noch) nicht tut
|
||||
|
||||
- **Kein Deployment.** Die Auslieferung läuft über den Deploymentcenter-Packager
|
||||
(`deploy/packager.config.json`, siehe Schnitt D-4). Das bewusst nicht automatisiert, solange
|
||||
die Live-Abnahme aussteht.
|
||||
- **Keine Integrationstests gegen eine echte MySQL.** Die Testsuite läuft gegen EF-InMemory.
|
||||
Ein MySQL-Service-Container wäre der nächste sinnvolle Ausbauschritt, wenn die
|
||||
Repository-Schicht einmal gegen echtes SQL geprüft werden soll.
|
||||
- **Kein `-warnaserror`.** Siehe Kasten in Abschnitt 2.
|
||||
Reference in New Issue
Block a user