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>
160 lines
6.1 KiB
YAML
160 lines
6.1 KiB
YAML
name: CI
|
|
|
|
# Wozu diese CI da ist:
|
|
# PolyTrader läuft künftig auf einem Linux-Server. Der plattformneutrale Zustand ist am
|
|
# 22.08.2026 mühsam hergestellt worden (WinForms-Ausbau) und driftet ohne Wächter wieder weg —
|
|
# eine einzige `net10.0-windows`-Zeile oder ein `using System.Drawing` genügt, und der
|
|
# Linux-Build ist still kaputt. Genau das fängt der "guard"-Job ab, und zwar auf Linux,
|
|
# nicht auf einer Windows-Entwicklermaschine, auf der es zufällig weiter baut.
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
pull_request:
|
|
branches: [main]
|
|
workflow_dispatch:
|
|
|
|
env:
|
|
DOTNET_NOLOGO: "true"
|
|
DOTNET_CLI_TELEMETRY_OPTOUT: "true"
|
|
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "true"
|
|
|
|
jobs:
|
|
|
|
build-test:
|
|
name: Build & Tests (Linux)
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Quellcode holen
|
|
uses: actions/checkout@v4
|
|
|
|
- name: .NET SDK einrichten
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: '10.0.x'
|
|
|
|
- name: Pakete wiederherstellen
|
|
# Der lokale Feed lib/nuget (Deploymentcenter.Client) ist in NuGet.Config relativ
|
|
# eingebunden und liegt im Repo - hier ist also nichts zusätzlich einzurichten.
|
|
run: dotnet restore PolyTraderSharp.sln
|
|
|
|
- name: Bauen
|
|
run: dotnet build PolyTraderSharp.sln --configuration Release --no-restore
|
|
|
|
- name: Tests
|
|
run: dotnet test tests/PolyTrader.Tests/PolyTrader.Tests.csproj --configuration Release --no-build --verbosity normal
|
|
|
|
- name: Linux-Publish (Nachweis der Lauffähigkeit)
|
|
# Kein Selbstzweck: hier fällt auf, wenn ein Paket doch windows-only ist.
|
|
run: dotnet publish src/PolyTrader.App.Avalonia/PolyTrader.App.Avalonia.csproj --configuration Release --runtime linux-x64 --self-contained false --output ./artifacts/linux-x64
|
|
|
|
- name: Publish-Ergebnis prüfen
|
|
run: |
|
|
set -e
|
|
cd ./artifacts/linux-x64
|
|
for f in PolyTrader.App.Avalonia PolyTrader.App.Avalonia.dll appsettings.json setup.json; do
|
|
if [ ! -f "$f" ]; then
|
|
echo "FEHLER: '$f' fehlt im Linux-Publish."
|
|
exit 1
|
|
fi
|
|
done
|
|
# Die nativen Skia-/HarfBuzz-Bibliotheken müssen die Linux-Fassung sein.
|
|
if ! ls libSkiaSharp.so >/dev/null 2>&1; then
|
|
echo "FEHLER: libSkiaSharp.so fehlt - Avalonia wäre auf Linux nicht lauffähig."
|
|
exit 1
|
|
fi
|
|
echo "Linux-Publish vollständig ($(ls | wc -l) Dateien)."
|
|
|
|
guard:
|
|
name: Plattformneutralität & Hygiene
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Quellcode holen
|
|
uses: actions/checkout@v4
|
|
|
|
- name: .NET SDK einrichten
|
|
uses: actions/setup-dotnet@v4
|
|
with:
|
|
dotnet-version: '10.0.x'
|
|
|
|
- name: Keine windows-spezifischen Zielframeworks
|
|
run: |
|
|
set -e
|
|
treffer=$(grep -rn -E "<TargetFrameworks?>[^<]*-windows" --include="*.csproj" . || true)
|
|
if [ -n "$treffer" ]; then
|
|
echo "FEHLER: windows-spezifisches Zielframework gefunden:"
|
|
echo "$treffer"
|
|
echo ""
|
|
echo "PolyTrader ist seit dem 22.08.2026 plattformneutral. Siehe docs/PROJEKTSTAND.md."
|
|
exit 1
|
|
fi
|
|
echo "OK - alle Projekte sind plattformneutral."
|
|
|
|
- name: Kein WinForms/WPF
|
|
run: |
|
|
set -e
|
|
treffer=$(grep -rn -E "<(UseWindowsForms|UseWPF)>\s*true" --include="*.csproj" . || true)
|
|
if [ -n "$treffer" ]; then
|
|
echo "FEHLER: WinForms/WPF wurde wieder eingeschaltet:"
|
|
echo "$treffer"
|
|
exit 1
|
|
fi
|
|
echo "OK - kein WinForms/WPF."
|
|
|
|
- name: Keine windows-only Namespaces im Code
|
|
run: |
|
|
set -e
|
|
# Nur echte using-Direktiven, keine Kommentare - die erklären im Bestand
|
|
# bewusst, WARUM etwas nicht verwendet wird.
|
|
treffer=$(grep -rn -E "^\s*using\s+System\.(Windows\.Forms|Drawing)\s*;" --include="*.cs" src/ tests/ || true)
|
|
if [ -n "$treffer" ]; then
|
|
echo "FEHLER: windows-only Namespace eingebunden:"
|
|
echo "$treffer"
|
|
echo ""
|
|
echo "System.Drawing.Common ist seit .NET 7 Windows-only und wirft auf Linux."
|
|
exit 1
|
|
fi
|
|
echo "OK - keine windows-only Namespaces."
|
|
|
|
- name: Keine Secret-Dateien versioniert
|
|
run: |
|
|
set -e
|
|
# Diese Dateien enthalten echte Zugangsdaten und gehören nie ins Repo.
|
|
# packager.config.json trägt FTP-Passwort und updateservice:publish-Token.
|
|
verboten="deploy/packager.config.json appsettings.Local.json master.key openrouter.key .gitea-token server_settings.xml"
|
|
fehler=0
|
|
for f in $verboten; do
|
|
if git ls-files --error-unmatch "$f" >/dev/null 2>&1; then
|
|
echo "FEHLER: '$f' ist versioniert - enthält Zugangsdaten."
|
|
fehler=1
|
|
fi
|
|
done
|
|
# Zusätzlich: Deploymentcenter-Tokens im Klartext irgendwo in versionierten Dateien.
|
|
# Die Plandokumente kürzen Tokens bewusst mit "…" ab, echte sind 40+ Zeichen.
|
|
if git grep -nE "dc_(sub|master)_[0-9a-f]{40,}" -- . >/dev/null 2>&1; then
|
|
echo "FEHLER: Deploymentcenter-Token im Klartext gefunden:"
|
|
git grep -nE "dc_(sub|master)_[0-9a-f]{40,}" -- .
|
|
fehler=1
|
|
fi
|
|
if [ "$fehler" -ne 0 ]; then
|
|
echo ""
|
|
echo "Diese Dateien gehören in .gitignore, nicht ins Repo."
|
|
exit 1
|
|
fi
|
|
echo "OK - keine Secret-Dateien versioniert."
|
|
|
|
- name: Pakete auf bekannte Schwachstellen prüfen
|
|
# Punkt 1 der wiederkehrenden Audit-Checkliste aus docs/sicherheit/SICHERHEITSKONZEPT.md.
|
|
# Läuft ab jetzt bei jedem Push statt nur quartalsweise von Hand.
|
|
run: |
|
|
set -e
|
|
dotnet restore PolyTraderSharp.sln
|
|
ausgabe=$(dotnet list PolyTraderSharp.sln package --vulnerable --include-transitive)
|
|
echo "$ausgabe"
|
|
if echo "$ausgabe" | grep -qE "^\s+>\s"; then
|
|
echo ""
|
|
echo "FEHLER: anfällige Pakete gefunden (siehe oben)."
|
|
exit 1
|
|
fi
|
|
echo "OK - keine anfälligen Pakete."
|