Der ursprüngliche Plan:
# Plan: CI-Pipeline fuer den Knowledge Manager
## 1. Aufgabenstellung
Der **Knowledge Manager** (`DCCT/knowledge_manager`) ist ein Python-Projekt, das Inhalte aus
Confluence extrahiert, transformiert und in Cognigy Knowledge Stores hochlaedt.
Das Projekt verfuegt ueber eine umfangreiche pytest-Testsuite, aber bisher gibt es
**keine automatisierte CI-Pipeline**, die diese Tests ausfuehrt.
### Anforderungen
| Nr. | Anforderung | Ausloeser |
|-----|-------------|-----------|
| 1 | Tests laufen automatisch bei **jedem Code-Push** auf einen beliebigen Branch (z.B. Feature-Branch) | `git push origin feature/xyz` |
| 2 | Tests laufen automatisch wenn ein **PR gegen `master` geoeffnet** wird | PR-Erstellung in Azure DevOps |
| 3 | Tests laufen automatisch wenn ein **PR in `master` gemerged** wird | Merge/Push auf `master` |
Zusaetzlich soll **Linting mit `ruff`** als separater Schritt ausgefuehrt werden.
Wenn Linting fehlschlaegt, sollen die Tests trotzdem weiterlaufen.
### Abgrenzung
- Kein Deployment, kein Packaging, keine Artefakte
- Keine SAST-Scans oder Dependency-Checks (nur fuer Deployment-Pipelines relevant)
- Keine Benachrichtigungen in der Pipeline (werden zentral in Azure DevOps konfiguriert)
---
## 2. Technischer Kontext
### Projekt-Steckbrief Knowledge Manager
| Eigenschaft | Wert |
|-------------|------|
| Repository | `DCCT/knowledge_manager` (Azure DevOps) |
| Sprache | Python 3.13 (`pyproject.toml`: `requires-python = ">=3.13"`) |
| Package Manager | UV (Installation per `curl` in Pipeline) |
| Test-Framework | pytest + pytest-cov + pytest-mock |
| Linter | ruff (in `[dependency-groups] dev`) |
| Lock-File | `uv.lock` vorhanden |
| Test-Verzeichnis | `tests/` mit Unterordnern pro Modul |
| Externe Abhaengigkeiten fuer Tests | Keine - alle Tests sind gemockt |
### Test-Struktur
tests/ ├── confluence_extractor/ # Extractor-Modul Tests │ ├── conftest.py # Shared Fixtures (Mock-Client, Testdaten) │ ├── test_base_extractor.py │ ├── test_batch_processor.py │ ├── test_converter.py │ ├── test_hierarchy_handler.py │ ├── test_sync_manager.py │ └── test_integration.py ├── markdown_transformer/ # Transformer-Modul Tests ├── cognigy_uploader/ # Uploader-Modul Tests ├── shared/ # Shared-Utils Tests ├── streamlit_components/ # UI-Komponenten Tests └── test_full_pipeline.py # Pipeline-Integrationstest
---
## 3. Rahmenbedingungen (aus Abstimmung mit CI/CD-Experten)
| Thema | Vorgabe | Auswirkung |
|-------|---------|------------|
| **CDOS-Template** | Pflicht: `extends: pipeline.yml@Templates` | Pipeline muss das CDOS-Template nutzen, mit `securityZone: dev` |
| **Build Service Rechte** | Build Service muss Reader in `CDOS/azure-devops-pipeline` sein | Sonst schlaegt `extends: template` fehl |
| **UV** | Nicht vorinstalliert, muss per `curl` installiert werden | Installation via `curl -LsSf <https://astral.sh/uv/install.sh> \\| sh` |
| **Internetzugang** | Agents haben Zugang zu `astral.sh` | UV-Installation und Python-Download funktionieren |
| **Python 3.13** | Via `uv python install 3.13` | UV laedt Python automatisch herunter |
| **Agent Pool** | `$(AGENT_POOL)` (Self-Hosted, persistenter Workspace) | Kein explizites Caching noetig |
| **Dateipfad** | `.azdo/ci.yaml` | Entspricht TeamBank-Konvention (semantischer Name fuer CI-Pipeline) |
| **Branch Policy** | Team richtet Build Validation selbst ein (manuell oder via Terraform) | Siehe Abschnitt 5.2 und 5.3 |
| **Linting** | `ruff check` als separater Step, Tests laufen trotzdem weiter | `continueOnError: true` auf Linting-Step |
| **Benachrichtigungen** | Zentral konfiguriert | Nichts in Pipeline noetig |
| **Compliance** | Keine fuer Test-Pipelines | Kein SAST/Dependency-Check noetig |
> **Hinweis zu UV:** Die CDOS-Templates (`azure-devops-pipeline`) enthalten keine
> UV-spezifischen Steps - nur pip/venv/conda-basierte Steps (`Steps/python/create_venv.yml`,
> `Steps/python/requirements_install.yml`). Da das Knowledge Manager Projekt `pyproject.toml`
> und `uv.lock` nutzt, verwenden wir UV direkt.
>
> **Bestaetigt durch Senior-Entwickler:** UV kann per `curl` von `astral.sh` installiert
> werden. Dieses Pattern wird bereits in der `export.yaml` Pipeline verwendet
> (Zeilen 209-224 in `cognigy-pipelines/.azdo/knowledgebases/export.yaml`).
---
## 4. Loesungsweg
### 4.1 Neue Datei erstellen
**Pfad:** `DCCT/knowledge_manager/.azdo/ci.yaml`
> **Referenz zur Konvention:** Die bestehenden Pipelines im Workspace liegen ebenfalls
> unter `.azdo/` (siehe `demo-chatbot-cognigy-version/.azdo/snapshots/create.yaml`,
> `.azdo/knowledgebases/export.yaml`, etc.).
### 4.2 Trigger-Konfiguration
```yaml
trigger:
branches:
include:
- '*'
pr:
branches:
include:
- master
Erklaerung:
| Trigger | YAML-Schluessel | Was passiert |
|---|---|---|
| Push auf beliebigen Branch | trigger: branches: include: ['*'] |
Deckt Anforderung 1 (Feature-Branch Push) und Anforderung 3 (Merge in master) ab |
| PR gegen master | pr: branches: include: [master] |
Deckt Anforderung 2 ab |
Hinweis: In Azure DevOps ist
triggerder sogenannte CI-Trigger - er reagiert auf jedengit push. Wenn ein PR inmastergemerged wird, ist das technisch ein Push aufmaster, daher deckttrigger: include: ['*']sowohl Feature-Branch-Pushes als auch Merges ab.Der
pr-Trigger ist der PR-Validation-Trigger - er reagiert speziell auf das Oeffnen/Aktualisieren eines Pull Requests.
resources:
repositories:
- repository: Templates
type: git
name: CDOS/azure-devops-pipeline
ref: refs/tags/v4
extends:
template: pipeline.yml@Templates
parameters:
securityZone: dev
stages:
- stage: test
...
Referenz: Exakt dasselbe Pattern wird in der bestehenden Knowledge-Export-Pipeline verwendet:
cognigy-pipelines/.azdo/knowledgebases/export.yaml(Zeilen 2-7 fuerresources, Zeilen 46-48 fuerextends).Der einzige Unterschied: Die Export-Pipeline nutzt
securityZone: ${{ parameters.securityZone }}(parametrisiert), wir verwenden festsecurityZone: dev, da unsere Test-Pipeline immer in der Dev-Zone laeuft.
- bash: |
set -eu
set -o pipefail
# UV installieren (nicht vorinstalliert auf Agents)
curl -LsSf <https://astral.sh/uv/install.sh> | sh
source "$HOME/.local/bin/env"
uv --version
# Python 3.13 sicherstellen
uv python install 3.13
python3 --version
# Alle Dependencies installieren (inkl. dev-Gruppe fuer ruff)
uv sync --frozen --python 3.13
# Virtual Environment fuer nachfolgende Steps verfuegbar machen
echo "##vso[task.prependpath]$(pwd)/.venv/bin"
echo "##vso[task.setvariable variable=VIRTUAL_ENV]$(pwd)/.venv"
displayName: Setup Python and install dependencies
Erklaerung der einzelnen Befehle:
| Befehl | Zweck |
|---|---|
set -eu / set -o pipefail |
Script bricht bei Fehlern sofort ab (Best Practice) |
curl -LsSf ... \| sh |
Laedt und installiert UV vom offiziellen Installer. -L folgt Redirects, -sS zeigt nur Fehler, -f bricht bei HTTP-Fehlern ab |
source "$HOME/.local/bin/env" |
Laedt die UV-Umgebungsvariablen, damit uv im PATH ist |
uv python install 3.13 |
Laedt Python 3.13 herunter und installiert es lokal |
uv sync --frozen --python 3.13 |
Installiert alle Dependencies aus uv.lock - reproduzierbar und deterministisch. Ohne --no-dev, damit auch ruff (dev-Gruppe) installiert wird |
##vso[task.prependpath] |
Azure DevOps Logging-Command: Fuegt .venv/bin zum PATH hinzu, damit nachfolgende Steps pytest und ruff direkt aufrufen koennen |
##vso[task.setvariable] |
Setzt VIRTUAL_ENV Environment-Variable fuer nachfolgende Steps |
Referenz: Exakt dasselbe Pattern findet sich in:
cognigy-pipelines/.azdo/knowledgebases/export.yaml(Zeilen 204-224).Einziger Unterschied zur Referenz: Die Export-Pipeline nutzt
--no-dev(da sie kein ruff braucht). Wir verwendenuv sync --frozen --python 3.13ohne--no-dev, damit ruff aus der dev-Gruppe mitinstalliert wird.Bestaetigt durch Senior-Entwickler: Die UV-Installation per
curlfunktioniert auf den Build-Agents. Dies ist das etablierte Pattern bei DCCT.
- bash: |
set -eu
set -o pipefail
echo "Running ruff linter..."
uv run ruff check src/ tests/
displayName: Lint with ruff
continueOnError: true
Wichtig:
continueOnError: truesorgt dafuer, dass die Pipeline bei Linting-Fehlern nicht abbricht. Der Step wird als "Warning" (orange) angezeigt, aber die nachfolgenden Test-Steps laufen trotzdem weiter. Dies entspricht der Vorgabe des CI/CD-Experten.
- bash: |
set -eu
set -o pipefail
uv run pytest \\
--tb=short \\
--junitxml=$(Build.ArtifactStagingDirectory)/test-results.xml \\
--cov=src \\
--cov-report=term-missing
displayName: Run tests with pytest
| Flag | Zweck |
|---|---|
--tb=short |
Kurze Tracebacks bei Fehlern (uebersichtlicher im Build-Log) |
--junitxml=... |
Erzeugt JUnit-XML-Report fuer Azure DevOps Test-Tab |
--cov=src |
Misst Code-Coverage ueber das gesamte src/-Verzeichnis |
--cov-report=term-missing |
Zeigt im Log, welche Zeilen nicht durch Tests abgedeckt sind |
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: JUnit
testResultsFiles: $(Build.ArtifactStagingDirectory)/test-results.xml
testRunTitle: Knowledge Manager Tests
Warum
condition: succeededOrFailed()? Standardmaessig werden nachfolgende Steps bei einem Fehler uebersprungen. MitsucceededOrFailed()wird der Test-Report auch bei fehlgeschlagenen Tests veroeffentlicht. So sieht man in Azure DevOps immer, welche Tests genau fehlgeschlagen sind - auch wenn der Build rot ist.Der Test-Report erscheint dann im Azure DevOps Build unter dem "Tests"-Tab.
---
trigger:
branches:
include:
- '*'
pr:
branches:
include:
- master
resources:
repositories:
- repository: Templates
type: git
name: CDOS/azure-devops-pipeline
ref: refs/tags/v4
pool: $(AGENT_POOL)
name: $(Build.BuildId)
extends:
template: pipeline.yml@Templates
parameters:
securityZone: dev
stages:
- stage: test
displayName: Lint and Test
jobs:
- job: lint_and_test
displayName: Lint and Test Knowledge Manager
steps:
- checkout: self
fetchDepth: 1
clean: true
- bash: |
set -eu
set -o pipefail
# UV installieren
curl -LsSf <https://astral.sh/uv/install.sh> | sh
source "$HOME/.local/bin/env"
uv --version
# Python 3.13 installieren
uv python install 3.13
python3 --version
# Dependencies installieren (inkl. dev-Gruppe fuer ruff)
uv sync --frozen --python 3.13
# Virtual Environment fuer nachfolgende Steps verfuegbar machen
echo "##vso[task.prependpath]$(pwd)/.venv/bin"
echo "##vso[task.setvariable variable=VIRTUAL_ENV]$(pwd)/.venv"
displayName: Setup Python and install dependencies
- bash: |
set -eu
set -o pipefail
echo "Running ruff linter..."
uv run ruff check src/ tests/
displayName: Lint with ruff
continueOnError: true
- bash: |
set -eu
set -o pipefail
uv run pytest \\
--tb=short \\
--junitxml=$(Build.ArtifactStagingDirectory)/test-results.xml \\
--cov=src \\
--cov-report=term-missing
displayName: Run tests with pytest
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: JUnit
testResultsFiles: $(Build.ArtifactStagingDirectory)/test-results.xml
testRunTitle: Knowledge Manager Tests
knowledge_manager auswaehlen.azdo/ci.yaml auswaehlenDamit PRs nur gemerged werden koennen, wenn die Tests gruen sind:
master das Kontextmenue oeffnen (drei Punkte) -> Branch PoliciesDieser Schritt wird vom Entwicklungsteam selbst durchgefuehrt (Bestaetigung durch CI/CD-Experten).
Die Build Validation wird ueber das tf-azdo Repository in der Datei alm.tfvars
konfiguriert. Dies ist der CDOS-konforme Weg und nutzt das Modul
tf_module_azdo_build_validations.
Es sind zwei Aenderungen in alm.tfvars noetig:
Schritt 1: Neuen Pipeline-Eintrag in pipelines hinzufuegen.
Position: Am Ende des
pipelines-Blocks (nach dem letzten bestehenden Eintrag).
# --- BESTEHENDER LETZTER EINTRAG (nicht aendern) ---
"partnerbank-chatbot-knowledge-stage" = {
name = "Stage Knowledge"
path = "\\\\Cognigy\\\\Partnerbank-Chatbot\\\\Knowledge"
branch_name = "refs/heads/main"
yaml_file_path = ".azdo/knowledgebases/stage.yaml"
repository_name = "partnerbank-chatbot-cognigy-version"
}
# --- NEUER EINTRAG (hinzufuegen) ---
"knowledge-manager-ci" = {
name = "CI Tests"
path = "\\\\DCCT\\\\Knowledge Manager"
branch_name = "refs/heads/master"
yaml_file_path = ".azdo/ci.yaml"
repository_name = "knowledge_manager"
}
| Feld | Wert | Erklaerung |
|---|---|---|
| Key | "knowledge-manager-ci" |
Eindeutiger Schluessel, wird in Schritt 2 referenziert |
name |
"CI Tests" |
Anzeigename der Pipeline in Azure DevOps |
path |
"\\\\DCCT\\\\Knowledge Manager" |
Ordnerstruktur in Azure DevOps Pipelines |
branch_name |
"refs/heads/master" |
Default-Branch des Repositories (nicht main!) |
yaml_file_path |
".azdo/ci.yaml" |
Pfad zur Pipeline-Datei im Repository |
repository_name |
"knowledge_manager" |
Name des Repositories in Azure DevOps |
Schritt 2: build_validations zum bestehenden knowledge_manager Repository-Block hinzufuegen.
Position: Im
repositories-Block gibt es bereits einen Eintrag"knowledge_manager". Dort mussbuild_validationsergaenzt werden.
Vorher:
"knowledge_manager" = {
reviewers = "dcct_contributors"
}
Nachher:
"knowledge_manager" = {
reviewers = "dcct_contributors"
build_validations = {
knowledge-manager-ci = ["*"]
}
}
| Feld | Wert | Erklaerung |
|---|---|---|
| Key | knowledge-manager-ci |
Muss exakt dem Pipeline-Key aus Schritt 1 entsprechen |
["*"] |
Alle Branches | Build Validation gilt fuer PRs gegen alle Branches. Analog zum bestehenden Pattern bei cognai-bot-deployment |
Schritt 3: PR in tf-azdo erstellen und mergen -> Terraform Apply
Ergebnis nach Terraform Apply: PRs gegen
masterimknowledge_managerRepository koennen nur noch gemerged werden, wenn die CI-Pipeline gruen ist.Referenz: Das exakt gleiche Pattern wird bereits fuer
cognai-bot-deploymentverwendet (Pipeline-Keycognai-bot-deployment-testmitbuild_validationsim Repository-Block).
Nach der Umsetzung koennen alle drei Anforderungen getestet werden:
| Test | Aktion | Erwartetes Ergebnis |
|---|---|---|
| Feature-Branch Push | Neuen Branch erstellen, Aenderung pushen | Pipeline startet automatisch, Tests laufen |
| PR-Erstellung | PR gegen master oeffnen |
Pipeline startet automatisch, Ergebnis erscheint im PR |
| Merge in master | PR genehmigen und mergen | Pipeline startet automatisch auf master |
| Linting-Fehler | Code mit ruff-Verstoessen pushen | Linting-Step zeigt Warning (orange), Tests laufen trotzdem |
| Test-Fehler | Fehlerhaften Test pushen | Build schlaegt fehl (rot), Test-Report ist trotzdem sichtbar im Tests-Tab |
| Referenz | Pfad | Was wird daraus uebernommen |
|---|---|---|
| Export-Pipeline (cognigy-pipelines) | cognigy-pipelines/.azdo/knowledgebases/export.yaml |
CDOS-Template-Einbindung (Zeilen 2-7, 46-48), Python/UV-Setup (Zeilen 204-224) |
| Snapshot-Create-Pipeline | demo-chatbot-cognigy-version/.azdo/snapshots/create.yaml |
Pool-Konfiguration $(AGENT_POOL), name: $(BuildID) Pattern |
| CDOS Pipeline Template | CDOS/azure-devops-pipeline (ref: v4) |
Basis-Template pipeline.yml, securityZone Parameter |
| CDOS Python Steps | azure-devops-pipeline/Steps/python/ |
Referenz fuer venv/pip-basierte Workflows (hier nicht genutzt, da UV verwendet wird) |
| CDOS Build Validations | tf_module_azdo_build_validations |
Terraform-Modul fuer automatisierte Branch Policies |
| Azure-Artikel (Microsoft) | DevOps Pipelines Baseline Architecture | Konzeptionelle Grundlage fuer PR- und CI-Trigger |
| pyproject.toml | knowledge_manager/pyproject.toml |
Python-Version (>=3.13), Dependencies (pytest, ruff) |
Dieser Plan wurde gegen die aktuellen CDOS-Templates und Best Practices verifiziert (Stand: Maerz 2026).
| Aspekt | Status | Beleg |
|---|---|---|
CDOS-Template Nutzung (extends: pipeline.yml@Templates) |
✅ | CDOS-Empfehlung, ref: v4 |
securityZone: dev fuer Test-Pipelines |
✅ | Standard in allen DCCT-Pipelines |
| UV-basiertes Python-Setup | ✅ | Etabliertes Pattern in DCCT-Projekten |
JUnit-Reporting mit PublishTestResults@2 |
✅ | CDOS-konform |
continueOnError: true fuer Linting |
✅ | Keine CDOS-Policy dagegen |
| Build Validation via Terraform | ✅ | tf_module_azdo_build_validations |
| Aspekt | CDOS-Default | Unsere Wahl | Begruendung |
|---|---|---|---|
| Pipeline-Dateiname | .azdo/azure-pipeline.yml |
.azdo/ci.yaml |
Semantisch beschreibend fuer CI-Pipeline; andere DCCT-Pipelines nutzen auch spezifische Namen (export.yaml, create.yaml) |
| Python-Setup | Steps/python/create_venv.yml + requirements_install.yml |
UV direkt | Projekt nutzt pyproject.toml + uv.lock; CDOS-Steps sind pip-basiert und unterstuetzen UV nicht |
| Punkt | Verantwortlich | Status |
|---|---|---|
Build Service als Reader in CDOS/azure-devops-pipeline |
DevOps-Admin | Vor Pipeline-Registrierung pruefen |
Internetzugang zu astral.sh |
Infrastruktur | ✅ Bestaetigt durch Senior-Entwickler |
### .azdo/ci.yaml:
<aside>
💡
In Repo tf_azdo wird die pipeline verlinkt, jedoch nicht konfiguriert! Normalerweise außerhalb TB wird tf_azdo nicht benötigt
</aside>
```yaml
# =============================================================================
# CI-Pipeline: Knowledge Manager - Lint & Test
# =============================================================================
#
# Zweck:
# Automatisierte Code-Qualitaetspruefung und Testausfuehrung fuer den
# Knowledge Manager. Laeuft bei jedem Push und bei PRs gegen master.
#
# Was passiert:
# 1. Python 3.13 + UV werden installiert (UV ist nicht vorinstalliert)
# 2. Alle Dependencies werden aus uv.lock installiert (reproduzierbar)
# 3. Linting mit ruff (Warnung bei Fehlern, kein Build-Abbruch)
# 4. Tests mit pytest (Build schlaegt fehl bei Test-Fehlern)
# 5. Test-Ergebnisse werden im Azure DevOps "Tests"-Tab angezeigt
#
# Voraussetzungen:
# - Build Service muss Reader-Rechte in CDOS/azure-devops-pipeline haben
# - Agents muessen Internetzugang zu astral.sh haben (fuer UV-Download)
#
# Referenzen:
# - CDOS-Template: CDOS/azure-devops-pipeline (ref: v4)
# - UV-Setup-Pattern: cognigy-pipelines/.azdo/knowledgebases/export.yaml
# =============================================================================
# ---------------------------------------------------------------------------
# Trigger-Konfiguration
# ---------------------------------------------------------------------------
#
# CI-Trigger (trigger):
# Reagiert auf jeden 'git push' - egal auf welchen Branch.
# Deckt ab:
# - Push auf Feature-Branches
# - Merge in master - ein Merge ist technisch ein Push
#
# PR-Trigger (pr):
# Reagiert auf das Oeffnen/Aktualisieren eines Pull Requests gegen master.
# Deckt ab:
# - PR-Erstellung gegen master
# ---------------------------------------------------------------------------
trigger:
branches:
include:
- '*'
pr:
branches:
include:
- master
# ---------------------------------------------------------------------------
# CDOS-Template Einbindung
# ---------------------------------------------------------------------------
# Pflicht fuer alle Pipelines: Das CDOS-Template wird als Basis verwendet.
# ref: refs/tags/v4 pinnt auf eine stabile Version des Templates.
# ---------------------------------------------------------------------------
resources:
repositories:
- repository: Templates
type: git
name: CDOS/azure-devops-pipeline
ref: refs/tags/v4
# Self-Hosted Agent Pool (wird zentral als Variable bereitgestellt)
pool: $(AGENT_POOL)
# Build-Nummer entspricht der Azure DevOps Build-ID
name: $(Build.BuildId)
# ---------------------------------------------------------------------------
# Pipeline-Struktur
# ---------------------------------------------------------------------------
# extends: pipeline.yml@Templates bindet das CDOS-Basis-Template ein.
# securityZone: dev - Test-Pipelines laufen immer in der Dev-Zone.
# ---------------------------------------------------------------------------
extends:
template: pipeline.yml@Templates
parameters:
securityZone: dev
stages:
- stage: test
displayName: Lint and Test
jobs:
- job: lint_and_test
displayName: Lint and Test Knowledge Manager
steps:
# ---------------------------------------------------------------
# Step 1: Repository auschecken
# ---------------------------------------------------------------
# fetchDepth: 1 - Nur den letzten Commit laden (schneller)
# clean: true - Workspace vorher bereinigen (keine Altlasten)
# ---------------------------------------------------------------
- checkout: self
fetchDepth: 1
clean: true
# ---------------------------------------------------------------
# Step 2: Python-Umgebung einrichten
# ---------------------------------------------------------------
# UV ist auf den Build-Agents nicht vorinstalliert und muss
# per curl heruntergeladen werden. Dieses Pattern ist etabliert
# und wird bereits in der Export-Pipeline verwendet.
#
# Ablauf:
# 1. UV installieren (offizieller Installer von astral.sh)
# 2. Python 3.13 ueber UV installieren
# 3. Alle Dependencies aus uv.lock installieren
# (--frozen: exakt die Versionen aus dem Lock-File)
# (ohne --no-dev: damit ruff aus der dev-Gruppe dabei ist)
# 4. .venv/bin zum PATH hinzufuegen, damit pytest und ruff
# in nachfolgenden Steps direkt verfuegbar sind
# ---------------------------------------------------------------
- bash: |
set -eu
set -o pipefail
# UV installieren (nicht vorinstalliert auf Agents)
# -L: Redirects folgen, -sS: nur Fehler anzeigen, -f: bei HTTP-Fehlern abbrechen
curl -LsSf <https://astral.sh/uv/install.sh> | sh
source "$HOME/.local/bin/env"
echo "UV Version: $(uv --version)"
# Python 3.13 sicherstellen (UV laedt es automatisch herunter)
uv python install 3.13
echo "Python Version: $(python3 --version)"
# Alle Dependencies installieren (inkl. dev-Gruppe fuer ruff)
# --frozen: Nutzt exakt die Versionen aus uv.lock (reproduzierbar)
uv sync --frozen --python 3.13
# Virtual Environment fuer nachfolgende Steps verfuegbar machen
# Ohne diese Zeilen wuerden pytest/ruff in den naechsten Steps nicht gefunden
echo "##vso[task.prependpath]$(pwd)/.venv/bin"
echo "##vso[task.setvariable variable=VIRTUAL_ENV]$(pwd)/.venv"
displayName: Setup Python and install dependencies
# ---------------------------------------------------------------
# Step 3: Linting mit ruff
# ---------------------------------------------------------------
# Prueft Code-Stil und typische Fehler in src/ und tests/.
#
# continueOnError: true
# → Bei Linting-Fehlern wird der Step als "Warning" (orange)
# angezeigt, aber die Pipeline laeuft weiter.
# → Tests werden trotzdem ausgefuehrt - ein Linting-Fehler
# soll den Build nicht blockieren.
# ---------------------------------------------------------------
- bash: |
set -eu
set -o pipefail
echo "Running ruff linter..."
uv run ruff check src/ tests/
displayName: Lint with ruff
continueOnError: true
# ---------------------------------------------------------------
# Step 4: Tests mit pytest
# ---------------------------------------------------------------
# Fuehrt die komplette Test-Suite aus.
#
# Flags:
# --tb=short Kurze Tracebacks (uebersichtlicher im Log)
# --junitxml=... JUnit-XML fuer den Azure DevOps Tests-Tab
# --cov=src Code-Coverage ueber das src/-Verzeichnis
# --cov-report=term-missing Zeigt nicht abgedeckte Zeilen im Log
#
# Wenn Tests fehlschlagen, wird der Build rot.
# Bei aktiver Branch Policy blockiert das den Merge des PRs.
# ---------------------------------------------------------------
- bash: |
set -eu
set -o pipefail
uv run pytest \\
--tb=short \\
--junitxml=$(Build.ArtifactStagingDirectory)/test-results.xml \\
--cov=src \\
--cov-report=term-missing
displayName: Run tests with pytest
# ---------------------------------------------------------------
# Step 5: Test-Ergebnisse veroeffentlichen
# ---------------------------------------------------------------
# Macht die Test-Ergebnisse im Azure DevOps "Tests"-Tab sichtbar.
#
# condition: succeededOrFailed()
# → Wird auch bei fehlgeschlagenen Tests ausgefuehrt.
# → Ohne diese Condition wuerde der Step bei roten Tests
# uebersprungen - und man wuesste nicht, welche Tests
# genau fehlgeschlagen sind.
# ---------------------------------------------------------------
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFormat: JUnit
testResultsFiles: $(Build.ArtifactStagingDirectory)/test-results.xml
testRunTitle: Knowledge Manager Tests