Files
Orchestrator/bahn/wissensdatenbank/.gitlab-ci.yml

157 lines
6.2 KiB
YAML

# =============================================================================
# Wissensdatenbank ETL-Pipeline (DB-GitLab)
# =============================================================================
# Die Runner-Pods erreichen pypi.org NICHT, aber den Artifactory-PyPI-Mirror auf
# bahnhub. Daher pip ueber PIP_INDEX_URL -> kein eigenes Deps-Image noetig.
# lint : ruff (ueber PyPI-Mirror)
# test : pip install (ueber Mirror) + pytest
# preview: pip install + --only (MR, manuell) -> erzeugte Markdowns als Artefakt
# etl : pip install + Wissensaufbau (Schedule/manuell), committet + refresht pages
# pages : pyyaml; Produktion auf main
# =============================================================================
stages:
- quality
- etl
- pages
variables:
HOME: "/tmp"
GIT_DEPTH: "1"
TARGET_BRANCH: "main"
# Artifactory-PyPI-Mirror (vom Cluster erreichbar). Bei Bedarf Repo-Name anpassen.
PIP_INDEX_URL: "https://bahnhub.tech.rz.db.de/artifactory/api/pypi/pypi-remote/simple"
PIP_DISABLE_PIP_VERSION_CHECK: "1"
# Robustheit gegen transiente 504/Timeouts vom Mirror (gilt fuer ALLE pip-Aufrufe):
PIP_RETRIES: "10"
PIP_DEFAULT_TIMEOUT: "90"
.python_image: &python_image
image: docker-hub-remote.bahnhub.tech.rz.db.de/python:3.14-alpine@sha256:26730869004e2b9c4b9ad09cab8625e81d256d1ce97e72df5520e806b1709f92
# --- Qualitaet: Lint (ruff ueber PyPI-Mirror) --------------------------------
lint:
<<: *python_image
stage: quality
script:
- pip install --no-cache-dir ruff --quiet
- python -m ruff check src tests scripts
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH'
# --- Qualitaet: Tests --------------------------------------------------------
test:
<<: *python_image
stage: quality
script:
- pip install --no-cache-dir -r requirements.txt pytest --quiet
- python -m pytest -q
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH'
# --- Qualitaet: Secret-Scan (gitleaks-Binary, kein pip) ----------------------
secret-scan:
stage: quality
image:
name: docker-hub-remote.bahnhub.tech.rz.db.de/zricethezav/gitleaks:latest@sha256:c00b6bd0aeb3071cbcb79009cb16a60dd9e0a7c60e2be9ab65d25e6bc8abbb7f
entrypoint: [""]
script:
- gitleaks detect --source . --no-banner --redact --exit-code 1
allow_failure: true # TODO: Image pinnen / pipeship scan_secrets pruefen
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
- if: '$CI_COMMIT_BRANCH'
# --- ETL: Wissen aufbauen + committen ---------------------------------------
# Netzzugang ueber den DB-Web-Proxy (oeffentliche Ziele wie www.dbinfrago.com und
# der Alpine-CDN fuer 'apk'). INTERNE Hosts (Confluence, bahnhub-PyPI, GitLab-Push)
# laufen per NO_PROXY am Proxy vorbei. Proxy ggf. anpassen, falls er abweicht.
knowledge-etl:
# Volles Debian-python-Image (enthaelt git) statt -alpine -> kein root-apk noetig.
image: docker-hub-remote.bahnhub.tech.rz.db.de/python:3.14@sha256:5c485439db26ba10745100656f6712d662075edb7ec6861dda715bcdfe579b29
stage: etl
variables:
HTTP_PROXY: "http://webproxy.comp.db.de:8080"
HTTPS_PROXY: "http://webproxy.comp.db.de:8080"
http_proxy: "http://webproxy.comp.db.de:8080"
https_proxy: "http://webproxy.comp.db.de:8080"
NO_PROXY: "localhost,127.0.0.1,.tech.rz.db.de,.deutschebahn.com"
no_proxy: "localhost,127.0.0.1,.tech.rz.db.de,.deutschebahn.com"
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
- if: '$CI_PIPELINE_SOURCE == "web"'
before_script:
- pip install --no-cache-dir -r requirements.txt --quiet
script:
- python -m src.main --config config/tools.yaml --data output --staging staging
after_script:
- |
if [ -z "${GIT_PUSH_TOKEN}" ]; then
echo "GIT_PUSH_TOKEN nicht gesetzt -> Ergebnis nur als Artefakt, kein Commit.";
exit 0;
fi
git config user.email "knowledge-bot@deutschebahn.com"
git config user.name "knowledge-bot"
git checkout -B "${TARGET_BRANCH}"
git add output/ staging/ docs/
if git diff --cached --quiet; then
echo "Keine Aenderungen am Wissen.";
else
git commit -m "chore(data): Wissensaktualisierung (automatischer Lauf)"
# KEIN ci.skip: der Daten-Commit auf main loest eine Pipeline aus, deren
# 'pages'-Job die Live-Seite mit dem frischen Wissen neu deployt. Kein Loop,
# da 'knowledge-etl' nur bei schedule/web laeuft (nicht bei push).
git push \
"https://oauth2:${GIT_PUSH_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git" \
"HEAD:${TARGET_BRANCH}"
fi
artifacts:
name: "knowledge-base-${CI_COMMIT_REF_NAME}"
paths:
- output/processed/
# Kurz halten: der Bot pusht das Wissen ohnehin nach main; das Artefakt ist
# nur Fallback, wenn der Push fehlschlaegt (kein GIT_PUSH_TOKEN).
expire_in: 7 days
# --- Pages: Produktion (nur Default-Branch) ----------------------------------
pages:
<<: *python_image
stage: pages
before_script:
- pip install --no-cache-dir pyyaml --quiet
script:
- python -m src.site --data output --staging staging --out public
artifacts:
paths:
- public
# Pages nutzt nur das neueste Artefakt; alte koennen weg.
expire_in: 7 days
rules:
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
# --- MR-Vorschau: zeigt, wie eine NEUE/geaenderte Quelle verarbeitet wird -----
# Kein GitLab-Pages-Hosting (parallel deployments werden hier nicht unterstuetzt) ->
# stattdessen werden die erzeugten Markdown-Dateien als Job-Artefakt bereitgestellt.
# Manuell starten und PREVIEW_ONLY auf Tool-Id / Domaene / URL-Teil der neuen Quelle
# setzen (z.B. PREVIEW_ONLY=pathos). So sieht man vor dem Merge das Ergebnis.
preview:
<<: *python_image
stage: quality
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
before_script:
- pip install --no-cache-dir -r requirements.txt --quiet
script:
- python -m src.main --config config/tools.yaml --data preview --staging preview_staging --only "${PREVIEW_ONLY}"
artifacts:
name: "vorschau-${CI_COMMIT_REF_SLUG}"
expose_as: "Wissens-Vorschau erzeugte Markdown-Dateien"
paths:
- preview/processed/
- preview_staging/
expire_in: 7 days