Repository navigation
feat(#441): lot 7 netcross_report, moteur de règles, rapports et graphiques #585
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| # Issue #463 : concentration des workflows. Anciennement trois workflows | |
| # parallèles (ci.yml, docs.yml, i18n.yml) se déclenchaient sur les mêmes | |
| # push/PR vers main/dev. Ils sont fusionnés ici en un seul, réduisant le | |
| # nombre de runs simultanés et le temps d'attente des checks requis. | |
| # | |
| # Jobs : | |
| # quality — lint, format, import-linter, tests (check requis) | |
| # gtk4 — tests GTK4 sous Xvfb (check requis) | |
| # packaging — construction + test de fumée deb/rpm (check requis) | |
| # types — mypy (non bloquant, continue-on-error) | |
| # documentation — mkdocs build --strict (check requis, ex docs.yml) | |
| # i18n — catalogues gettext à jour et valides (ex i18n.yml check) | |
| "on": | |
| push: | |
| branches: [main, dev] | |
| pull_request: | |
| branches: [main, dev] | |
| workflow_dispatch: | |
| jobs: | |
| quality: | |
| name: Qualité (lint, format, import-linter, tests) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout du dépôt | |
| uses: actions/checkout@v7 | |
| - name: Installation de Wireshark CLI (tshark, editcap, capinfos) et de pdftotext | |
| # Issue #262 : tshark n'était installé dans AUCUN environnement de | |
| # développement du projet, donc toute la suite @requires_tshark / | |
| # @requires_editcap était systématiquement sautée. Deux bugs réels | |
| # (#261 filtre inutilisable, #262 format de sortie ignoré) ont ainsi | |
| # survécu des mois à une CI verte. Les installer ici rend ces tests | |
| # exécutables : c'est la seule correction qui empêche la classe entière | |
| # de régressions de redevenir invisible. | |
| # DEBIAN_FRONTEND + preseed : l'installeur de wireshark-common pose | |
| # sinon une question interactive sur les droits de capture. | |
| run: | | |
| echo "wireshark-common wireshark-common/install-setuid boolean false" \ | |
| | sudo debconf-set-selections | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq tshark poppler-utils gettext | |
| tshark --version | head -1 | |
| editcap --version | head -1 | |
| # poppler-utils fournit pdftotext, utilise par tests/test_security_outputs.py | |
| # (issue #218) pour REEXTRAIRE le texte du PDF produit au lieu de | |
| # s'arreter avant le rendu. C'est precisement le niveau de | |
| # verification qui manquait a l'issue #259 : un champ present dans | |
| # les donnees et absent du rendu final. Meme raisonnement que | |
| # tshark ci-dessus (#262) -- sauter ces tests quand l'outil manque | |
| # rendrait la CI verte en supprimant la seule verification qui | |
| # regarde le fichier livre a l'utilisateur. | |
| pdftotext -v 2>&1 | head -1 | |
| - name: Installation de uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| with: | |
| enable-cache: true | |
| - name: Installation de Python | |
| run: uv python install 3.14 | |
| - name: Installation des dépendances (extras dev + api + ai) | |
| run: uv sync --extra dev --extra api --extra ai | |
| - name: Lint (ruff check) | |
| run: uv run ruff check . | |
| - name: Formatage (ruff format --check) | |
| run: uv run ruff format --check . | |
| - name: Architecture en couches (import-linter) | |
| run: uv run lint-imports | |
| env: | |
| PYTHONPATH: src | |
| - name: Diagramme de classes à jour (issue #140) | |
| # Vérifie que docs/class-diagram.md correspond au code source de src/. | |
| # Le hook pre-commit `class-diagram` le fait en local, mais CI est le | |
| # filet de sécurité pour les contributions qui n'ont pas lancé le hook. | |
| run: python3 scripts/generate_class_diagram.py --check | |
| - name: Spécification OpenAPI à jour (issue #209) | |
| # Même filet de sécurité que le diagramme de classes ci-dessus : | |
| # docs/openapi.yaml est dérivé du code de netcross_api, il doit donc | |
| # être régénéré et commité dès qu'une route ou un modèle change. | |
| env: | |
| PYTHONPATH: src | |
| run: uv run python scripts/generate_openapi.py --check | |
| - name: Tests (pytest + couverture) | |
| # --cov sans chemin : source lue depuis [tool.coverage.run] (source = | |
| # ["src"]) dans pyproject.toml. term-missing dans les logs CI, | |
| # coverage.xml publie comme artifact (issue #224). Seuil bloquant : | |
| # fail_under dans [tool.coverage.report] (issue #246), l'etape echoue | |
| # si la couverture totale passe dessous. | |
| run: uv run pytest --cov --cov-report=term-missing --cov-report=xml | |
| - name: Aucun test sauté silencieusement (issues #261/#262) | |
| # Trace le nombre de tests sautés et échoue si la suite @requires_tshark | |
| # l'est encore : un test sauté est une vérification qui n'a pas eu lieu, | |
| # et le rapport doit le dire plutôt que de le laisser passer pour un | |
| # succès (règle de traçabilité du projet). | |
| run: | | |
| set -o pipefail | |
| uv run pytest -q -rs --no-header \ | |
| tests/test_export_filtered.py tests/test_adjust_timestamps.py \ | |
| | tee /tmp/reel.txt | |
| if grep -q "tshark non installe\|editcap non installe" /tmp/reel.txt; then | |
| echo "::error::des tests exigeant tshark/editcap ont été sautés alors que CI les installe" | |
| exit 1 | |
| fi | |
| echo "tests réels tshark/editcap : tous exécutés" | |
| - name: Vérification réelle du contenu des PDF (pdftotext non sauté) | |
| # Issue #218 : les tests de la section de sécurité du PDF réextraient | |
| # le texte du fichier produit. Sans ce garde-fou, une disparition de | |
| # poppler-utils de l'image CI rendrait ces tests « sautés » et la CI | |
| # resterait verte en ayant perdu la seule vérification qui regarde le | |
| # fichier livré à l'utilisateur. | |
| run: | | |
| set -o pipefail | |
| uv run pytest -q -rs --no-header tests/test_security_outputs.py | tee /tmp/pdf.txt | |
| if grep -q "pdftotext non installe" /tmp/pdf.txt; then | |
| echo "::error::des tests vérifiant le contenu des PDF ont été sautés alors que CI installe poppler-utils" | |
| exit 1 | |
| fi | |
| echo "tests réels pdftotext : tous exécutés" | |
| - name: Publication du rapport de couverture (artifact) | |
| # coverage.xml (format Cobertura) produit par l'etape pytest --cov ; | |
| # conserve 14 jours, temps de telechargement court. | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: coverage-report | |
| path: coverage.xml | |
| retention-days: 14 | |
| if-no-files-found: warn | |
| gtk4: | |
| # Tests GTK4 réellement exécutés (issues #357, #363, #421). | |
| # Le job Qualité n'installe ni pygobject ni libgtk-4 : tous les tests | |
| # pilotés via pygobject y sont SAUTÉS -- c'est voulu (#285/#421 : aucun | |
| # test n'exige GTK4 dans ce job). Mais un test sauté est une vérification | |
| # qui n'a pas eu lieu (#261/#262) : sans ce job, les ~180 tests des lots | |
| # de #421 ne tourneraient jamais en CI et pourraient régresser | |
| # indéfiniment sous une CI verte (un test du lot 7 échouait déjà sous | |
| # GTK4 tout en passant en CI). Ici : GTK4 + pygobject + serveur X | |
| # virtuel (Xvfb), suite complète, et échec si un test GTK est sauté. | |
| name: Tests GTK4 (Xvfb) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout du dépôt | |
| uses: actions/checkout@v7 | |
| - name: GTK4, introspection, Xvfb, tshark, pdftotext | |
| # libgirepository-2.0-dev + libcairo2-dev : compilation de | |
| # pygobject/pycairo depuis les sources si aucune roue ne convient. | |
| run: | | |
| echo "wireshark-common wireshark-common/install-setuid boolean false" \ | |
| | sudo debconf-set-selections | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \ | |
| gir1.2-gtk-4.0 libgirepository-2.0-dev libcairo2-dev pkg-config \ | |
| xvfb xauth tshark poppler-utils gettext | |
| - name: Installation de uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| with: | |
| enable-cache: true | |
| - name: Installation de Python | |
| run: uv python install 3.14 | |
| - name: Installation des dépendances (extras dev + api + ai, pygobject) | |
| # pygobject n'est pas une dépendance du projet (la GUI utilise celui | |
| # du système via le paquet) : installé ici dans le venv de test. | |
| run: | | |
| uv sync --extra dev --extra api --extra ai | |
| uv pip install pygobject pycairo | |
| - name: Tests sous Xvfb, aucun test GTK sauté | |
| # Motifs de saut : tests/gtk4_display.py. -p no:cacheprovider : | |
| # rien à conserver entre deux exécutions de ce job. | |
| run: | | |
| set -o pipefail | |
| xvfb-run -a uv run pytest -q -rs --no-header -p no:cacheprovider \ | |
| --cov=netcross_gtk4 --cov-report=term --cov-fail-under=0 \ | |
| | tee /tmp/gtk4.txt | |
| if grep -qE "pygobject absent|GTK4 absent|pas d'affichage pour GTK4" /tmp/gtk4.txt; then | |
| echo "::error::des tests GTK4 ont été sautés alors que ce job installe GTK4 et Xvfb" | |
| exit 1 | |
| fi | |
| echo "tests GTK4 : tous exécutés" | |
| types: | |
| # Verification statique des types (issue #281). | |
| # NON BLOQUANT pour l instant : continue-on-error = true. | |
| # Deviendra bloquant des que la baseline atteint 0 sur les modules | |
| # stricts (bascule : retirer continue-on-error + ajouter les modules | |
| # dans [[tool.mypy.overrides]] de pyproject.toml). | |
| name: Types (mypy) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout du dépôt | |
| uses: actions/checkout@v7 | |
| - name: Installation de uv | |
| uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 | |
| with: | |
| enable-cache: true | |
| - name: Installation de Python | |
| run: uv python install 3.14 | |
| - name: Installation des dépendances (extras dev) | |
| run: uv sync --extra dev | |
| - name: Vérification des types (mypy) | |
| run: uv run mypy | |
| packaging: | |
| # Issue #342 : la casse du .deb (#336, sous-paquets et pcap_parser non | |
| # installes) est passee inapercue faute de job qui construise PUIS | |
| # installe le paquet. Ce job teste le paquet tel que l'utilisateur le | |
| # recoit : installation apt, --help de chaque lanceur, import de chaque | |
| # module avec /usr/bin/python3, analyse reelle d'une capture. | |
| name: Paquets (deb installé, rpm vérifié) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout du dépôt | |
| uses: actions/checkout@v7 | |
| - name: Outils de construction (debhelper, rpm) et tshark | |
| run: | | |
| echo "wireshark-common wireshark-common/install-setuid boolean false" \ | |
| | sudo debconf-set-selections | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \ | |
| build-essential debhelper dpkg-dev gettext rpm tshark | |
| - name: Construction du .deb | |
| run: ./build-deb/build.sh | |
| - name: Test de fumée du .deb installé | |
| run: ./scripts/smoke-test-packages.sh deb build-deb/dist/netcross_*_all.deb | |
| - name: Construction du .rpm | |
| run: ./build-rpm/build.sh | |
| - name: Vérification du contenu du .rpm | |
| run: ./scripts/smoke-test-packages.sh rpm build-rpm/dist/netcross-*.noarch.rpm | |
| - name: Publication des paquets (artifact) | |
| if: always() | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: paquets | |
| path: | | |
| build-deb/dist/*.deb | |
| build-rpm/dist/*.rpm | |
| retention-days: 7 | |
| if-no-files-found: warn | |
| documentation: | |
| # Ex docs.yml (issue #282). Check requis par la protection de dev : | |
| # le nom du job doit rester « Construction (mkdocs build --strict) ». | |
| # Pas de if: -- check_branch_protection.py --hors-ligne ignore les jobs | |
| # conditionnels. | |
| name: Construction (mkdocs build --strict) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout du dépôt | |
| uses: actions/checkout@v7 | |
| - name: Installation de Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.14" | |
| - name: Installation de mkdocs-material | |
| run: pip install mkdocs-material pymdown-extensions | |
| - name: Construction (strict -- échoue sur lien mort) | |
| run: mkdocs build --strict | |
| - name: Upload de l'artefact (site HTML) | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: mkdocs-site | |
| path: site/ | |
| i18n: | |
| # Ex i18n.yml check (issue #299). Vérifie que les catalogues de traduction | |
| # gettext sont à jour avec les sources, valides et compilables. | |
| # Non requis par la protection de dev : peut avoir un if: de filtre, mais | |
| # les fichiers concernés (src/**/*.py, lang/**) couvrent la majeure partie | |
| # du code, donc le job tourne sur toutes les PR/push. | |
| name: i18n (catalogues à jour) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout du dépôt (historique complet pour le diff) | |
| uses: actions/checkout@v7 | |
| with: | |
| fetch-depth: 0 | |
| - name: Installation de Python | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.14" | |
| - name: Installer gettext | |
| run: | | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get update -qq | |
| sudo DEBIAN_FRONTEND=noninteractive apt-get install -y -qq gettext | |
| - name: Catalogues à jour et valides | |
| id: sync | |
| continue-on-error: ${{ github.event_name != 'pull_request' }} | |
| run: ./scripts/i18n-update.sh --check | |
| - name: Compilation de toutes les locales | |
| run: ./scripts/i18n-update.sh --compile "$RUNNER_TEMP/locale" | |
| - name: Résumé | |
| if: always() | |
| env: | |
| BASE: ${{ github.event.pull_request.base.sha || github.event.before }} | |
| run: | | |
| since=() | |
| if [ -n "$BASE" ] && git cat-file -e "$BASE^{commit}" 2>/dev/null; then since=(--since "$BASE"); fi | |
| python3 scripts/i18n_report.py --compiled "$RUNNER_TEMP/locale" "${since[@]}" | |
| python3 scripts/i18n_report.py --markdown --compiled "$RUNNER_TEMP/locale" "${since[@]}" >> "$GITHUB_STEP_SUMMARY" | |
| python3 scripts/i18n_report.py --strict > /dev/null | |
| - name: Catalogues désynchronisés | |
| if: steps.sync.outcome == 'failure' | |
| run: echo "::warning::catalogues à régénérer -- le job update ouvre la PR de mise à jour" |