Chaque workflow se déclenchait sur push (toutes branches) et sur pull_request : chaque commit de PR jouait tout deux fois. sonarqube.yml reconstruisait et retestait front, back et ML en parallèle des workflows qui le faisaient déjà, et son test backend tournait sans uv sync. ci.yml devient le seul point d'entrée (pull_request, push sur dev et main) : - paths-filter choisit les composants à jouer sur une PR, tout est rejoué sur dev et main ; - backend, frontend, ml, airflow et infra passent en workflow_call ; - le job sonar reprend les couvertures versées par ces jobs au lieu de tout rejouer ; - « CI ok » agrège le résultat, seul check à exiger dans les règles de branche. Au passage : - npm run test:ci au lieu de npm test --watch=false, option que npm gardait pour lui ; - uv sync --locked au lieu de --frozen, pour qu'un verrou périmé casse la CI ; - setup-uv et sonarqube-scan-action épinglés sur un SHA (règle S7637), timeout sur chaque job ; - frontend : un seul npm ci pour la construction et les tests ; - infra : validation des fichiers Compose et actionlint sur les workflows ; - exclusions Sonar en globs, doublon apps/frontend/sonar-project.properties supprimé.
85 lines
3.4 KiB
YAML
85 lines
3.4 KiB
YAML
name: Airflow
|
|
|
|
# Piège : la version de Python vient de etl/airflow/.python-version. C'est 3.12 et non 3.14
|
|
# (contrairement à backend.yml et ml.yml) : celui de l'image apache/airflow retenue, et les tests
|
|
# doivent tourner sur le même interpréteur qu'elle. Le 3.14 de ml/ ne vit que dans l'image
|
|
# Docker, dans son propre environnement (cf. etl/airflow/Dockerfile).
|
|
#
|
|
# Piège : l'image COPY les fichiers de dépendances et le code de ml/ et de apps/backend/. Une
|
|
# modification de l'un ou de l'autre peut donc casser sa construction : le filtre `airflow` de
|
|
# ci.yml, qui appelle ce workflow, inclut ces chemins alors qu'il ne teste ni le modèle ni l'API.
|
|
|
|
on:
|
|
workflow_call:
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
verification:
|
|
name: Lint et intégrité des DAGs
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 15
|
|
defaults:
|
|
run:
|
|
working-directory: etl/airflow
|
|
|
|
steps:
|
|
- name: Récupère le dépôt
|
|
uses: actions/checkout@v7
|
|
|
|
# Action tierce, épinglée sur le commit du tag (règle Sonar githubactions:S7637).
|
|
- name: Installe uv
|
|
uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7
|
|
with:
|
|
enable-cache: true
|
|
cache-dependency-glob: etl/airflow/uv.lock
|
|
prune-cache: false
|
|
|
|
- name: Installe l'interpréteur déclaré par .python-version
|
|
run: uv python install
|
|
|
|
- name: Synchronise les dépendances sur le verrou
|
|
run: uv sync --all-groups --locked
|
|
|
|
- name: Vérifie le formatage
|
|
run: uv run ruff format --check .
|
|
|
|
- name: Analyse statique
|
|
run: uv run ruff check --output-format=github .
|
|
|
|
# Aucun test ne lance de tâche ni de scheduler : DagBag charge les fichiers de dags/ et
|
|
# vérifie import, planification, plafonds d'exécution et commande de chaque tâche.
|
|
- name: Tests d'intégrité des DAGs
|
|
run: uv run pytest
|
|
|
|
image:
|
|
name: Construction de l'image
|
|
runs-on: ubuntu-latest
|
|
timeout-minutes: 25
|
|
|
|
steps:
|
|
- name: Récupère le dépôt
|
|
uses: actions/checkout@v7
|
|
|
|
- name: Construit l'image (contexte à la racine, elle COPY ml/ et apps/backend/)
|
|
run: docker build -f etl/airflow/Dockerfile -t enervision-airflow:ci .
|
|
|
|
# Vérifie ce qui ne casse qu'à l'exécution, pas à la construction : libgomp1 absent
|
|
# (`OSError: libgomp.so.1` au premier import) ou environnement ml/ non figé.
|
|
- name: Vérifie que le pipeline ML s'importe sans réseau
|
|
run: >
|
|
docker run --rm --network none enervision-airflow:ci
|
|
bash -c "cd /opt/ml && env -u VIRTUAL_ENV uv run --no-sync python -m enervision_ml.train --help"
|
|
|
|
# `--help` sort par argparse avant `get_settings()` : ni base ni secret requis, et
|
|
# l'import des modules prouve que l'environnement /opt/backend est complet.
|
|
- name: Vérifie que les quatre commandes backend s'importent sans réseau
|
|
run: >
|
|
docker run --rm --network none enervision-airflow:ci
|
|
bash -c "cd /opt/backend
|
|
&& env -u VIRTUAL_ENV uv run --no-sync python -m app.detection.internal_alerts --help
|
|
&& env -u VIRTUAL_ENV uv run --no-sync python -m app.cli generate-recommendations --help
|
|
&& env -u VIRTUAL_ENV uv run --no-sync python -m app.etl.historical_import --help
|
|
&& env -u VIRTUAL_ENV uv run --no-sync python -m app.etl.mock_api_import --help"
|