Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0a5abbb1ee | ||
|
|
9e1f6007ca | ||
|
|
40d825e6dd | ||
|
|
c661f4393e |
No files matched your search
@@ -1,231 +1,6 @@
|
|||||||
# sandbox
|
# sandbox
|
||||||
|
|
||||||
Test- und Beispiel-Repository für einen lokalen Dev-Platform-Stack mit:
|
jenkins testing repobranch protection test
|
||||||
|
|
||||||
- **Gitea 1.22.x**
|
|
||||||
- **Jenkins Multibranch Pipeline**
|
|
||||||
- **Webhook-Trigger von Gitea nach Jenkins**
|
|
||||||
- **C++/CMake/Ninja Build**
|
|
||||||
- **PR Policy Checks**
|
|
||||||
- **Docker-basiertem CI-Agent**
|
|
||||||
|
|
||||||
---
|
branch main protection test
|
||||||
|
|
||||||
## Aktueller Funktionsumfang
|
|
||||||
|
|
||||||
Dieses Repository und das zugehörige Jenkins/Gitea-Setup können aktuell:
|
|
||||||
|
|
||||||
### SCM / Repository
|
|
||||||
- Repository in **Gitea** hosten
|
|
||||||
- Änderungen per **Git Push** empfangen
|
|
||||||
- **Pull Requests** in Gitea verwalten
|
|
||||||
- Webhooks von Gitea an Jenkins senden
|
|
||||||
|
|
||||||
### Jenkins / CI
|
|
||||||
- Jenkins als **Multibranch Pipeline** verwenden
|
|
||||||
- Branches und Pull Requests automatisch erkennen
|
|
||||||
- Builds durch **Push Events** automatisch starten
|
|
||||||
- Build-Status an Gitea zurückmelden
|
|
||||||
|
|
||||||
### Build-Umgebung
|
|
||||||
- Pipeline-Schritte in einem **Docker-Container** ausführen
|
|
||||||
- dafür ein vorbereitetes CI-Image verwenden
|
|
||||||
- folgende Tools im CI bereitstellen:
|
|
||||||
- `python3`
|
|
||||||
- `clang-format`
|
|
||||||
- `cmake`
|
|
||||||
- `ninja`
|
|
||||||
- `git`
|
|
||||||
- `g++`
|
|
||||||
- `make`
|
|
||||||
|
|
||||||
### C++ Projektbasis
|
|
||||||
- minimales Beispielprogramm über `main.cpp`
|
|
||||||
- Build mit **CMake**
|
|
||||||
- Testausführung über **CTest**
|
|
||||||
- Testdateien unter `tests/`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Repository-Struktur
|
|
||||||
|
|
||||||
```text
|
|
||||||
.
|
|
||||||
├── .clang-format
|
|
||||||
├── CMakeLists.txt
|
|
||||||
├── Dockerfile.ci
|
|
||||||
├── Jenkinsfile
|
|
||||||
├── README.md
|
|
||||||
├── ci/
|
|
||||||
│ └── check_pr_policies.py
|
|
||||||
├── main.cpp
|
|
||||||
└── tests/
|
|
||||||
└── test_main.cpp
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## CI / Jenkins Pipeline
|
|
||||||
|
|
||||||
Die Jenkins-Pipeline umfasst aktuell diese Schritte:
|
|
||||||
|
|
||||||
1. **Checkout**
|
|
||||||
- Repository aus Gitea auschecken
|
|
||||||
- zusätzliche Fetch-/Submodule-Schritte ausführen
|
|
||||||
|
|
||||||
2. **Policy Checks**
|
|
||||||
- `ci/check_pr_policies.py` ausführen
|
|
||||||
- Formatierung und Testbezug prüfen
|
|
||||||
|
|
||||||
3. **Configure**
|
|
||||||
- CMake-Buildverzeichnis erzeugen
|
|
||||||
|
|
||||||
4. **Build**
|
|
||||||
- Projekt mit CMake/Ninja bauen
|
|
||||||
|
|
||||||
5. **Test**
|
|
||||||
- Tests über `ctest` ausführen
|
|
||||||
|
|
||||||
6. **Cleanup**
|
|
||||||
- Workspace am Ende bereinigen
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## PR Policy Checks
|
|
||||||
|
|
||||||
Für geänderte C/C++-Dateien werden in der CI folgende Regeln geprüft:
|
|
||||||
|
|
||||||
- `.clang-format` muss im Repository vorhanden sein
|
|
||||||
- geänderte C/C++-Dateien müssen mit `clang-format` konform sein
|
|
||||||
- zu geänderten C/C++-Dateien muss ein passender Test unter `tests/` oder `test/` vorhanden sein
|
|
||||||
|
|
||||||
### Vergleichsbasis der Policy
|
|
||||||
|
|
||||||
Die Policy unterscheidet zwischen Pull-Request-Builds und normalen Branch-Builds:
|
|
||||||
|
|
||||||
- **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
|
|
||||||
|
|
||||||
Damit funktioniert die Policy sowohl in PR-Builds als auch bei regulären Branch-Indexing- oder Branch-Build-Läufen.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Docker-basierter CI-Agent
|
|
||||||
|
|
||||||
Die Pipeline verwendet ein vorbereitetes Docker-Image statt bei jedem Lauf ein neues Build-Image zu erzeugen.
|
|
||||||
|
|
||||||
### Beispiel
|
|
||||||
Das Image wird lokal oder auf dem Build-Host gebaut:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
docker build -t lifemaps/ci-cpp:latest -f Dockerfile.ci .
|
|
||||||
```
|
|
||||||
|
|
||||||
Danach nutzt Jenkins dieses Image als Build-Agent.
|
|
||||||
|
|
||||||
### Vorteile
|
|
||||||
- schnellere PR-Builds
|
|
||||||
- reproduzierbare Toolchain
|
|
||||||
- keine langen `apt install`-Phasen pro Build
|
|
||||||
- saubere Trennung zwischen Jenkins-Controller und Build-Umgebung
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Branch- und PR-Workflow
|
|
||||||
|
|
||||||
Der aktuelle Workflow unterstützt:
|
|
||||||
|
|
||||||
- Arbeiten auf Feature-Branches
|
|
||||||
- Öffnen von Pull Requests gegen `main`
|
|
||||||
- automatisches Bauen von PRs
|
|
||||||
- Rückmeldung des Build-Status an Gitea
|
|
||||||
|
|
||||||
Empfohlen ist:
|
|
||||||
|
|
||||||
- keine direkten Änderungen auf `main`
|
|
||||||
- Änderungen über Feature-Branch + Pull Request
|
|
||||||
- Merge erst nach erfolgreichem CI-Lauf
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Lokales Arbeiten
|
|
||||||
|
|
||||||
### Formatierung prüfen
|
|
||||||
```bash
|
|
||||||
clang-format --dry-run --Werror main.cpp tests/test_main.cpp
|
|
||||||
```
|
|
||||||
|
|
||||||
### Formatierung anwenden
|
|
||||||
```bash
|
|
||||||
clang-format -i main.cpp tests/test_main.cpp
|
|
||||||
```
|
|
||||||
|
|
||||||
### CI-Policy lokal testen
|
|
||||||
```bash
|
|
||||||
python3 ci/check_pr_policies.py
|
|
||||||
```
|
|
||||||
|
|
||||||
### Build lokal ausführen
|
|
||||||
```bash
|
|
||||||
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Debug
|
|
||||||
cmake --build build --parallel
|
|
||||||
ctest --test-dir build --output-on-failure
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Voraussetzungen auf Jenkins-Seite
|
|
||||||
|
|
||||||
Für das Setup werden u. a. folgende Jenkins-Plugins benötigt:
|
|
||||||
|
|
||||||
- `docker-workflow`
|
|
||||||
- `pipeline-model-definition`
|
|
||||||
- `workflow-scm-step`
|
|
||||||
- `workflow-cps`
|
|
||||||
- `ws-cleanup`
|
|
||||||
- `gitea`
|
|
||||||
- `git`
|
|
||||||
- `git-client`
|
|
||||||
- `scm-api`
|
|
||||||
- `workflow-multibranch`
|
|
||||||
|
|
||||||
Zusätzlich muss der Jenkins-Container Zugriff auf Docker haben, z. B. über:
|
|
||||||
|
|
||||||
- Docker CLI im Jenkins-Container
|
|
||||||
- Mount von `/var/run/docker.sock`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Webhook / Automatischer Trigger
|
|
||||||
|
|
||||||
Gitea ist so konfiguriert, dass **Push Events** an Jenkins gemeldet werden.
|
|
||||||
|
|
||||||
Beispiel-Endpunkt:
|
|
||||||
|
|
||||||
```text
|
|
||||||
https://jenkins.life-maps.com/gitea-webhook/post
|
|
||||||
```
|
|
||||||
|
|
||||||
Damit können automatisch Jenkins-Builds für Branches und Pull Requests ausgelöst werden.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Beispielziel des Repositories
|
|
||||||
|
|
||||||
Dieses Repository dient aktuell als:
|
|
||||||
|
|
||||||
- Referenz für Jenkins/Gitea-Integration
|
|
||||||
- Testumgebung für PR-Policies
|
|
||||||
- Minimalbeispiel für C++/CMake-basierte CI
|
|
||||||
- Grundlage für weitere CI- und Policy-Erweiterungen
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## Status
|
|
||||||
|
|
||||||
Aktuell ist das Setup geeignet für:
|
|
||||||
|
|
||||||
- Jenkins/Gitea-Webhook-Integration
|
|
||||||
- Pull-Request-basierte CI
|
|
||||||
- C++/CMake/Ninja Beispielprojekte
|
|
||||||
- Policy-basierte Qualitätsprüfungen im PR-Prozess
|
|
||||||
+5
-22
@@ -34,10 +34,7 @@ def git_ref_exists(ref: str) -> bool:
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def is_pull_request_build() -> bool:
|
def resolve_target_ref() -> str:
|
||||||
return bool(os.environ.get("CHANGE_ID"))
|
|
||||||
|
|
||||||
def resolve_target_ref() -> str | None:
|
|
||||||
raw = os.environ.get("CHANGE_TARGET", "").strip()
|
raw = os.environ.get("CHANGE_TARGET", "").strip()
|
||||||
|
|
||||||
candidates = []
|
candidates = []
|
||||||
@@ -55,27 +52,13 @@ def resolve_target_ref() -> str | None:
|
|||||||
if git_ref_exists(ref):
|
if git_ref_exists(ref):
|
||||||
return ref
|
return ref
|
||||||
|
|
||||||
return None
|
print("ERROR: Kein gültiger Ziel-Branch-Ref gefunden. Geprüft:", ", ".join(candidates))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
def changed_files():
|
def changed_files():
|
||||||
target = resolve_target_ref()
|
target = resolve_target_ref()
|
||||||
|
print(f"Vergleiche gegen Ziel-Ref: {target}")
|
||||||
if target:
|
out = run(f"git diff --name-only {target}...HEAD")
|
||||||
print(f"Vergleiche gegen Ziel-Ref: {target}")
|
|
||||||
out = run(f"git diff --name-only {target}...HEAD")
|
|
||||||
return [line.strip() for line in out.splitlines() if line.strip()]
|
|
||||||
|
|
||||||
if is_pull_request_build():
|
|
||||||
print("ERROR: Kein gültiger Ziel-Branch-Ref für PR-Build gefunden.")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
if git_ref_exists("HEAD~1"):
|
|
||||||
print("Kein Ziel-Branch-Ref gefunden, verwende HEAD~1 für Branch-Build.")
|
|
||||||
out = run("git diff --name-only HEAD~1..HEAD")
|
|
||||||
return [line.strip() for line in out.splitlines() if line.strip()]
|
|
||||||
|
|
||||||
print("Keine Vergleichsbasis gefunden, behandle alle versionierten Dateien als geändert.")
|
|
||||||
out = run("git ls-files")
|
|
||||||
return [line.strip() for line in out.splitlines() if line.strip()]
|
return [line.strip() for line in out.splitlines() if line.strip()]
|
||||||
|
|
||||||
def is_cpp_file(path: Path) -> bool:
|
def is_cpp_file(path: Path) -> bool:
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
hook test Di 4. Aug 00:08:29 CEST 2026
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
should fail
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
push-hook-test Di 4. Aug 00:11:58 CEST 2026
|
||||||
Reference in new issue
Block a user