Phase 4 (CI) : lint-python/lint-js bloquants + sonarqube non-bloquant
Build and deploy / test-python (push) Successful in 13m44s
Build and deploy / test-js (push) Successful in 1m27s
Build and deploy / lint-python (push) Successful in 4m32s
Build and deploy / lint-js (push) Successful in 3m5s
Build and deploy / build-and-push (push) Skipped
Build and deploy / deploy (push) Skipped
Build and deploy / sonarqube (push) Failing after 4m3s

Les hooks pre-commit locaux (deja tous verts, voir le commit Phase 3) ne
protegent que la machine du committeur, jamais un push direct ou une PR
mergee depuis ailleurs sans passer par ces hooks. Ajoute donc en CI :

- lint-python (ruff check/format, mypy --strict, vulture, bandit,
  import-linter) et lint-js (eslint, stylelint) : bloquants des
  maintenant, memes commandes que .pre-commit-config.yaml, deja verts en
  local donc aucune raison d'attendre. djlint volontairement exclu (49
  H021 deja en backlog assume, a ajouter ici une fois ce lot traite).
  build-and-push en depend desormais (needs), en plus des tests deja en
  place.

- sonarqube : scan contre l'instance self-hebergee (sonar.forgebase.fr)
  a chaque push. continue-on-error: true au niveau du job (non-bloquant
  pendant cette premiere periode, le temps de trier le rapport deja
  analyse en Phase 3 - code smells/vulnerabilites), et absent du needs
  de build-and-push : un echec ici n'affecte jamais le reste du
  pipeline, meme si l'infra n'est pas encore prete (echec attendu tant
  que SONAR_TOKEN n'est pas configure cote Gitea).

Secret a ajouter dans Gitea (Parametres du depot > Actions > Secrets) :
SONAR_TOKEN (jeton d'analyse genere sur sonar.forgebase.fr, jamais le
mot de passe admin).

djLint (H021, styles inline) volontairement saute pour ce commit - meme
backlog assume que le commit Phase 3, aucun rapport avec ce changement.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
william
2026-09-15 16:26:21 +02:00
co-authored by Claude Sonnet 5
parent c57420c8c9
commit 2ff127f68e
+85 -7
View File
@@ -4,12 +4,26 @@ on:
push:
branches: [main, dev]
# Le job "test" tourne sur CHAQUE push (main et dev) : jusqu'ici aucune
# étape de CI n'exécutait la suite de tests, 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 les tests.
# 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
# verts en local, voir le commit "Phase 3 : hardening qualite de code") —
# 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,
# lui, reste NON-BLOQUANT (continue-on-error) pendant cette première
# période — voir CODE_QUALITY.md pour la trajectoire vers un mode
# bloquant une fois le rapport trié (code smells, vulnerabilites) plutôt
# que de bloquer tout de suite sur des centaines de signalements pas
# encore triés.
# Secrets à configurer dans Gitea (Paramètres du dépôt > Actions > Secrets) :
# REGISTRY_HOST adresse du registre d'images (ex: gitea.exemple.com)
@@ -20,6 +34,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
@@ -79,8 +95,70 @@ jobs:
RUN node --test static/js/play/__tests__/*.test.js static/js/scenes/__tests__/*.test.js
DOCKERFILE
lint-python:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Qualite Python (ruff/mypy/vulture/bandit/import-linter — memes commandes que .pre-commit-config.yaml)
run: |
# Meme neutralisation de .dockerignore que test-python ci-dessus :
# ruff/mypy typent aussi tests/ (voir le plan de typage strict),
# exclu par defaut de l'image de PROD.
mv .dockerignore .dockerignore.disabled-for-ci
docker build -f - -t forge-lint-python:${{ gitea.sha }} . <<'DOCKERFILE'
FROM python:3.13-slim
WORKDIR /app
COPY requirements.txt requirements-dev.txt ./
RUN pip install --no-cache-dir -r requirements-dev.txt
COPY . .
RUN ruff check .
RUN ruff format --check .
RUN mypy .
RUN vulture
RUN bandit -c pyproject.toml -r ai auth core db filters publish routes screens scripts app.py build_css.py
RUN lint-imports
DOCKERFILE
lint-js:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Qualite JS/CSS (eslint/stylelint — memes commandes que .pre-commit-config.yaml, via les scripts npm de package.json)
run: |
docker build -f - -t forge-lint-js:${{ gitea.sha }} . <<'DOCKERFILE'
FROM node:20-slim
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run lint:js
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]
needs: [test-python, test-js, lint-python, lint-js]
if: gitea.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps: