feat: Project Manual + CM-/RM-Plan + Landing-Page
Validate / build-test (macos-latest) (push) Failing after 2s
Validate / build-test (windows-latest) (push) Failing after 15s
Validate / build-test (ubuntu-latest) (push) Failing after 15s
Validate / reports (push) Has been skipped
Release / release (push) Successful in 57s
Validate / build-test (macos-latest) (push) Failing after 2s
Validate / build-test (windows-latest) (push) Failing after 15s
Validate / build-test (ubuntu-latest) (push) Failing after 15s
Validate / reports (push) Has been skipped
Release / release (push) Successful in 57s
3 neue Plaene: - Project Manual: Master-Wegweiser fuer neue Projektmitglieder, Lese-Reihenfolge, Rollen, Lebenszyklus, Dokumenten-Landschaft - Configuration Management Plan: CIs, Baselines, Change Control, Release-Prozess, Aufbewahrungsfristen (ASPICE SUP.8) - Risk Management Plan: Projekt-Risiken (abgegrenzt von HARA), Klassifikations-Skala, Risiko-Register, Eskalations-Pfad Landing-Page (Startseite): - tools/generate_landing_page.py erzeugt build/index.html - Standalone-HTML, oeffnet im Browser ohne Server - KPI-Cards: SG/SYS/SWE/Arch/Komponenten/Tests-Counts - Sektionen mit Links: Plaene, Safety, Manuals, Audit, Reports, Diagramme, Source-Code, externe Links - Existenz-Check: nicht-generierte Reports werden grau markiert - Im Release-Bundle als index.html ganz oben CI-Integration: - validate.yml: neuer Step "Landing-Page" + Upload als Artefakt - release.yml: Landing-Page generieren + ins Bundle einbauen, zusaetzlich Source-Code im Bundle (war vorher nur als tar.gz) Makefile: neues Target `make landing-page`
This commit is contained in:
@@ -31,11 +31,12 @@ jobs:
|
||||
make coverage
|
||||
make test-report
|
||||
|
||||
- name: Traceability + Diagramme + API-Doc
|
||||
- name: Traceability + Diagramme + API-Doc + Landing-Page
|
||||
run: |
|
||||
python3 tools/traceability.py publish docs/traceability
|
||||
python3 tools/render_plantuml.py
|
||||
make docs
|
||||
make landing-page
|
||||
|
||||
- name: Cppcheck-Report (XML)
|
||||
run: |
|
||||
@@ -46,7 +47,10 @@ jobs:
|
||||
- name: Release-Bundle paketieren
|
||||
run: |
|
||||
BUNDLE="release/demo-epb-${TAG}"
|
||||
mkdir -p "$BUNDLE"/{coverage,traceability,diagrams,api-doc,reports,docs}
|
||||
mkdir -p "$BUNDLE"/{coverage,traceability,diagrams,api-doc,reports,docs,src,tests}
|
||||
|
||||
# Landing-Page (Startseite) im Bundle-Root
|
||||
cp build/index.html "$BUNDLE/index.html"
|
||||
|
||||
# CI-generierte Artefakte
|
||||
cp -r build/coverage-html/* "$BUNDLE/coverage/" 2>/dev/null || true
|
||||
@@ -57,6 +61,10 @@ jobs:
|
||||
cp build/test-report.html "$BUNDLE/reports/" 2>/dev/null || true
|
||||
cp build/test-report.md "$BUNDLE/reports/" 2>/dev/null || true
|
||||
|
||||
# Source-Code zum Anklicken aus dem Bundle (begrenzt auf das wichtigste)
|
||||
cp -r src/*.c src/*.h "$BUNDLE/src/" 2>/dev/null || true
|
||||
cp -r src/stubs "$BUNDLE/src/" 2>/dev/null || true
|
||||
|
||||
# Alle Word-Dokumente (Plaene, Safety, Manuals, Audit-Artefakte)
|
||||
mkdir -p "$BUNDLE/docs/plaene" "$BUNDLE/docs/safety" "$BUNDLE/docs/manuals" \
|
||||
"$BUNDLE/docs/reviews" "$BUNDLE/docs/non-conformities" "$BUNDLE/docs/misra"
|
||||
|
||||
@@ -84,6 +84,9 @@ jobs:
|
||||
- name: Doxygen API-Dokumentation
|
||||
run: make docs
|
||||
|
||||
- name: Landing-Page
|
||||
run: make landing-page
|
||||
|
||||
- name: Cppcheck-Report (XML)
|
||||
run: |
|
||||
mkdir -p build
|
||||
@@ -128,6 +131,13 @@ jobs:
|
||||
name: api-doc
|
||||
path: build/api-doc/html/
|
||||
|
||||
- name: Upload Landing-Page
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: landing-page
|
||||
path: build/index.html
|
||||
|
||||
- name: Upload Cppcheck-Report
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
|
||||
@@ -21,10 +21,13 @@ TESTS = test_switch_debouncer test_actuator_driver test_apply_controller \
|
||||
test_safety_manager
|
||||
TEST_BINS = $(TESTS:%=$(BUILD)/%)
|
||||
|
||||
.PHONY: all test coverage clean misra static docs test-report
|
||||
.PHONY: all test coverage clean misra static docs test-report landing-page
|
||||
|
||||
all: $(TEST_BINS)
|
||||
|
||||
landing-page:
|
||||
python3 tools/generate_landing_page.py
|
||||
|
||||
docs:
|
||||
@which doxygen >/dev/null 2>&1 || { echo "doxygen not installed (brew/apt install doxygen)"; exit 1; }
|
||||
doxygen Doxyfile
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,148 @@
|
||||
---
|
||||
doc-id: SLM-EPB-CM-001
|
||||
version: 1.0
|
||||
status: Freigegeben
|
||||
datum: 2026-05-12
|
||||
---
|
||||
|
||||
# Configuration Management Plan (CM-Plan)
|
||||
|
||||
| Feld | Wert |
|
||||
|--------------|----------------------------------------|
|
||||
| Projekt | demo-epb |
|
||||
| Dokument-ID | SLM-EPB-CM-001 |
|
||||
| Version | 1.0 |
|
||||
| Status | Freigegeben |
|
||||
| Datum | 2026-05-12 |
|
||||
| Norm | ASPICE SUP.8 + ISO 26262-8 §7 |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck
|
||||
|
||||
Beschreibt, wie Konfigurations-Items identifiziert, versioniert, freigegeben
|
||||
und kontrolliert geaendert werden.
|
||||
|
||||
## 2. Configuration Items (CIs)
|
||||
|
||||
Folgende Artefakte stehen unter Konfigurationskontrolle:
|
||||
|
||||
| Typ | Pfad | Versionierung |
|
||||
|-------------------------|----------------------------------------|------------------------------|
|
||||
| Source-Code | `src/**/*.{c,h}` | Git |
|
||||
| Tests | `tests/**` | Git |
|
||||
| Anforderungen | `reqs/{sys,swe}/*.md` | Git + Doorstop-Item-Hash |
|
||||
| Architektur | `arch/{sys,swe}/*.md` | Git + Doorstop-Item-Hash |
|
||||
| Safety Goals | `safety/sg/*.md` | Git |
|
||||
| Plaene (Word) | `docs/plaene/*.docx` | Git + Dokument-Versionsblock |
|
||||
| Safety-Doku (Word) | `docs/safety/*.docx` | Git |
|
||||
| Manuals (Word) | `docs/manuals/*.docx` | Git |
|
||||
| Reviews + NCs | `docs/reviews/`, `docs/non-conformities/` | Git |
|
||||
| MISRA-Records | `misra/records/*.docx` | Git |
|
||||
| CI-Konfiguration | `.gitea/workflows/*.yml` | Git |
|
||||
| Build-Definition | `Makefile`, `Doxyfile` | Git |
|
||||
| Tools | `tools/*.py` | Git |
|
||||
|
||||
## 3. Repository-Struktur
|
||||
|
||||
- **Remote:** https://gitea.slohmaier.com/slohmaier/demo-epb
|
||||
- **Branch `main`:** stabil, immer freigegebener Stand
|
||||
- **Branch `develop`:** aktueller Entwicklungsstand
|
||||
- **Feature-Branches:** `feature/SWE-XXX-...`
|
||||
- **Bugfix-Branches:** `bugfix/<issue>-...`
|
||||
- **Release-Branches:** `release/vX.Y` (nur bei Real-Projekt; Demo: direkt von main)
|
||||
|
||||
## 4. Baselines
|
||||
|
||||
Eine Baseline ist ein eingefrorener, freigegebener Stand. Baselines werden durch
|
||||
Git-Tags gesetzt.
|
||||
|
||||
| Baseline-Typ | Tag-Schema | Wann |
|
||||
|---------------------------|-------------------|----------------------------------------|
|
||||
| Requirements Baseline | `req-vX.Y` | Nach Anforderungs-Freigabe |
|
||||
| Architecture Baseline | `arch-vX.Y` | Nach Architektur-Review |
|
||||
| Release Baseline | `vX.Y.Z` | Bei produktiver Freigabe |
|
||||
| Internal Snapshot | `snap-YYYY-MM-DD` | Bei wichtigen Zwischenstaenden |
|
||||
|
||||
Jeder Tag triggert (bei `vX.Y.Z`) den Release-Workflow, der ein Bundle erzeugt.
|
||||
|
||||
## 5. Versions-Schema
|
||||
|
||||
| Artefakt | Schema |
|
||||
|-----------------------|------------------------------------------|
|
||||
| Software-Release | Semantic Versioning `MAJOR.MINOR.PATCH` |
|
||||
| Anforderungen | Doorstop-Level `X.Y` + Datum |
|
||||
| Architektur | Doorstop-Level `X.Y` + Datum |
|
||||
| Word-Dokumente | `MAJOR.MINOR` im Dokument-Header |
|
||||
|
||||
## 6. Change Control
|
||||
|
||||
Aenderungen an Configuration Items erfolgen ueber:
|
||||
|
||||
1. **Trivial-Aenderung** (Tippfehler, Kommentare): direkt im Branch, PR mit 1 Approval
|
||||
2. **Normal-Aenderung** (Feature, Bugfix): Feature-Branch, PR mit Reviews je nach ASIL
|
||||
3. **Major-Aenderung** (Architektur, Sicherheits-Konzept): Change Request + Reviewer-Quorum
|
||||
|
||||
| Asil | Reviewer-Mindestanzahl |
|
||||
|---------|--------------------------------------|
|
||||
| QM | 1 |
|
||||
| ASIL-A/B| 1 |
|
||||
| ASIL-C | 2 (mind. 1 Technical Reviewer) |
|
||||
| ASIL-D | 2 Technical Reviewer + Safety Manager|
|
||||
|
||||
Reviews werden in `docs/reviews/REV-XXX.docx` dokumentiert.
|
||||
|
||||
## 7. Release-Prozess
|
||||
|
||||
```
|
||||
1. Alle PRs in main gemerged
|
||||
2. Branch protected, alle CI-Checks gruen
|
||||
3. Release-Notes-Entwurf im PR vorbereitet
|
||||
4. Tag setzen: git tag -a vX.Y.Z -m "..."
|
||||
5. Push: git push origin vX.Y.Z
|
||||
6. Release-Workflow laeuft (.gitea/workflows/release.yml):
|
||||
- Build + Tests + Coverage
|
||||
- Traceability + Diagrams + API-Doc
|
||||
- Word-Dokumente bundlen
|
||||
- Source + Artefakt-Archive packen
|
||||
- Gitea-Release anlegen
|
||||
7. Release manuell pruefen (Bundle herunterladen, sichten)
|
||||
8. Release als "stable" markieren
|
||||
```
|
||||
|
||||
## 8. Aufbewahrung
|
||||
|
||||
| Artefakt | Aufbewahrungsdauer |
|
||||
|--------------------------|----------------------------------------|
|
||||
| Git-Repository | Unbegrenzt (Gitea + Backup) |
|
||||
| Release-Bundles | 10 Jahre nach Produkt-EOL |
|
||||
| Reviews + NCs | 10 Jahre nach Produkt-EOL |
|
||||
| MISRA-Records | 10 Jahre nach Produkt-EOL |
|
||||
| CI-Artefakte (kurzlebig) | 90 Tage (in Gitea-Artifacts) |
|
||||
|
||||
ISO 26262 fordert 10 Jahre nach End-of-Production-Life (Annahme).
|
||||
|
||||
## 9. Verifikation
|
||||
|
||||
Alle Pull Requests laufen durch:
|
||||
- `doorstop`-aequivalenter Traceability-Check (`tools/traceability.py check`)
|
||||
- Build + Unit-Tests
|
||||
- Static Analysis + MISRA-Check
|
||||
- Coverage-Messung
|
||||
|
||||
Erst nach Approval und CI-Gruen kann der Merge nach `main` erfolgen.
|
||||
|
||||
## 10. Verantwortlichkeiten
|
||||
|
||||
| Rolle | Aufgabe |
|
||||
|------------------|--------------------------------------------------|
|
||||
| Configuration Mgr| Pflege dieses CM-Plans, Repo-Hygiene, Baselines |
|
||||
| Entwickler | Korrekte Branch-Strategie, sinnvolle Commit-Msg |
|
||||
| Reviewer | Pruefung vor Merge, Audit-Trail |
|
||||
| Project Owner | Release-Freigabe |
|
||||
|
||||
## 11. Aenderungshistorie
|
||||
|
||||
| Version | Datum | Aenderung | Autor |
|
||||
|---------|-------------|---------------------|-------------|
|
||||
| 1.0 | 2026-05-12 | Erstfreigabe | S. Lohmaier |
|
||||
@@ -0,0 +1,172 @@
|
||||
---
|
||||
doc-id: SLM-EPB-PM-MAN-001
|
||||
version: 1.0
|
||||
status: Freigegeben
|
||||
datum: 2026-05-12
|
||||
---
|
||||
|
||||
# Project Manual — demo-epb
|
||||
|
||||
| Feld | Wert |
|
||||
|--------------|----------------------------------------|
|
||||
| Projekt | demo-epb (Elektrische Parkbremse) |
|
||||
| Dokument-ID | SLM-EPB-PM-MAN-001 |
|
||||
| Version | 1.0 |
|
||||
| Status | Freigegeben |
|
||||
| Datum | 2026-05-12 |
|
||||
| Zielgruppe | Neue Projektmitglieder, Auditoren |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck
|
||||
|
||||
Dieses Project Manual ist der **Einstieg** ins demo-epb Projekt. Es beantwortet:
|
||||
|
||||
- Was wird gebaut?
|
||||
- Welche Dokumente gibt es, in welcher Reihenfolge lesen?
|
||||
- Wer ist verantwortlich wofuer?
|
||||
- Wie laeuft der Entwicklungs- und Freigabe-Zyklus?
|
||||
|
||||
## 2. Was ist demo-epb?
|
||||
|
||||
Eine vollstaendige Demo des **slohmaier Dev Process** anhand einer
|
||||
EPB-Steuergeraet-Software. Ziel ist **nicht** die produktive Software, sondern
|
||||
der Nachweis ASPICE 4.0 / ISO 26262-konformer Entwicklung.
|
||||
|
||||
Detail: `docs/plaene/PID.docx`.
|
||||
|
||||
## 3. Lese-Reihenfolge fuer neue Projektmitglieder
|
||||
|
||||
| Tag | Dokument | Warum |
|
||||
|-----|----------------------------------------|----------------------------------------|
|
||||
| 1 | dieses Project Manual | Orientierung |
|
||||
| 1 | `PID.docx` | Was + Warum |
|
||||
| 1 | `User-Manual.docx` | Produkt-Verstaendnis |
|
||||
| 2 | `HARA.docx` + `Safety-Case.docx` | Sicherheits-Konzept |
|
||||
| 2 | `SWE-Plan.docx` + `QA-Plan.docx` | Engineering-Konventionen |
|
||||
| 3 | `reqs/` + `arch/` (Markdown) | Anforderungen + Architektur |
|
||||
| 3 | `src/apply_controller.c` | Beispiel ASIL-D Code |
|
||||
| 4 | `traceability/index.html` | Vernetzung der Artefakte |
|
||||
| 4 | `coverage/index.html` | Was ist getestet |
|
||||
| 5 | Diese Anleitung selber pflegen | Onboarding fuer den Naechsten |
|
||||
|
||||
## 4. Dokumenten-Landschaft
|
||||
|
||||
```
|
||||
demo-epb/
|
||||
├── docs/plaene/ ← PID, PM-Plan, QA-Plan, SWE-Plan, Test-Plan, CM-Plan, RM-Plan
|
||||
├── docs/safety/ ← HARA, Safety-Case, FMEDA, MISRA-Compliance, Verification-Report, Tool-Qualification
|
||||
├── docs/manuals/ ← User-Manual, Service-Manual
|
||||
├── docs/reviews/ ← Review-Protokolle
|
||||
├── docs/non-conformities/ ← NC-Eintraege
|
||||
├── misra/records/ ← MISRA Deviation Records
|
||||
├── reqs/sys/ ← Doorstop-MD System Requirements
|
||||
├── reqs/swe/ ← Doorstop-MD Software Requirements
|
||||
├── arch/sys/ ← Doorstop-MD System Architecture + PlantUML
|
||||
├── arch/swe/ ← Doorstop-MD Software Architecture + PlantUML
|
||||
├── safety/sg/ ← Doorstop-MD Safety Goals (ASIL-Ableitung)
|
||||
├── src/ ← C-Code, mit @arch + @reqs Tags im Header
|
||||
├── tests/ ← Unit-Tests mit @reqs Tags
|
||||
├── tools/ ← Python-Skripte (Traceability, PlantUML, Reports)
|
||||
├── .gitea/workflows/ ← CI-Pipelines (validate + release)
|
||||
└── docs/index.html ← Auto-generierte Startseite
|
||||
```
|
||||
|
||||
Eine **klickbare Uebersicht** liefert `docs/index.html` (Browser oeffnen).
|
||||
|
||||
## 5. Rollen und Verantwortlichkeiten
|
||||
|
||||
| Rolle | Verantwortung | Person (Demo) |
|
||||
|--------------------|-----------------------------------------------------|--------------------------|
|
||||
| Project Owner | Strategische Entscheidungen, Freigabe Release | Stefan Lohmaier |
|
||||
| Technical Lead | Architektur, Code-Reviews, technische Entscheidungen | Stefan Lohmaier |
|
||||
| Safety Manager | HARA, Safety Case, ASIL-Konformitaet | Stefan Lohmaier (Demo) |
|
||||
| QA-Beauftragter | QA-Plan-Pflege, Audit-Vorbereitung | Stefan Lohmaier (Demo) |
|
||||
| Configuration Mgr | Baselines, Releases, Git-Repo-Hygiene | Stefan Lohmaier (Demo) |
|
||||
| Entwickler | Implementierung gemaess Architektur + Tests | Stefan Lohmaier (Demo) |
|
||||
| Reviewer | Code- und Dokument-Reviews | Externer Reviewer (TBD) |
|
||||
|
||||
In der Demo ist eine Person in allen Rollen; in einem Real-Projekt mit ASIL-C/D
|
||||
sind diese personell zu trennen (insb. Entwickler ungleich Reviewer fuer
|
||||
sicherheitskritischen Code).
|
||||
|
||||
## 6. Entwicklungs-Lebenszyklus
|
||||
|
||||
```
|
||||
Anforderung
|
||||
│
|
||||
▼
|
||||
Architektur (Markdown + PlantUML)
|
||||
│
|
||||
▼
|
||||
Implementation (C, mit @arch + @reqs)
|
||||
│
|
||||
▼
|
||||
Unit-Test (CppUTest-aehnliches Framework, mit @reqs)
|
||||
│
|
||||
▼
|
||||
Pull Request (Branch -> main)
|
||||
│
|
||||
▼
|
||||
CI: Build + Test + Coverage + MISRA + Traceability-Check
|
||||
│
|
||||
▼
|
||||
Code-Review (Approval-Pflicht je nach ASIL)
|
||||
│
|
||||
▼
|
||||
Merge nach main
|
||||
│
|
||||
▼ (bei Release-Punkt)
|
||||
Tag v*.*.*
|
||||
│
|
||||
▼
|
||||
CI Release-Workflow: Bundle + Gitea-Release
|
||||
```
|
||||
|
||||
## 7. Freigabe-Strategie
|
||||
|
||||
- **Pull-Requests** brauchen mindestens 1 Approval (mehr fuer ASIL-C/D, siehe SWE-Plan)
|
||||
- **Tags** im Format `vMAJOR.MINOR.PATCH` triggern den Release-Workflow
|
||||
- **Release-Bundle** enthaelt Source + alle Reports + alle Word-Dokumente
|
||||
- **Audit-Faehigkeit** ist jederzeit gegeben (Git-History + Doku-Lifecycle)
|
||||
|
||||
## 8. Wo Probleme melden
|
||||
|
||||
| Problem-Typ | Wo dokumentieren |
|
||||
|-----------------------|-------------------------------------------------|
|
||||
| Bug | Gitea Issue (Tag `bug`) |
|
||||
| Anforderungs-Aenderung| Gitea Issue (Tag `requirement`) + Doorstop-Update |
|
||||
| Non-Conformity | `docs/non-conformities-md/NC-XXX.md` -> Word |
|
||||
| MISRA-Abweichung | `misra/records-md/MISRA-REC-XXX.md` -> Word |
|
||||
| Sicherheits-Problem | Sofort an Safety Manager + NC |
|
||||
|
||||
## 9. Tools
|
||||
|
||||
Siehe `infrastructure/` im iCloud-Workspace fuer Setup-Details. Kurzform:
|
||||
|
||||
- **Gitea** (gitea.slohmaier.com) — Source-Control + CI + Releases
|
||||
- **Doorstop-Stil** Markdown — Anforderungen + Architektur
|
||||
- **PlantUML** — Diagramme (eingebettet)
|
||||
- **Cppcheck** + **GCC -Werror** — Statische Analyse + MISRA
|
||||
- **gcov/lcov** — Coverage
|
||||
- **Doxygen** — API-Doc
|
||||
- **pandoc** — Markdown -> Word/PDF
|
||||
- **Python** (Stdlib) — Traceability + Report-Generatoren
|
||||
|
||||
## 10. Verwandte Dokumente
|
||||
|
||||
| Plan | Datei | Inhalt |
|
||||
|----------------------|-------------------------------------|----------------------------------------|
|
||||
| Project Initiation | `PID.docx` | Was + Warum |
|
||||
| Projekt-Management | `PM-Plan.docx` | Arbeitspakete, Termine, Stakeholder |
|
||||
| Quality Assurance | `QA-Plan.docx` | Reviews, Audits, NC-Management |
|
||||
| Configuration Mgmt | `CM-Plan.docx` | Baselines, Releases, Change Control |
|
||||
| Risk Management | `RM-Plan.docx` | Risiken, Mitigation, Monitoring |
|
||||
| Software Development | `SWE-Plan.docx` | Sprache, Standards, Coverage-Ziele |
|
||||
| Test | `Test-Plan.docx` | Test-Strategie |
|
||||
|
||||
## 11. Aenderungshistorie
|
||||
|
||||
| Version | Datum | Aenderung | Autor |
|
||||
|---------|-------------|---------------------|-------------|
|
||||
| 1.0 | 2026-05-12 | Erstfreigabe | S. Lohmaier |
|
||||
@@ -0,0 +1,111 @@
|
||||
---
|
||||
doc-id: SLM-EPB-RM-001
|
||||
version: 1.0
|
||||
status: Freigegeben
|
||||
datum: 2026-05-12
|
||||
---
|
||||
|
||||
# Risk Management Plan (RM-Plan)
|
||||
|
||||
| Feld | Wert |
|
||||
|--------------|----------------------------------------|
|
||||
| Projekt | demo-epb |
|
||||
| Dokument-ID | SLM-EPB-RM-001 |
|
||||
| Version | 1.0 |
|
||||
| Status | Freigegeben |
|
||||
| Datum | 2026-05-12 |
|
||||
| Norm | ASPICE MAN.5 |
|
||||
|
||||
---
|
||||
|
||||
## 1. Zweck
|
||||
|
||||
Identifiziert, bewertet und behandelt **Projekt-Risiken** (organisatorisch,
|
||||
technisch, Zeitplan, Resource). Abgegrenzt von **funktionalen Sicherheits-
|
||||
Risiken** (Hazards), die im HARA behandelt werden.
|
||||
|
||||
## 2. Methodik
|
||||
|
||||
| Schritt | Aktion |
|
||||
|--------------------|-------------------------------------------------|
|
||||
| 1. Identifikation | Workshops, Lessons-Learned, Stakeholder-Input |
|
||||
| 2. Klassifikation | Wahrscheinlichkeit (W) x Auswirkung (A) |
|
||||
| 3. Bewertung | Risk Score = W * A (1-25) |
|
||||
| 4. Behandlung | Vermeiden / Mindern / Akzeptieren / Transferieren |
|
||||
| 5. Monitoring | Quartalsweise Review, Statusupdate |
|
||||
|
||||
### 2.1 Klassifikations-Skala
|
||||
|
||||
| Wahrscheinlichkeit | Bedeutung |
|
||||
|--------------------|----------------------------|
|
||||
| 1 | Sehr unwahrscheinlich |
|
||||
| 2 | Unwahrscheinlich |
|
||||
| 3 | Moeglich |
|
||||
| 4 | Wahrscheinlich |
|
||||
| 5 | Sehr wahrscheinlich |
|
||||
|
||||
| Auswirkung | Bedeutung |
|
||||
|------------|--------------------------------------------|
|
||||
| 1 | Vernachlaessigbar |
|
||||
| 2 | Geringe Verzoegerung / Mehraufwand |
|
||||
| 3 | Spuerbare Auswirkung auf Termin/Budget |
|
||||
| 4 | Erhebliche Auswirkung, Projekt gefaehrdet |
|
||||
| 5 | Projekt-Stop |
|
||||
|
||||
| Score-Bereich | Aktion |
|
||||
|---------------|------------------------------------------|
|
||||
| 1-4 | Akzeptieren, monitoren |
|
||||
| 5-9 | Mindern (Plan) |
|
||||
| 10-15 | Mindern (sofort, mit Eskalation) |
|
||||
| 16-25 | Eskalation an Project Owner |
|
||||
|
||||
## 3. Risiko-Register
|
||||
|
||||
| ID | Beschreibung | W | A | Score | Behandlung | Status |
|
||||
|-------|---------------------------------------------------------|---|---|-------|------------------------------------------|----------|
|
||||
| R-01 | Demo wird als produktreifer Code missverstanden | 3 | 3 | 9 | Disclaimer im README + Project Manual | Mitigated |
|
||||
| R-02 | MISRA-Tooling-Update bricht CI (false positives) | 2 | 3 | 6 | Tool-Versionen pinnen, Regression-Suite | Mitigated |
|
||||
| R-03 | Reviewer-Verfuegbarkeit fuer ASIL-D | 3 | 4 | 12 | Self-Review dokumentiert (nur Demo) | Akzeptiert (Demo) |
|
||||
| R-04 | Gitea-Server-Ausfall | 2 | 4 | 8 | Lokale Klone, regelmaessige Backups | Mitigated |
|
||||
| R-05 | Apple-Cert-Ablauf ohne Vorwarnung | 3 | 3 | 9 | Renewal-Reminder + 30-Tage-Vorwarnung | Mitigated |
|
||||
| R-06 | Windows-Build-VM unzuverlaessig (busybox-PATH-Konflikte)| 4 | 2 | 8 | MSYS2 dokumentiert, alt PATH vorne | Open |
|
||||
| R-07 | macOS act_runner host-mode Cache-Bug | 3 | 2 | 6 | continue-on-error, dokumentiert | Open |
|
||||
| R-08 | Doorstop-Tooling-Kompatibilitaet bei Update | 2 | 3 | 6 | Eigenes traceability.py, kein doorstop-Dep | Mitigated |
|
||||
| R-09 | Wissensverlust bei Single-Person-Setup | 4 | 4 | 16 | Project Manual + Dokumentation pflegen | Open |
|
||||
|
||||
## 4. Risiko-Reviews
|
||||
|
||||
| Frequenz | Teilnehmer | Outputs |
|
||||
|--------------|-------------------------|--------------------------------------|
|
||||
| Quartalsweise| Project Owner + TL | Aktualisiertes Register, Action-Items |
|
||||
| Bei Aenderung| Betroffene Rollen | Risiko-Score-Update |
|
||||
| Bei Release | Project Owner + QA | Restrisiken-Bewertung |
|
||||
|
||||
## 5. Eskalations-Pfad
|
||||
|
||||
```
|
||||
R-Owner (taeglich)
|
||||
│ Score > 9
|
||||
▼
|
||||
Project Owner (woechentlich)
|
||||
│ Score > 15
|
||||
▼
|
||||
Stakeholder / Auftraggeber (sofort)
|
||||
```
|
||||
|
||||
## 6. Lessons Learned
|
||||
|
||||
Geschlossene Risiken werden bei Projektabschluss in `docs/lessons-learned/`
|
||||
zusammengefasst, um in Folge-Projekten besser einschaetzen zu koennen.
|
||||
|
||||
## 7. Verwandte Dokumente
|
||||
|
||||
- `PM-Plan.docx` — Top-Level-Risiken (Auszug)
|
||||
- `HARA.docx` — Funktionale Sicherheits-Risiken (Hazards, getrennt von Projekt-Risiken)
|
||||
- `QA-Plan.docx` — Non-Conformity-Management
|
||||
|
||||
## 8. Aenderungshistorie
|
||||
|
||||
| Version | Datum | Aenderung | Autor |
|
||||
|---------|-------------|---------------------|-------------|
|
||||
| 1.0 | 2026-05-12 | Erstfreigabe | S. Lohmaier |
|
||||
@@ -0,0 +1,298 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Erzeugt eine HTML-Startseite (Dashboard) fuer demo-epb.
|
||||
|
||||
Scant das Repo nach Word-Dokumenten, Reports, Code, Tests, Architektur, und
|
||||
schreibt build/index.html mit klickbaren Links.
|
||||
|
||||
Run nach `make test && make coverage && make docs && make test-report && python3 tools/traceability.py publish docs/traceability && python3 tools/render_plantuml.py`.
|
||||
|
||||
Output:
|
||||
build/index.html — standalone, oeffnen mit Browser
|
||||
|
||||
Verwendung im Release-Bundle:
|
||||
- Liegt bei demo-epb-vX.Y.Z/index.html
|
||||
- Verlinkt alle anderen Bundle-Inhalte relativ
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import html
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
REPO = Path(__file__).resolve().parent.parent
|
||||
BUILD = REPO / "build"
|
||||
|
||||
|
||||
def count_files(pattern: str, base: Path = REPO) -> int:
|
||||
return sum(1 for _ in base.glob(pattern))
|
||||
|
||||
|
||||
def git_info() -> tuple[str, str]:
|
||||
try:
|
||||
sha = subprocess.check_output(
|
||||
["git", "rev-parse", "--short", "HEAD"], cwd=str(REPO),
|
||||
text=True).strip()
|
||||
except Exception:
|
||||
sha = "?"
|
||||
try:
|
||||
tag = subprocess.check_output(
|
||||
["git", "describe", "--tags", "--abbrev=0"], cwd=str(REPO),
|
||||
text=True, stderr=subprocess.DEVNULL).strip()
|
||||
except Exception:
|
||||
tag = "(no tag)"
|
||||
return sha, tag
|
||||
|
||||
|
||||
def count_doorstop_items(directory: str) -> int:
|
||||
return count_files(f"{directory}/*.md")
|
||||
|
||||
|
||||
def count_tests() -> int:
|
||||
total = 0
|
||||
for f in (REPO / "tests" / "unit").glob("test_*.c"):
|
||||
text = f.read_text()
|
||||
total += len(re.findall(r"TEST_BEGIN\(", text))
|
||||
return total
|
||||
|
||||
|
||||
def collect_docs(rel_dir: str, in_release: bool = False) -> list[tuple[str, str]]:
|
||||
"""Return [(display_name, href)] for all .docx in a directory."""
|
||||
out = []
|
||||
d = REPO / rel_dir
|
||||
if not d.exists():
|
||||
return out
|
||||
for f in sorted(d.glob("*.docx")):
|
||||
# In release bundle, paths are different; here we use relative-to-repo.
|
||||
href = os.path.relpath(f, REPO)
|
||||
# If running for in_release context, paths need adjustment, but for now
|
||||
# we always use repo-relative.
|
||||
out.append((f.stem, href))
|
||||
return out
|
||||
|
||||
|
||||
def status_for(path: Path) -> str:
|
||||
if path.exists():
|
||||
return "ok"
|
||||
return "missing"
|
||||
|
||||
|
||||
def kpi_card(label: str, value: str, sub: str = "", color: str = "#1f3864") -> str:
|
||||
return f"""
|
||||
<div class='kpi'>
|
||||
<div class='kpi-value' style='color:{color}'>{html.escape(value)}</div>
|
||||
<div class='kpi-label'>{html.escape(label)}</div>
|
||||
<div class='kpi-sub'>{html.escape(sub)}</div>
|
||||
</div>
|
||||
"""
|
||||
|
||||
|
||||
def doc_section(title: str, docs: list[tuple[str, str]], description: str = "") -> str:
|
||||
if not docs:
|
||||
items = "<li class='cnt'>— keine Dokumente —</li>"
|
||||
else:
|
||||
items = "\n".join(
|
||||
f'<li><a href="{html.escape(href)}">{html.escape(name)}</a></li>'
|
||||
for name, href in docs
|
||||
)
|
||||
return f"""
|
||||
<section>
|
||||
<h2>{html.escape(title)}</h2>
|
||||
{f"<p class='cnt'>{html.escape(description)}</p>" if description else ""}
|
||||
<ul>{items}</ul>
|
||||
</section>
|
||||
"""
|
||||
|
||||
|
||||
def report_link(name: str, href: str, exists: bool, desc: str) -> str:
|
||||
cls = "ok" if exists else "missing"
|
||||
label = name + ("" if exists else " (nicht generiert — Coverage/Build laufen lassen)")
|
||||
if exists:
|
||||
return (f"<li><a href='{html.escape(href)}'>{html.escape(label)}</a> "
|
||||
f"<span class='cnt'>— {html.escape(desc)}</span></li>")
|
||||
return f"<li class='{cls}'>{html.escape(label)} <span class='cnt'>— {html.escape(desc)}</span></li>"
|
||||
|
||||
|
||||
def main() -> int:
|
||||
BUILD.mkdir(parents=True, exist_ok=True)
|
||||
sha, tag = git_info()
|
||||
now = datetime.datetime.now(datetime.timezone.utc).isoformat(timespec="seconds")
|
||||
|
||||
# Counts
|
||||
n_sg = count_doorstop_items("safety/sg")
|
||||
n_sys = count_doorstop_items("reqs/sys")
|
||||
n_swe = count_doorstop_items("reqs/swe")
|
||||
n_sa = count_doorstop_items("arch/sys")
|
||||
n_swa = count_doorstop_items("arch/swe")
|
||||
n_tests = count_tests()
|
||||
n_impl = sum(1 for f in (REPO / "src").glob("*.c"))
|
||||
n_stubs = sum(1 for f in (REPO / "src" / "stubs").glob("*.h"))
|
||||
|
||||
# Word docs
|
||||
plans = collect_docs("docs") # plaene
|
||||
safety = collect_docs("docs/safety")
|
||||
manuals = collect_docs("docs/manuals")
|
||||
reviews = collect_docs("docs/reviews")
|
||||
ncs = collect_docs("docs/non-conformities")
|
||||
misra_r = collect_docs("misra/records")
|
||||
|
||||
# Reports (existence-checked)
|
||||
rep_cov_idx = REPO / "build" / "coverage-html" / "index.html"
|
||||
rep_test_html = REPO / "build" / "test-report.html"
|
||||
rep_api = REPO / "build" / "api-doc" / "html" / "index.html"
|
||||
rep_trace = REPO / "docs" / "traceability" / "index.html"
|
||||
rep_cppcheck = REPO / "build" / "cppcheck-report.xml"
|
||||
|
||||
html_body = f"""<!doctype html>
|
||||
<html lang='de'><head>
|
||||
<meta charset='utf-8'>
|
||||
<title>demo-epb {html.escape(tag)} — Projekt-Dashboard</title>
|
||||
<style>
|
||||
:root {{ color-scheme: light; }}
|
||||
body {{ font-family: -apple-system, "Segoe UI", sans-serif; margin: 0; padding: 0; color: #222; background: #f5f6f8; }}
|
||||
header {{ background: #1f3864; color: white; padding: 20px 40px; }}
|
||||
header h1 {{ margin: 0; font-size: 26px; }}
|
||||
header .meta {{ color: #b9c2d6; font-size: 13px; margin-top: 6px; }}
|
||||
main {{ max-width: 1100px; margin: 0 auto; padding: 20px 40px; }}
|
||||
.kpis {{ display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 12px; margin: 20px 0; }}
|
||||
.kpi {{ background: white; padding: 16px; border-radius: 6px; box-shadow: 0 1px 3px rgba(0,0,0,0.07); }}
|
||||
.kpi-value {{ font-size: 28px; font-weight: 700; }}
|
||||
.kpi-label {{ color: #555; font-size: 13px; margin-top: 4px; text-transform: uppercase; letter-spacing: 0.5px; }}
|
||||
.kpi-sub {{ color: #888; font-size: 12px; margin-top: 2px; }}
|
||||
section {{ background: white; padding: 16px 24px; border-radius: 6px; margin-bottom: 16px; box-shadow: 0 1px 3px rgba(0,0,0,0.06); }}
|
||||
h2 {{ color: #1f3864; margin-top: 0; font-size: 17px; }}
|
||||
ul {{ list-style: none; padding-left: 0; }}
|
||||
li {{ padding: 4px 0; }}
|
||||
a {{ color: #1f3864; text-decoration: none; border-bottom: 1px dotted #1f3864; }}
|
||||
a:hover {{ background: #ffea8a; }}
|
||||
.cnt {{ color: #888; font-size: 13px; }}
|
||||
.missing {{ color: #c00; font-style: italic; }}
|
||||
.cols {{ display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }}
|
||||
@media (max-width: 700px) {{ .cols {{ grid-template-columns: 1fr; }} }}
|
||||
footer {{ text-align: center; color: #888; padding: 30px; font-size: 13px; }}
|
||||
.banner {{ background: #fff3cd; padding: 10px 24px; border-left: 4px solid #ff9800; margin-bottom: 16px; border-radius: 4px; }}
|
||||
</style></head>
|
||||
<body>
|
||||
<header>
|
||||
<h1>demo-epb — Elektrische Parkbremse</h1>
|
||||
<div class='meta'>Version <strong>{html.escape(tag)}</strong> · Commit <code>{html.escape(sha)}</code> · Generiert {html.escape(now)}</div>
|
||||
</header>
|
||||
<main>
|
||||
|
||||
<div class='banner'>
|
||||
<strong>Demo-Projekt:</strong> Vollstaendige Demo des
|
||||
<a href='https://gitea.slohmaier.com/slohmaier/dev-process'>slohmaier Dev Process</a>.
|
||||
Diese Software ist bewusst kein Produktivcode, sondern Showcase der Engineering-Methodik.
|
||||
</div>
|
||||
|
||||
<div class='kpis'>
|
||||
{kpi_card("Safety Goals", str(n_sg), "ASIL D/D/A/C/B", "#d62728")}
|
||||
{kpi_card("System Reqs", str(n_sys), f"in reqs/sys/")}
|
||||
{kpi_card("SW Reqs", str(n_swe), f"in reqs/swe/")}
|
||||
{kpi_card("Arch-Elemente", f"{n_sa+n_swa}", f"{n_sa} SA + {n_swa} SWA")}
|
||||
{kpi_card("Komponenten", f"{n_impl}", f"+ {n_stubs} Stubs", "#2ca02c")}
|
||||
{kpi_card("Unit-Tests", str(n_tests), "Alle gruen", "#2ca02c")}
|
||||
</div>
|
||||
|
||||
<div class='cols'>
|
||||
|
||||
<section>
|
||||
<h2>Plaene (Word)</h2>
|
||||
<ul>
|
||||
"""
|
||||
for name, href in plans:
|
||||
if not href.startswith("docs/safety") and not href.startswith("docs/manuals"):
|
||||
html_body += f" <li><a href='{html.escape(href)}'>{html.escape(name)}</a></li>\n"
|
||||
html_body += " </ul></section>\n"
|
||||
|
||||
html_body += doc_section("Funktionale Sicherheit (Word)", safety,
|
||||
"HARA, Safety Case, FMEDA, Compliance, Verification, Tool-Qualification")
|
||||
|
||||
html_body += "</div><div class='cols'>"
|
||||
|
||||
html_body += doc_section("Manuals (Word)", manuals,
|
||||
"End-User + Werkstatt-Doku")
|
||||
|
||||
audit_docs = reviews + ncs + misra_r
|
||||
html_body += doc_section("Audit-Artefakte (Word)", audit_docs,
|
||||
"Reviews, Non-Conformities, MISRA-Deviation-Records")
|
||||
|
||||
html_body += "</div>"
|
||||
|
||||
# Reports
|
||||
html_body += "<section><h2>Engineering-Reports (CI-generiert)</h2><ul>\n"
|
||||
html_body += report_link("Traceability-Matrix",
|
||||
os.path.relpath(rep_trace, REPO),
|
||||
rep_trace.exists(),
|
||||
"SG -> SYS -> SA, SWE -> SWA -> Code+Test, bidirektional verifiziert")
|
||||
html_body += report_link("Test-Summary",
|
||||
os.path.relpath(rep_test_html, REPO),
|
||||
rep_test_html.exists(),
|
||||
f"{n_tests} Unit-Tests mit Anforderungs-Mapping")
|
||||
html_body += report_link("Coverage (gcov/lcov)",
|
||||
os.path.relpath(rep_cov_idx, REPO) if rep_cov_idx.exists() else "build/coverage-html/index.html",
|
||||
rep_cov_idx.exists(),
|
||||
"Statement + Branch Coverage, klickbar bis Zeilen-Level")
|
||||
html_body += report_link("API-Dokumentation (Doxygen)",
|
||||
os.path.relpath(rep_api, REPO) if rep_api.exists() else "build/api-doc/html/index.html",
|
||||
rep_api.exists(),
|
||||
"Alle Header + Funktionen, mit @arch/@reqs/@asil")
|
||||
html_body += report_link("Cppcheck-Report (XML)",
|
||||
os.path.relpath(rep_cppcheck, REPO) if rep_cppcheck.exists() else "build/cppcheck-report.xml",
|
||||
rep_cppcheck.exists(),
|
||||
"Statische Analyse + MISRA-Findings")
|
||||
html_body += "</ul></section>"
|
||||
|
||||
# Diagrams
|
||||
diagrams = sorted((REPO / "docs" / "diagrams").glob("*.svg"))
|
||||
if diagrams:
|
||||
html_body += "<section><h2>Architektur-Diagramme (PlantUML)</h2><ul>"
|
||||
for d in diagrams:
|
||||
href = os.path.relpath(d, REPO)
|
||||
html_body += f" <li><a href='{html.escape(href)}'>{html.escape(d.stem)}</a></li>\n"
|
||||
html_body += "</ul></section>"
|
||||
|
||||
# Source code links
|
||||
html_body += """
|
||||
<section>
|
||||
<h2>Source-Code</h2>
|
||||
<ul>
|
||||
<li><a href='src/safety_manager.c'>safety_manager.c</a> — Safety Manager (ASIL-D, Hill-Hold + Auto-Apply + Drive-Away)</li>
|
||||
<li><a href='src/apply_controller.c'>apply_controller.c</a> — Apply Controller (ASIL-D, State Machine)</li>
|
||||
<li><a href='src/actuator_driver.c'>actuator_driver.c</a> — Actuator Driver (ASIL-B, Overcurrent-Cutoff)</li>
|
||||
<li><a href='src/switch_debouncer.c'>switch_debouncer.c</a> — Switch Debouncer (QM)</li>
|
||||
<li class='cnt'>Plus 6 Stub-Header in <a href='src/stubs/'>src/stubs/</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
"""
|
||||
|
||||
html_body += f"""
|
||||
<section>
|
||||
<h2>Externe Links</h2>
|
||||
<ul>
|
||||
<li><a href='https://gitea.slohmaier.com/slohmaier/demo-epb'>Gitea-Repo</a></li>
|
||||
<li><a href='https://gitea.slohmaier.com/slohmaier/demo-epb/releases'>Releases</a></li>
|
||||
<li><a href='https://gitea.slohmaier.com/slohmaier/dev-process'>Methodik-Repo (dev-process)</a></li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
Build {html.escape(now)} · demo-epb {html.escape(tag)} ({html.escape(sha)}) · slohmaier.com
|
||||
</footer>
|
||||
|
||||
</body></html>
|
||||
"""
|
||||
|
||||
out = BUILD / "index.html"
|
||||
out.write_text(html_body)
|
||||
print(f"Wrote {out}")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
Reference in New Issue
Block a user