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 `