Files
PolyTraderSharp/docs/LEITFADEN-CI.md
T
RichardandClaude Opus 5 5507db3e32 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>
2026-08-22 11:25:01 +02:00

134 lines
6.5 KiB
Markdown

# 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.