# 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 ```bash clang-format --dry-run --Werror <datei> ``` #### Lokal automatisch formatieren ```bash clang-format -i <datei> ``` Beispiel: ```bash 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: ```text 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: ```text 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: ```bash ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_signing -C "dein.name@example.com" ``` --- ### 2. Git für SSH-Signing konfigurieren ```bash 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: ```text <principal> <public-key> ``` Beispiel: ```text 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: ```bash 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 ```bash 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 ```bash 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 ```bash clang-format -i main.cpp tests/test_main.cpp ``` ### Policy lokal ausführen ```bash python3 ci/check_pr_policies.py ``` ### Projekt lokal bauen ```bash cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug cmake --build build --parallel ctest --test-dir build --output-on-failure ``` --- ## Verhalten in Jenkins Die Jenkins-Pipeline umfasst typischerweise diese Stages: 1. **Checkout** 2. **Policy Checks** 3. **Configure** 4. **Build** 5. **Test** 6. **Cleanup** Wenn die Policy-Checks fehlschlagen, werden die späteren Build- und Test-Stages nicht mehr ausgeführt. --- ## Typische Fehlerursachen ### Formatfehler Beispiel: ```text ERROR: Formatfehler in tests/test_main.cpp ``` #### Lösung ```bash clang-format -i tests/test_main.cpp ``` --- ### Kein passender Test gefunden Beispiel: ```text 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: ```text 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_signers` eingetragen ist - Commit neu erstellen oder neu signieren --- ### `.clang-format` fehlt Beispiel: ```text ERROR: .clang-format fehlt im Repository-Root. ``` #### Lösung - `.clang-format` im Repository-Root anlegen oder wiederherstellen --- ## Empfohlener Workflow 1. Feature-Branch erstellen 2. Änderungen implementieren 3. Test ergänzen oder anpassen 4. Code formatieren 5. Commit SSH-signiert erstellen 6. lokal Policy, Build und Tests ausführen 7. pushen 8. Pull Request öffnen 9. Jenkins-Ergebnis prüfen 10. 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.py` lä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