From ccf836f2c59b79b7f533b62489831f9bc9218c6a Mon Sep 17 00:00:00 2001 From: william Date: Fri, 18 Sep 2026 16:38:29 +0200 Subject: [PATCH] Lot 4 modernisation JS (SonarLint) + restauration CI sonarqube non-bloquante Corrige les findings SonarQube (via SonarLint IDE, fichier par fichier) sur ~24 fichiers static/js/ : parseFloat/parseInt -> Number.*, .replace(/x/g,y) -> .replaceAll, .indexOf() -> .includes()/.startsWith(), getAttribute/setAttribute -> .dataset, tableaux -> Set, x && x.y -> x?.y (verifie site par site), extraction de template litteraux imbriques, ternaires imbriquees, refactors de complexite cognitive (S3776) via tables de dispatch, Object.hasOwn, .at(), et deduplication de fonctions identiques (S4144). Deux exceptions S2486 documentees/corrigees (filter-repeater-rows.js) et un cas S2703 de partage inter-scripts complete (_collisionWizard, trigger-editor.js <-> collision-rules-editor.js). Details complets dans CODE_QUALITY.md section 5. Restaure aussi le job CI "sonarqube" (non-bloquant) dans .gitea/workflows/deploy.yml maintenant que l'instance prod est operationnelle. Suites vertes : 276/276 JS (node --test), 591/591 Python (pytest). SKIP=djlint sur ce commit : hook djlint bloquant sur le backlog H021 (styles inline, 49 occurrences/6 templates) deja documente comme dette assumee non traitee dans CODE_QUALITY.md section 6, aucun rapport avec ce commit (aucun template touche ici) - valide explicitement avec l'utilisateur avant de contourner ce hook. Co-Authored-By: Claude Sonnet 5 --- .gitea/workflows/deploy.yml | 47 +- CODE_QUALITY.md | 17 +- static/js/ia/ia-chat.js | 6 +- static/js/play/__tests__/actions.test.js | 398 ++++++++++- .../collision-dialogue-integration.test.js | 5 + .../collision-rules-controller.test.js | 16 +- .../__tests__/dialogue-box-controller.test.js | 43 +- .../play/__tests__/quiz-box-templates.test.js | 3 + static/js/play/actions.js | 627 ++++++++++-------- static/js/play/bindings.js | 62 +- static/js/play/collision-rules-controller.js | 209 +++--- static/js/play/conditions.js | 32 +- static/js/play/dialogue-box-controller.js | 153 +++-- .../__tests__/filter-repeater-rows.test.js | 22 + .../__tests__/render-special-widgets.test.js | 115 ++++ static/js/play/offline/compute-operation.js | 119 ++-- .../js/play/offline/filter-repeater-rows.js | 26 +- static/js/play/offline/render-element.js | 34 +- static/js/play/offline/render-jauge.js | 89 ++- static/js/play/offline/render-overlay.js | 2 +- static/js/play/offline/render-repeater.js | 8 +- .../js/play/offline/render-special-widgets.js | 10 +- static/js/play/personnage-controller.js | 184 ++--- static/js/play/quiz-box-templates.js | 33 +- static/js/play/screen-triggers-controller.js | 2 +- static/js/play/screens.js | 10 +- static/js/play/triggers.js | 9 +- static/js/scenes/collision-rules-editor.js | 17 +- static/js/scenes/global-variables.js | 2 +- static/js/scenes/scene-editor.js | 112 ++-- static/js/screen_edit/panel-init.js | 29 +- static/js/screen_edit/personnage-panel.js | 2 +- static/js/screen_edit/personnage-preview.js | 4 +- static/js/screen_edit/tree-panels.js | 33 +- static/js/triggers/trigger-editor.js | 64 +- static/object_form.js | 14 +- 36 files changed, 1720 insertions(+), 838 deletions(-) diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 00fd3d70..39610926 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -4,12 +4,13 @@ on: push: branches: [main, dev] -# Les jobs "test-*"/"lint-*" tournent sur CHAQUE push (main et dev) : -# jusqu'ici aucune étape de CI n'exécutait la suite de tests ni les outils -# qualité, rien n'empêchait un commit cassé d'atteindre la production (voir -# l'audit qualité de la Phase 0 du plan). "build-and-push"/"deploy", eux, -# restent réservés à main (via le filtre "if" sur gitea.ref) — un push sur -# dev ne doit jamais redéployer la prod, seulement faire tourner tests/lint. +# Les jobs "test-*"/"lint-*"/"sonarqube" tournent sur CHAQUE push (main et +# dev) : jusqu'ici aucune étape de CI n'exécutait la suite de tests ni les +# outils qualité, rien n'empêchait un commit cassé d'atteindre la +# production (voir l'audit qualité de la Phase 0 du plan). "build-and- +# push"/"deploy", eux, restent réservés à main (via le filtre "if" sur +# gitea.ref) — un push sur dev ne doit jamais redéployer la prod, seulement +# faire tourner tests/lint/sonar. # # lint-python/lint-js rejouent EXACTEMENT les hooks pre-commit locaux # (.pre-commit-config.yaml) mais bloquants ici dès le départ (déjà tous @@ -17,11 +18,11 @@ on: # les hooks pre-commit ne protègent que la machine du committeur, jamais # un push direct ou une PR mergée depuis ailleurs. djlint EXCLU # volontairement (49 H021 "styles inline" déjà en backlog assumé, voir -# CODE_QUALITY.md) — à ajouter ici quand ce lot sera traité. -# -# SonarQube (job CI + service prod) retiré pour l'instant — voir -# CODE_QUALITY.md pour le contexte (accès instance locale/prod bloqué par -# des soucis d'infra réseau, mis de côté volontairement). +# CODE_QUALITY.md) — à ajouter ici quand ce lot sera traité. sonarqube, +# lui, reste NON-BLOQUANT (continue-on-error) — remis en place le +# 18/09/2026 une fois l'instance prod opérationnelle (voir CODE_QUALITY.md +# pour l'historique du retrait temporaire), le temps que le rapport de +# code smells soit entièrement trié. # Secrets à configurer dans Gitea (Paramètres du dépôt > Actions > Secrets) : # REGISTRY_HOST adresse du registre d'images (ex: gitea.exemple.com) @@ -32,6 +33,8 @@ on: # DEPLOY_USER utilisateur SSH sur ce serveur # DEPLOY_SSH_KEY clé privée SSH (au format PEM) autorisée sur ce serveur # DEPLOY_PATH dossier sur le serveur où vit docker-compose.prod.yml (ex: /home/deploy/forge-engine) +# SONAR_TOKEN jeton d'analyse SonarQube (Mon compte > Security > Generate Token +# sur sonar.forgebase.fr) — jamais le mot de passe admin. # # Utilise directement docker/ssh/scp en ligne de commande plutôt que des # actions du marketplace, pour ne pas dépendre de la disponibilité de @@ -131,6 +134,28 @@ jobs: RUN npm run lint:css DOCKERFILE + sonarqube: + runs-on: ubuntu-latest + # Non-bloquant pendant cette premiere periode (voir le bloc de + # commentaires en tete de fichier) — un echec ici n'empeche jamais + # build-and-push/deploy, contrairement a lint-python/lint-js. + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - name: Analyse SonarQube (rapport seul, non-bloquant) + run: | + # Meme neutralisation de .dockerignore que test-python : sonar- + # project.properties couvre aussi tests/ (sonar.tests). + mv .dockerignore .dockerignore.disabled-for-ci + docker build -f - -t forge-sonar:${{ gitea.sha }} . <<'DOCKERFILE' + FROM sonarsource/sonar-scanner-cli:latest + WORKDIR /usr/src + COPY . . + DOCKERFILE + docker run --rm forge-sonar:${{ gitea.sha }} \ + -Dsonar.host.url=https://sonar.forgebase.fr \ + -Dsonar.token=${{ secrets.SONAR_TOKEN }} + build-and-push: needs: [test-python, test-js, lint-python, lint-js] if: gitea.ref == 'refs/heads/main' diff --git a/CODE_QUALITY.md b/CODE_QUALITY.md index c47e4a05..907252c1 100644 --- a/CODE_QUALITY.md +++ b/CODE_QUALITY.md @@ -81,8 +81,10 @@ ignore de fichier entier ou de règle globale — voir section 4. - `profile = "jinja"`, `max_line_length = 160`, `indent = 2`. - H021 (styles inline) : **backlog assumé, pas une exception corrigée** — voir section 6, ne pas confondre avec les vraies exceptions de la section 5. -### SonarQube — retiré pour l'instant -Le job CI `sonarqube` (`.gitea/workflows/deploy.yml`) et le service prod `sonarqube`/`sonar-postgres` (`docker-compose.prod.yml`) ont été retirés le 18/09/2026 : l'accès au dashboard (local WSL2 et prod derrière Caddy) est resté bloqué par des soucis d'infrastructure réseau (redirection de port WSL2/pare-feu Hyper-V côté local, réseau Docker partagé avec Caddy pas encore en place côté prod) sans lien avec le code du moteur — mis de côté volontairement plutôt que de continuer à bloquer sur de l'infra. Le lot "modernisation JS" (voir `docs/JS_MODERNIZATION_PLAN.md`) s'est arrêté après le lot 3 (`S2486`) pour cette même raison : les lots 4+ dépendent de scores Sonar exacts (complexité cognitive notamment) qu'aucun proxy fiable ne remplace. À reprendre une fois l'accès rétabli — voir section 6. +### SonarQube +- **CI (`sonar.forgebase.fr`)** : job `sonarqube` (`.gitea/workflows/deploy.yml`), scan à chaque push, **non-bloquant** (`continue-on-error: true`) le temps que le rapport soit entièrement trié. Retiré le 18/09/2026 (voir historique ci-dessous), remis en place le 18/09/2026 une fois l'instance prod confirmée opérationnelle. +- **Service prod** (`docker-compose.prod.yml`) : reste retiré côté dépôt pour l'instant — l'instance prod opérationnelle n'est pas (encore) pilotée par ce fichier de ce côté-ci ; à réintégrer explicitement si besoin. +- **Historique du retrait temporaire (16-18/09/2026)** : l'accès au dashboard (local WSL2 et prod derrière Caddy) était resté bloqué par des soucis d'infrastructure réseau (redirection de port WSL2/pare-feu Hyper-V côté local, réseau Docker partagé avec Caddy pas encore en place côté prod à ce moment) sans lien avec le code du moteur. Le lot "modernisation JS" (voir `docs/JS_MODERNIZATION_PLAN.md`) s'était arrêté après le lot 3 (`S2486`) pour cette même raison — les lots 4+ dépendent de scores Sonar exacts (complexité cognitive notamment) qu'aucun proxy fiable ne remplace parfaitement (le SonarLint de l'IDE a servi de solution de contournement fonctionnelle en attendant, voir lots 4 en cours directement sur les fichiers ouverts dans l'éditeur). ## 3. Lancer les checks en local @@ -106,7 +108,7 @@ python -m pytest tests/ -q node --test static/js/play/__tests__/*.test.js static/js/play/offline/__tests__/*.test.js static/js/scenes/__tests__/*.test.js ``` -SonarQube (local et CI/prod) retiré pour l'instant — voir section 2, sous-section "SonarQube — retiré pour l'instant". +SonarQube : voir section 2, sous-section "SonarQube" — CI restaurée (non-bloquante), instance locale toujours bloquée (voir historique dans cette même sous-section). ## 4. Procédure de justification d'une exception @@ -137,15 +139,18 @@ SonarQube (local et CI/prod) retiré pour l'instant — voir section 2, sous-sec | `static/js/play/bindings.js:179` (`gameData = newData`) | `javascript:S2703` | Pattern volontaire de scripts globaux (pas des modules ES) : `gameData`/`screensData` sont déclarés une fois par `let` dans le `` (voir Phase 3). Plusieurs syntaxes de suppression testées (commentaire Jinja `{# #}`, commentaire JS natif dans un `