5.6 KiB
Conventions et revue avant livraison
Ce fichier existe pour que le projet reste cohérent d'une version à l'autre, et pour qu'une anomalie soit trouvée sur le poste de développement plutôt qu'après soixante minutes de construction.
Revue avant chaque livraison
Dans cet ordre, sans exception, y compris pour un correctif d'une ligne :
python -m ruff check . # analyse statique, zéro signalement toléré
python -m pytest -q # la suite complète
node --check enclume/static/*.js # syntaxe des scripts
sh tests/interface.sh # l'editeur, dans un DOM headless
sh -n docker/*.sh # syntaxe des scripts shell
python -c "import yaml,glob;[yaml.safe_load(open(f)) for f in glob.glob('catalog/**/*.yml',recursive=True)]"
docker compose -f compose.yaml config > /dev/null
Puis, dans un environnement vierge — c'est ce qui a manqué le jour où requests a cassé la
CI :
python -m venv /tmp/vierge && /tmp/vierge/bin/pip install -r requirements.txt pytest
/tmp/vierge/bin/python -m pytest -q
Et enfin la revue humaine, qui ne s'automatise pas :
- toute ressource référencée par un gabarit existe-t-elle réellement ? (un test le vérifie désormais, parce que l'oubli a déjà eu lieu)
- les noms d'hôte, de dépôt et de domaine cités dans la documentation et les exemples sont-ils
encore les bons ? Ni
ruffni les tests ne lisent le Markdown. - une variable nouvelle est-elle présente dans
.env.example, danscompose.yamlet documentée ? - une valeur venant de l'utilisateur peut-elle contenir un caractère qui casse le format où
on l'insère ? Point-virgule pour le CLAPI,
@et:pour une URL de connexion, guillemet simple pour le shell,%pour un fichier ini lu par configparser. Quatre incidents sur ce seul motif — c'est le premier endroit où regarder. - une modification a-t-elle réellement été appliquée ? Une correction annoncée en 1.11.1 n'avait jamais pris : le texte recherché avait changé entre-temps. Relire le fichier après l'édition, et faire passer un test par le chemin réel, pas seulement par la couche voisine.
- une valeur déjà encodée traverse-t-elle un second format qui réinterprète son encodage ?
C'est la variante du piège précédent :
%40est correct dans une URL, et devient une interpolation dans un ini. - ce qui est écrit en base a-t-il traversé
strip_secrets?
Un principe : le moins de saisie libre possible
Chaque champ de texte libre est une occasion de faute de frappe qui ne se verra qu'au déploiement sur le central. Un champ nouveau doit donc, dans l'ordre de préférence :
- une liste fermée quand les valeurs possibles sont connues et finies — un fuseau horaire, un type de commande, une version SNMP ;
- une liste ouverte avec suggestions quand des valeurs existent déjà sur le central que nous ne connaissons pas — un modèle parent, un groupe d'hôtes, une commande de vérification ;
- la saisie libre seulement pour ce qui est propre à l'utilisateur : un nom, une description, un seuil.
Et quand une valeur juste est majoritairement la même, elle est préremplie. Un projet
vide part avec /usr/lib/centreon/plugins, generic-active-host-custom et Central :
l'utilisateur corrige si son installation diffère, il ne devine pas.
Nommage
| Objet | Règle | Exemple |
|---|---|---|
| Modules Python | français, minuscules, sans accent | routes_donnees.py |
| Fonctions et variables | français, snake_case |
utilisateur_courant, _repertoire_catalogue |
| Classes | français, PascalCase |
Soumission, Prerequis |
| Variables d'environnement | préfixe ENCLUME_, majuscules |
ENCLUME_DB_MOTDEPASSE |
| Routes d'API | français, pluriel | /api/soumissions, /api/partages |
| Identifiants HTML | français, kebab-case |
btn-serveur-ouvrir, filtre-statut |
| Fichiers statiques | français | editeur.js, moderation.js |
| Tables | français, pluriel | utilisateurs, partages |
| Packs du catalogue | <famille>-<techno>[-<protocole>] |
os-linux-snmp, hw-dell-idrac-snmp |
| Modèles d'hôte générés | <Famille>-<Techno>-custom |
OS-Linux-SNMP-custom |
| Modèles de service | <Famille>-<Techno>-<Sonde> |
OS-Linux-SNMP-Cpu |
| Images | <registre>/enclume/<composant> |
.../enclume/catalog-sync |
| Branches de soumission | pack/<id>-<numéro> |
pack/app-rabbitmq-7 |
Les commentaires et la documentation sont en français. Le code source reste sans accents, par choix, pour éviter toute question d'encodage dans les conteneurs.
Versions
Sémantique stricte, parce que la rétention Harbor et le retour arrière s'y appuient :
- correctif (
1.1.2) : rien de nouveau, rien qui change de nom - mineure (
1.2.0) : fonctionnalité, nouvelle variable, migration de schéma - majeure (
2.0.0) : rupture pour qui héberge déjà — variable supprimée, format de projet incompatible
Une migration de schéma n'ajoute que des colonnes et des tables. Une suppression attend la version suivante, sinon revenir à l'image précédente casse l'application.
Coût de construction
L'arm64 passe par l'émulation QEMU et coûte l'essentiel du temps de construction. Il n'est
donc produit que sur un tag de version ; un simple push sur main ne construit que
l'amd64. Le cache de couches vit dans Harbor, à côté des images : tant que
requirements.txt ne change pas, l'installation des dépendances est reprise du cache.
Conséquence pratique : itérer sur main est rapide, publier une version reste lent. Autant
grouper les corrections avant de taguer.