7.1 KiB
Entwicklerhinweise: Anforderungen bei Push und Pull Request
Dieses Repository verwendet Jenkins-basierte PR- und Branch-Policies.
Ziel ist, dass Code bereits vor dem Merge bestimmte Qualitätsanforderungen erfüllt.
Diese Datei beschreibt, was bei einem Push erwartet wird, was in Jenkins geprüft wird und wie du Fehler lokal vermeiden kannst.
Überblick
Bei Pushes und Pull Requests werden automatisierte Policies ausgeführt.
Je nach Build-Typ gelten leicht unterschiedliche Vergleichsregeln:
- bei Pull Requests wird gegen den Zielbranch verglichen, z. B.
origin/main - bei normalen Branch-Builds wird auf eine lokale Vergleichsbasis zurückgefallen, z. B.
HEAD~1, falls kein Zielbranch-Ref verfügbar ist
Die eigentlichen Qualitätsanforderungen bleiben gleich.
Was beim Push / PR geprüft wird
1. .clang-format muss vorhanden sein
Im Repository-Root muss eine Datei .clang-format liegen.
Ohne diese Datei schlägt der Policy-Check fehl.
2. Geänderte C/C++-Dateien müssen korrekt formatiert sein
Für geänderte C/C++-Dateien wird clang-format geprüft.
Betroffen sind insbesondere Dateien mit diesen Endungen:
.c.cc.cpp.cxx.h.hh.hpp.hxx
Wenn eine Datei nicht korrekt formatiert ist, schlägt der Build fehl.
Lokal prüfen
clang-format --dry-run --Werror <datei>
Lokal automatisch formatieren
clang-format -i <datei>
Beispiel:
clang-format -i main.cpp tests/test_main.cpp
3. Zu geänderten C/C++-Dateien muss ein passender Test existieren
Wenn du eine C/C++-Datei änderst, muss ein passender Test vorhanden sein.
Es wird nach Tests in diesen Verzeichnissen gesucht:
tests/test/qt6-after/qt6-migrated-benchmark/tests/
Unterstützte typische Testnamen sind zum Beispiel:
test_<name>.cpp<name>_test.cpp<name>test.cpp<name>gtest.cpp
Zusätzlich erkennt die Policy auch ähnliche Dateinamen heuristisch, solange test oder gtest im Dateinamen vorkommt.
Beispiel
Wenn du main.cpp änderst, ist z. B. passend:
tests/test_main.cpp
Wenn kein passender Test gefunden wird, schlägt der Build fehl.
4. Nur gültig SSH-signierte Commits sind erlaubt
Neue Commits im geprüften Bereich müssen gültig mit SSH signiert sein.
Die Jenkins-Policy prüft Commit-Signaturen gegen eine erlaubte Signiererdatei:
ci/allowed_signers
Wenn ein Commit:
- nicht signiert ist
- nicht per SSH signiert ist
- mit einem nicht erlaubten SSH-Schlüssel signiert ist
dann schlägt der Build fehl.
SSH-signierte Commits einrichten
1. SSH-Signing-Key erzeugen
Falls du noch keinen dedizierten Signing-Key hast:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_signing -C "dein.name@example.com"
2. Git für SSH-Signing konfigurieren
git config --global gpg.format ssh
git config --global user.signingkey ~/.ssh/id_ed25519_signing.pub
git config --global commit.gpgsign true
Damit werden neue Commits automatisch mit deinem SSH-Key signiert.
3. Öffentlichen Schlüssel zur Allowlist hinzufügen
Dein öffentlicher Schlüssel muss in ci/allowed_signers eingetragen sein.
Format:
<principal> <public-key>
Beispiel:
max.mustermann@example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
Ohne Eintrag in ci/allowed_signers wird dein signierter Commit in Jenkins trotzdem abgelehnt.
4. Optional: lokale Verifikation aktivieren
Wenn du lokal dieselbe Vertrauenskette wie Jenkins verwenden willst:
mkdir -p ~/.config/git
cp ci/allowed_signers ~/.config/git/allowed_signers
git config --global gpg.ssh.allowedSignersFile ~/.config/git/allowed_signers
5. Signierten Commit erstellen
git add .
git commit -S -m "Meine Änderung"
git push
Wenn commit.gpgsign=true gesetzt ist, signiert Git Commits in der Regel automatisch.
6. Signatur lokal prüfen
git log --show-signature -1
git verify-commit HEAD
Lokaler Minimal-Check vor dem Push
Vor dem Push solltest du mindestens diese Schritte ausführen:
Format anwenden
clang-format -i main.cpp tests/test_main.cpp
Policy lokal ausführen
python3 ci/check_pr_policies.py
Projekt lokal im CI-Container bauen
Zuerst das lokale CI-Image bauen:
docker build -t lifemaps/ci-cpp:latest -f Dockerfile.ci .
Danach das Projekt im Container bauen und testen:
docker run --rm -it \
-v "$PWD:/workspace" \
-w /workspace \
lifemaps/ci-cpp:latest \
bash -lc '
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug &&
cmake --build build --parallel &&
ctest --test-dir build --output-on-failure
'
Damit wird dieselbe Toolchain verwendet wie in der Jenkins-CI.
Policy-Check lokal im CI-Container ausführen
docker run --rm -it \
-v "$PWD:/workspace" \
-w /workspace \
lifemaps/ci-cpp:latest \
bash -lc 'python3 ci/check_pr_policies.py'
Verhalten in Jenkins
Die Jenkins-Pipeline umfasst typischerweise diese Stages:
- Checkout
- Policy Checks
- Configure
- Build
- Test
- Cleanup
Wenn die Policy-Checks fehlschlagen, werden die späteren Build- und Test-Stages nicht mehr ausgeführt.
Typische Fehlerursachen
Formatfehler
Beispiel:
ERROR: Formatfehler in tests/test_main.cpp
Lösung
clang-format -i tests/test_main.cpp
Kein passender Test gefunden
Beispiel:
ERROR: Kein passender Test unter tests/, test/ oder qt6-after/qt6-migrated-benchmark/tests für main.cpp gefunden.
Lösung
- passenden Test anlegen
- Testdatei passend benennen
- Test in einem der erlaubten Testverzeichnisse ablegen
Commit nicht gültig SSH-signiert
Beispiel:
ERROR: Commit ist nicht gültig mit erlaubtem SSH-Signierer signiert: <sha>
Lösung
- SSH-Signing lokal korrekt konfigurieren
- prüfen, ob der richtige Schlüssel verwendet wird
- prüfen, ob der öffentliche Schlüssel in
ci/allowed_signerseingetragen ist - Commit neu erstellen oder neu signieren
.clang-format fehlt
Beispiel:
ERROR: .clang-format fehlt im Repository-Root.
Lösung
.clang-formatim Repository-Root anlegen oder wiederherstellen
Empfohlener Workflow
- Feature-Branch erstellen
- Änderungen implementieren
- Test ergänzen oder anpassen
- Code formatieren
- Commit SSH-signiert erstellen
- lokal Policy, Build und Tests ausführen
- pushen
- Pull Request öffnen
- Jenkins-Ergebnis prüfen
- erst bei grünem Status mergen
Kurz-Checkliste vor jedem Push
- C/C++-Dateien sind formatiert
- passender Test existiert
- Commit ist SSH-signiert
- öffentlicher Schlüssel steht in
ci/allowed_signers python3 ci/check_pr_policies.pyläuft erfolgreich- Build und Tests laufen lokal
Ziel der Regeln
Die Policies sollen sicherstellen, dass:
- Code konsistent formatiert ist
- Änderungen nachvollziehbar getestet sind
- nur autorisierte Signierer Commits einbringen
- PRs frühzeitig automatisiert validiert werden