docs(ci): Front-Matter + CI-Docs + YT-Sync vorbereitet (MP-7)

This commit is contained in:
Stefan Mogeritsch 2025-10-22 11:11:10 +02:00
parent 79c9d4a71a
commit 1bdd5c38aa
13 changed files with 310 additions and 2 deletions

15
.github/pull_request_template.md vendored Normal file
View File

@ -0,0 +1,15 @@
## Ziel
Kurze Beschreibung des Ziels/Problems und was dieser PR löst.
## Änderungen
-
## Prüfliste (Definition of Done)
- [ ] CI grün (Backend/Docs)
- [ ] Doku-FrontMatter vorhanden und valide (`modul`, `status`, `summary`, optional `last_reviewed`, `review_cycle`, `yt_epic/yt_issues`)
- [ ] Links geprüft (CI LinkChecker läuft grün)
- [ ] Falls relevant: YouTrackKey im PRTitel/Commit enthalten (z. B. MP-7)
- [ ] Bei Architekturänderung: ADR aktualisiert und verlinkt
## Screenshots/Notizen (optional)
-

89
.github/workflows/ci-docs.yml vendored Normal file
View File

@ -0,0 +1,89 @@
name: CI Docs
on:
pull_request:
paths:
- 'docs/**'
- '.junie/**'
- '.github/workflows/ci-docs.yml'
- '.markdownlint.yaml'
- '.vale.ini'
push:
branches: [ main ]
paths:
- 'docs/**'
- '.junie/**'
- '.github/workflows/ci-docs.yml'
- '.markdownlint.yaml'
- '.vale.ini'
jobs:
docs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node (markdownlint)
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install markdownlint
run: npm i -g markdownlint-cli
- name: Markdownlint
run: markdownlint 'docs/**/*.md'
- name: Setup Vale
run: |
curl -fsSL https://install.goreleaser.com/github.com/errata-ai/vale.sh | sh
sudo mv bin/vale /usr/local/bin/vale
- name: Vale
run: vale docs/
- name: Link Checker
uses: lycheeverse/lychee-action@v1
with:
args: --verbose --no-progress 'docs/**/*.md'
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Front-Matter Schema Validate
run: |
pip install pyyaml jsonschema
python .junie/scripts/validate-frontmatter.py
- name: Docs Drift Check
run: bash .junie/scripts/check-docs-drift.sh
- name: Render PlantUML
run: bash .junie/scripts/render-plantuml.sh
- name: Upload diagrams artifact
uses: actions/upload-artifact@v4
with:
name: diagrams
path: build/diagrams
- name: Validate YouTrack issues exist (optional)
if: ${{ env.YT_URL != '' && env.YT_TOKEN != '' }}
run: |
set -euo pipefail
KEYS=$(grep -Rho "[A-Z]\+-[0-9]\+" docs | sort -u || true)
if [ -z "$KEYS" ]; then
echo "No YouTrack keys found in docs."
exit 0
fi
echo "Prüfe Keys:" $KEYS
fail=0
for k in $KEYS; do
code=$(curl -s -o /dev/null -w "%{http_code}" \
-H "Authorization: Bearer $YT_TOKEN" \
-H "Accept: application/json" \
"$YT_URL/api/issues/$k?fields=idReadable")
if [ "$code" != "200" ]; then
echo "[YT] Issue nicht gefunden: $k (HTTP $code)"; fail=1;
fi
done
exit $fail
env:
YT_URL: ${{ secrets.YT_URL }}
YT_TOKEN: ${{ secrets.YT_TOKEN }}

29
.github/workflows/youtrack-sync.yml vendored Normal file
View File

@ -0,0 +1,29 @@
name: YouTrack Sync (on merge)
on:
push:
branches: [ main ]
jobs:
notify:
runs-on: ubuntu-latest
steps:
- name: Comment to YouTrack Issue(s)
run: |
set -euo pipefail
KEYS=$(git log -1 --pretty=%B | grep -o '[A-Z]\+-[0-9]\+' | sort -u || true)
if [ -z "$KEYS" ]; then
echo "No issue keys in last commit message. Skipping."
exit 0
fi
for ISSUE in $KEYS; do
MSG=$(printf 'PR/Commit gemergt: %s\nRepo: %s\nCommit: %s' "${{ github.event.head_commit.url }}" "${{ github.repository }}" "${{ github.sha }}")
curl -sS -X POST \
-H "Authorization: Bearer $YT_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
"$YT_URL/api/issues/$ISSUE/comments" \
-d "{\"text\": \"$MSG\"}"
done
env:
YT_URL: ${{ secrets.YT_URL }}
YT_TOKEN: ${{ secrets.YT_TOKEN }}

View File

@ -0,0 +1,30 @@
#!/usr/bin/env bash
set -euo pipefail
err=0
has() { grep -q "$2" "$1" || { echo "[DRIFT] '$2' fehlt in $1"; err=1; }; }
miss() { grep -q "$2" "$1" && { echo "[DRIFT] Veralteter Begriff '$2' in $1"; err=1; }; }
# Quelle der Wahrheit: Spring Cloud Gateway
has docs/overview/system-overview.md "Spring Cloud Gateway"
has docs/architecture/adr/0007-api-gateway-pattern-de.md "Spring Cloud Gateway"
miss docs/architecture/adr/0007-api-gateway-pattern-de.md "Ktor"
# C4: Container muss Technology korrekt führen
has docs/architecture/c4/02-container-de.puml "Spring Cloud Gateway"
miss docs/architecture/c4/02-container-de.puml "Ktor"
# Verbiete versehentlich verbliebene englische ADR/C4 ohne -de
if ls docs/architecture/adr/*.md 2>/dev/null | grep -E -v '-de\.md$' >/dev/null; then
echo "[DRIFT] Englische ADR-Dateien ohne -de gefunden in docs/architecture/adr/"
ls docs/architecture/adr/*.md | grep -E -v '-de\.md$' || true
err=1
fi
if ls docs/architecture/c4/*.puml 2>/dev/null | grep -E -v '-de\.puml$' >/dev/null; then
echo "[DRIFT] Englische C4-Dateien ohne -de gefunden in docs/architecture/c4/"
ls docs/architecture/c4/*.puml | grep -E -v '-de\.puml$' || true
err=1
fi
exit $err

View File

@ -0,0 +1,9 @@
#!/usr/bin/env bash
set -euo pipefail
mkdir -p build/diagrams
shopt -s nullglob
for f in docs/architecture/c4/*.puml; do
docker run --rm -v "$PWD":/data plantuml/plantuml -tsvg "/data/$f" -o "/data/build/diagrams"
echo "Rendered build/diagrams/$(basename "${f%.puml}").svg"
done

View File

@ -0,0 +1,33 @@
import os, re, yaml, json
from glob import glob
try:
import jsonschema
except ImportError:
# GitHub Actions step will install this before running; provide friendlier message if missing
raise SystemExit("[FM] jsonschema package not installed. Please run: pip install jsonschema pyyaml")
SCHEMA_PATH = 'docs/.frontmatter.schema.json'
FM_REGEX = re.compile(r'^---\n(.*?)\n---', re.S)
with open(SCHEMA_PATH, encoding='utf-8') as f:
schema = json.load(f)
errors = 0
for path in glob('docs/**/*.md', recursive=True):
# Skip generated or non-content files if any (none by default)
with open(path, 'r', encoding='utf-8') as fh:
content = fh.read()
m = FM_REGEX.search(content)
if not m:
print(f"[FM] fehlt: {path}")
errors = 1
continue
try:
fm = yaml.safe_load(m.group(1)) or {}
jsonschema.validate(fm, schema)
except Exception as e:
print(f"[FM] invalid in {path}: {e}")
errors = 1
exit(errors)

View File

@ -0,0 +1,8 @@
extends: existence
message: "Veralteter Begriff: '%s'"
level: error
ignorecase: true
scope: text
nonword: true
tokens:
- Ktor

3
.markdownlint.yaml Normal file
View File

@ -0,0 +1,3 @@
default: true
MD013: false # Zeilenlänge entspannt
MD033: false # Inline-HTML erlaubt

5
.vale.ini Normal file
View File

@ -0,0 +1,5 @@
StylesPath = .junie/vale
MinAlertLevel = warning
[*.md]
BasedOnStyles = Vale, MoCode

View File

@ -0,0 +1,16 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["status", "summary"],
"properties": {
"modul": {"type": "string"},
"status": {"type": "string", "enum": ["active", "draft", "deprecated"]},
"summary": {"type": "string"},
"last_reviewed": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
"review_cycle": {"type": "string", "pattern": "^\\d+d$"},
"yt_epic": {"type": "string", "pattern": "^[A-Z]+-\\d+$"},
"yt_issues": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z]+-\\d+$"}},
"tags": {"type": "array", "items": {"type": "string"}}
},
"additionalProperties": true
}

View File

@ -1,4 +1,15 @@
# Meldestelle REST API Documentation
---
modul: api-overview
status: active
last_reviewed: 2025-10-22
review_cycle: 180d
summary: Überblick und Einstieg in die RESTAPIs der Meldestelle.
yt_epic: MP-1
yt_issues: [MP-7]
tags: [api, overview]
---
# Meldestelle RESTAPI Dokumentation
## Überblick

View File

@ -1,4 +1,15 @@
# Members API Documentation
---
modul: members-api
status: active
last_reviewed: 2025-10-22
review_cycle: 180d
summary: Dokumentation der MembersAPI (Endpunkte, Parameter, Beispiele).
yt_epic: MP-1
yt_issues: []
tags: [api, members]
---
# MembersAPI Dokumentation
## Überblick

View File

@ -0,0 +1,49 @@
---
modul: workflow-pr-branchschutz
status: active
last_reviewed: 2025-10-22
review_cycle: 180d
summary: Empfehlungen für Branchschutz, PR-Ablauf und Naming-Konventionen.
yt_epic: MP-1
yt_issues: []
---
# Branchschutz & Pull-Request Workflow
Diese Anleitung beschreibt einen einfachen, robusten Flow für `main` mit kurzen Feature-Branches und klaren Qualitätschecks.
## 1) Branch-Naming
- Feature: `feature/<kurz-beschreibung>`
- Bugfix: `fix/<kurz-beschreibung>`
- Docs: `docs/<kurz-beschreibung>`
Optional: Issue-Key voranstellen, z. B. `feature/MP-7-doku-konsolidieren`.
## 2) Pull Request (PR)
- PR-Titel nach Conventional Commits (kurz): `docs(api): FrontMatter vereinheitlicht (MP-7)`
- Beschreibung kurz mit Bulletpoints; DoD-Checkliste abhaken (Template vorhanden)
- CI muss grün sein (Backend + Docs)
## 3) Branchschutz (GitHub Einstellungen → Branches → main)
- Require a pull request before merging
- Require status checks to pass before merging
- aktivieren: `CI Docs`, `CI` (Backend falls vorhanden)
- Require linear history
- Require approvals: mindestens 1 (bei Solo-Projekt optional, aber empfohlen)
- Allow squash merging only
- Disallow force pushes, Disallow deletions
## 4) Commits & YouTrack
- Commit-Message enthält Issue-Key (z. B. `MP-7`) → erleichtert Nachverfolgung
- In Doku-FrontMatter `yt_epic`/`yt_issues` pflegen
- Optional: GitHub Secrets `YT_URL`, `YT_TOKEN` setzen → CI validiert verlinkte Issues, und `youtrack-sync.yml` kommentiert beim Merge automatisch ins Issue
## 5) Definition of Done (Auszug)
- Doku aktuell (README/ADR/C4/API)
- FrontMatter valide (`modul`, `status`, `summary`, optional `last_reviewed`, `review_cycle`, `yt_*`)
- Links funktionieren (CI link-check grün)
- Tests grün
## 6) Lokale Tipps
- Vor dem Push: `markdownlint`, `vale` lokal laufen lassen (optional via pre-commit hooks)
- kleine, häufige PRs statt großer Monster-PRs