# ============================================================================= # 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