Repository navigation
416 lines (356 loc) · 18.3 KB
/
Copy pathci.yml
File metadata and controls
416 lines (356 loc) · 18.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
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:
# Dans un conteneur, le shell par défaut des étapes run est sh (dash) :
# les scripts du workflow utilisent des tableaux bash (i18n) -> bash imposé.
defaults:
run:
shell: bash
jobs:
quality:
name: Qualité (lint, format, import-linter, tests)
runs-on: ${{ fromJSON(vars.NETCROSS_RUNS_ON || '"ubuntu-latest"') }}
container:
image: ubuntu:26.04
options: --privileged
steps:
- name: Prérequis du conteneur (git, certificats, compilateur)
# ubuntu:26.04 est une image minimale : ni git (checkout et diff i18n),
# ni certificats, ni gcc (roues pygobject/pycairo compilées localement),
# ni python3 (scripts du dépôt), ni sudo (scripts/smoke-test-packages.sh).
run: |
DEBIAN_FRONTEND=noninteractive apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates curl build-essential sudo python3 python3-venv
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- 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" \
| debconf-set-selections
DEBIAN_FRONTEND=noninteractive apt-get update -qq
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 \
tests/test_split_by_interface.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: ${{ fromJSON(vars.NETCROSS_RUNS_ON || '"ubuntu-latest"') }}
container:
image: ubuntu:26.04
options: --privileged
steps:
- name: Prérequis du conteneur (git, certificats, compilateur)
# ubuntu:26.04 est une image minimale : ni git (checkout et diff i18n),
# ni certificats, ni gcc (roues pygobject/pycairo compilées localement),
# ni python3 (scripts du dépôt), ni sudo (scripts/smoke-test-packages.sh).
run: |
DEBIAN_FRONTEND=noninteractive apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates curl build-essential sudo python3 python3-venv
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- 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" \
| debconf-set-selections
DEBIAN_FRONTEND=noninteractive apt-get update -qq
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)
# Python seul : natif sur les runners maison (Ubuntu 20.04, Python par
# uv), sans conteneur. Repli GitHub : variable NETCROSS_RUNS_ON_LEGER.
runs-on: ${{ fromJSON(vars.NETCROSS_RUNS_ON_LEGER || '{"group":"maison","labels":["self-hosted","linux"]}') }}
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: ${{ fromJSON(vars.NETCROSS_RUNS_ON || '"ubuntu-latest"') }}
container:
image: ubuntu:26.04
options: --privileged
steps:
- name: Prérequis du conteneur (git, certificats, compilateur)
# ubuntu:26.04 est une image minimale : ni git (checkout et diff i18n),
# ni certificats, ni gcc (roues pygobject/pycairo compilées localement),
# ni python3 (scripts du dépôt), ni sudo (scripts/smoke-test-packages.sh).
run: |
DEBIAN_FRONTEND=noninteractive apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates curl build-essential sudo python3 python3-venv
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- 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" \
| debconf-set-selections
DEBIAN_FRONTEND=noninteractive apt-get update -qq
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)
# Python seul : natif sur les runners maison (Ubuntu 20.04, Python par
# uv), sans conteneur. Repli GitHub : variable NETCROSS_RUNS_ON_LEGER.
runs-on: ${{ fromJSON(vars.NETCROSS_RUNS_ON_LEGER || '{"group":"maison","labels":["self-hosted","linux"]}') }}
steps:
- name: Checkout du dépôt
uses: actions/checkout@v7
- name: Installation de uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
- name: Installation de Python 3.14 (uv)
# Python système trop ancien sur les runners maison (3.8) : venv uv.
run: |
uv venv --python 3.14 --seed "$RUNNER_TEMP/venv"
echo "$RUNNER_TEMP/venv/bin" >> "$GITHUB_PATH"
- 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: ${{ fromJSON(vars.NETCROSS_RUNS_ON || '"ubuntu-latest"') }}
container:
image: ubuntu:26.04
options: --privileged
steps:
- name: Prérequis du conteneur (git, certificats, compilateur)
# ubuntu:26.04 est une image minimale : ni git (checkout et diff i18n),
# ni certificats, ni gcc (roues pygobject/pycairo compilées localement),
# ni python3 (scripts du dépôt), ni sudo (scripts/smoke-test-packages.sh).
run: |
DEBIAN_FRONTEND=noninteractive apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq git ca-certificates curl build-essential sudo python3 python3-venv
git config --global --add safe.directory "$GITHUB_WORKSPACE"
- name: Checkout du dépôt (historique complet pour le diff)
uses: actions/checkout@v7
with:
fetch-depth: 0
- name: Installation de Python 3.14 (paquet Ubuntu 26.04)
# setup-python ne publie pas de build pour ubuntu 26.04 : Python du
# système dans un venv (PEP 668 interdit pip hors venv).
run: |
python3 --version
python3 -m venv "$RUNNER_TEMP/venv"
echo "$RUNNER_TEMP/venv/bin" >> "$GITHUB_PATH"
- name: Installer gettext
run: |
DEBIAN_FRONTEND=noninteractive apt-get update -qq
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"