docs(ci): Front-Matter + CI-Docs + YT-Sync vorbereitet (MP-7)
This commit is contained in:
parent
79c9d4a71a
commit
1bdd5c38aa
15
.github/pull_request_template.md
vendored
Normal file
15
.github/pull_request_template.md
vendored
Normal 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-Front‑Matter vorhanden und valide (`modul`, `status`, `summary`, optional `last_reviewed`, `review_cycle`, `yt_epic/yt_issues`)
|
||||
- [ ] Links geprüft (CI Link‑Checker läuft grün)
|
||||
- [ ] Falls relevant: YouTrack‑Key im PR‑Titel/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
89
.github/workflows/ci-docs.yml
vendored
Normal 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
29
.github/workflows/youtrack-sync.yml
vendored
Normal 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 }}
|
||||
30
.junie/scripts/check-docs-drift.sh
Normal file
30
.junie/scripts/check-docs-drift.sh
Normal 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
|
||||
9
.junie/scripts/render-plantuml.sh
Normal file
9
.junie/scripts/render-plantuml.sh
Normal 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
|
||||
33
.junie/scripts/validate-frontmatter.py
Normal file
33
.junie/scripts/validate-frontmatter.py
Normal 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)
|
||||
8
.junie/vale/MoCode/ForbiddenTerms.yml
Normal file
8
.junie/vale/MoCode/ForbiddenTerms.yml
Normal 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
3
.markdownlint.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
default: true
|
||||
MD013: false # Zeilenlänge entspannt
|
||||
MD033: false # Inline-HTML erlaubt
|
||||
5
.vale.ini
Normal file
5
.vale.ini
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
StylesPath = .junie/vale
|
||||
MinAlertLevel = warning
|
||||
|
||||
[*.md]
|
||||
BasedOnStyles = Vale, MoCode
|
||||
16
docs/.frontmatter.schema.json
Normal file
16
docs/.frontmatter.schema.json
Normal 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
|
||||
}
|
||||
|
|
@ -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 REST‑APIs der Meldestelle.
|
||||
yt_epic: MP-1
|
||||
yt_issues: [MP-7]
|
||||
tags: [api, overview]
|
||||
---
|
||||
|
||||
# Meldestelle – REST‑API Dokumentation
|
||||
|
||||
## Überblick
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,15 @@
|
|||
# Members API Documentation
|
||||
---
|
||||
modul: members-api
|
||||
status: active
|
||||
last_reviewed: 2025-10-22
|
||||
review_cycle: 180d
|
||||
summary: Dokumentation der Members‑API (Endpunkte, Parameter, Beispiele).
|
||||
yt_epic: MP-1
|
||||
yt_issues: []
|
||||
tags: [api, members]
|
||||
---
|
||||
|
||||
# Members‑API – Dokumentation
|
||||
|
||||
## Überblick
|
||||
|
||||
|
|
|
|||
49
docs/how-to/branchschutz-und-pr-workflow.md
Normal file
49
docs/how-to/branchschutz-und-pr-workflow.md
Normal 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): Front‑Matter 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-Front‑Matter `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)
|
||||
- Front‑Matter 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
|
||||
Loading…
Reference in New Issue
Block a user