Files
Workflow config file is invalid. Please check your config file: yaml: line 5: mapping values are not allowed in this context
Serreau Jovann 6fa970e60d refactor: rebrand project to CRM SITECONSEIL (SARL SITECONSEIL)
- Rename all references from E-Cosplay/Ecosplay to SITECONSEIL
- Update entity from Association to SARL SITECONSEIL (Siret: 418664058)
- Update address to 27 rue Le Serurier, 02100 Saint-Quentin
- Update emails: contact@siteconseil.fr, rgpd@siteconseil.fr
- Update hosting from GCP to OVHcloud (Roubaix, Gravelines, Strasbourg, Paris)
- Update legal pages: mentions legales, CGV, RGPD, conformite, hebergement, cookies, CGU
- Add tarifs page with tabs: Site Internet, E-Commerce, Nom de domaine, Esy-Mail, Esy-Mailer, Esy-Tchat, Esy-Meet, Esy-Defender
- Add Discord webhook notification workflow
- Disable deploy and sonarqube workflows
- Update OAuth Keycloak realm to master
- Update logo references to logo_facture.png
- Remove forced image sizing in Liip Imagine filters
- Update SonarQube project key and badge token
- Update tribunal competent to Saint-Quentin
- Move tarif tabs JS to app.js (CSP compliance)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 18:48:25 +02:00

354 lines
18 KiB
YAML

j'ai gitea + sonarqube auto hébger tu me conseiler quoi en plus pour analyser le code php
13:35
Bonne question ! Avec Gitea + SonarQube déjà en place, voici ce que je te recommanderais pour compléter ta chaîne d'analyse PHP :
Analyse statique complémentaire — Tu utilises déjà PHPStan via SonarQube, mais le lancer aussi en standalone (niveau max) te donne un feedback plus rapide dans ta CI. Psalm est une alternative/complément intéressant, surtout pour l'analyse de type et la détection de dead code. Les deux peuvent coexister.
Style & standards — PHP CS Fixer ou PHP_CodeSniffer pour enforcer un coding standard (PSR-12 ou custom). PHP CS Fixer s'intègre bien dans un pre-commit hook ou un job CI Gitea Actions/Drone.
Sécurité — Snyk ou Trivy pour scanner les dépendances Composer (CVE). Trivy est self-hostable et peut aussi scanner tes images Docker, ce qui colle bien avec ton stack. Semgrep est aussi un bon choix pour des règles de sécurité custom sur le code PHP (OWASP patterns, injections SQL, XSS).
Complexité & dette technique — PHPMetrics génère des rapports HTML visuels sur la complexité cyclomatique, le couplage, la maintenabilité. Ça complète bien SonarQube avec une vue plus "architecturale". dePHPend analyse les dépendances entre classes/packages pour détecter les couplages problématiques.
Tests & couverture — Si pas déjà en place, PHPUnit + Infection (mutation testing) pour mesurer la qualité réelle de tes tests, pas juste le coverage brut. SonarQube peut ingérer les rapports de coverage PHPUnit.
En priorité pour ton contexte (multi-tenant, ~85 sites ESY-WEB), je partirais sur :
PHPStan niveau max en CI (si pas déjà fait en standalone)
Trivy (scan dépendances Composer + images Docker — tu as déjà le stack Docker)
PHP CS Fixer en pre-commit
PHPMetrics pour le reporting visuel
Tout ça s'orchestre bien avec des Gitea Actions ou un pipeline Makefile, ce qui colle avec ton workflow habituel. Tu veux que je t'aide à mettre en place un de ces outils en particulier ?
name: CI on: push: branches: - master - main pull_request: jobs: sonarqube: runs_on: ubuntu-latest services: database: image: postgres:16-alpine env: POSTGRES_USER: app POSTGRES_PASSWORD: secret POS
pasted
j'ai deja tout sa
13:36
Ah ok, t'es déjà bien équipé ! Ton pipeline est solide. Voici ce qui manque et qui aurait une vraie valeur ajoutée :
Sécurité applicative — Semgrep pour de l'analyse SAST orientée patterns PHP (injections SQL, XSS, SSRF, deserialize unsafe). OWASP Dependency-Check couvre les dépendances, mais pas le code lui-même. Semgrep est gratuit en CLI et s'ajoute en une step.
Qualité / dette — PHPMetrics pour un rapport HTML visuel (complexité cyclomatique, couplage, maintenabilité par classe). SonarQube donne des métriques mais PHPMetrics a une vue "bubble chart" par classe qui aide à prioriser le refacto. Très rapide à ajouter, pas besoin de services.
Tests — Infection (mutation testing). Tu as déjà PHPUnit + coverage, mais le coverage seul ne dit pas si tes tests détectent vraiment les régressions. Infection mute ton code et vérifie que les tests cassent. Ça s'intègre bien avec le coverage.xml que tu génères déjà.
Infra/Docker — Trivy en remplacement ou complément de Hadolint. Hadolint lint les Dockerfiles, Trivy scanne les images buildées (CVE dans les packages OS + dépendances). Vu ton stack multi-container c'est pertinent.
Frontend — Lighthouse CI si tu as des pages publiques côté SITECONSEIL. Perf, accessibilité, SEO en une step.
En résumé les ajouts concrets :
yaml
- name: Semgrep SAST
run: |
pip install semgrep --break-system-packages
semgrep scan --config=auto --json -o semgrep-report.json src/ || true
- name: PHPMetrics
run: |
composer global require phpmetrics/phpmetrics --no-interaction
phpmetrics --report-html=phpmetrics-report src/
- name: Infection (mutation testing)
run: |
vendor/bin/infection --threads=4 --min-msi=50 --min-covered-msi=60 --logger-json=infection-report.json || true
Semgrep est le plus impactant vu que t'as zéro SAST sur le code source actuellement — OWASP DC ne couvre que les dépendances. Tu veux que je t'intègre ça proprement dans ton workflow complet ?
name: CI on: push: branches: - master - main pull_request: jobs: sonarqube: runs_on: ubuntu-latest services: database: image: postgres:16-alpine env: POSTGRES_USER: app POSTGRES_PASSWORD: secret POS
pasted
13:37
Nickel, t'as intégré les trois. Ton pipeline est maintenant très complet. Quelques remarques d'optimisation :
Problème potentiel avec Infection — il a besoin du coverage.xml généré par PHPUnit, mais il faut lui passer explicitement. Vérifie que ton infection.json5 pointe bien dessus, sinon ajoute --coverage=coverage.xml ou mieux, utilise le flag --skip-initial-tests si tu veux qu'il réutilise le coverage existant.
PHPMetrics — composer global require peut être lent en CI. Une alternative plus rapide :
yaml
- name: PHPMetrics
run: |
wget -qO phpmetrics.phar https://github.com/phpmetrics/PhpMetrics/releases/latest/download/phpmetrics.phar
php phpmetrics.phar --report-html=phpmetrics-report src/
Semgrep — pip install en CI c'est aussi un peu lent. L'image Docker officielle est plus rapide :
yaml
- name: Semgrep SAST
run: |
docker run --rm -v "${GITHUB_WORKSPACE}:/src" semgrep/semgrep semgrep scan --config=auto --json -o /src/semgrep-report.json /src/src/ || true
Mais vu que t'es sur Gitea Actions (pas GitHub), vérifie que le Docker-in-Docker fonctionne dans ton runner. Sinon le pip install reste le plus safe.
Ce qui manque pour boucler — tous ces rapports (semgrep, phpmetrics, infection, hadolint) sont générés mais pas exploités. Deux options :
SonarQube — configure sonar.externalIssuesReportPaths dans ton sonar-project.properties pour ingérer les JSON de Semgrep et Hadolint. SonarQube les affichera comme "external issues".
Artifacts — upload les rapports comme artifacts de build pour les consulter après :
yaml
- name: Upload reports
uses: actions/upload-artifact@v3
with:
name: ci-reports
path: |
semgrep-report.json
phpmetrics-report/
infection-report.json
hadolint-*.json
dependency-check-report.*
eslint-report.json
phpstan-report.json
Ça te permettrait de consulter le rapport PHPMetrics HTML directement. Tu veux que je te génère le sonar-project.properties adapté avec l'import des rapports externes ?
name: CI on: push: branches: - master - main pull_request: jobs: sonarqube: runs_on: ubuntu-latest services: database: image: postgres:16-alpine env: POSTGRES_USER: app POSTGRES_PASSWORD: secret POS
pasted
13:38
OK, quelques corrections à faire sur ton workflow actuel :
PHPMetrics — tu mélanges les deux approches. Tu fais composer global require mais ensuite php phpmetrics.phar (qui n'existe pas puisque t'as pas téléchargé le phar). Choisis l'un ou l'autre :
yaml
# Option A : phar (plus rapide)
- name: PHPMetrics
run: |
wget -qO phpmetrics.phar https://github.com/phpmetrics/PhpMetrics/releases/latest/download/phpmetrics.phar
php phpmetrics.phar --report-html=phpmetrics-report src/
# Option B : composer global
- name: PHPMetrics
run: |
composer global require phpmetrics/phpmetrics --no-interaction
~/.composer/vendor/bin/phpmetrics --report-html=phpmetrics-report src/
Semgrep Docker — attention, sur Gitea Actions le ${GITHUB_WORKSPACE} n'existe probablement pas. Selon ton runner Gitea, ça sera plutôt ${GITEA_WORKSPACE} ou ${{ github.workspace }} (si ton runner est compatible). Vérifie, sinon reviens au pip install qui est plus portable :
yaml
- name: Semgrep SAST
run: |
pip install semgrep --break-system-packages
semgrep scan --config=auto --json -o semgrep-report.json src/ || true
Upload des artifacts + sonar-project.properties — tu veux que je te génère les deux fichiers ? Le sonar-project.properties avec l'import de tous tes rapports externes (Semgrep, PHPStan, ESLint, Hadolint, coverage), et la step d'upload artifacts à ajouter en fin de pipeline ?
sort tout le workflow stp
13:38
Voici le workflow complet corrigé :
Presenting files
Presenting files
Workflow CI complet corrigé avec tous les outils d'analyse
ci.yml
sonar-project.properties avec import de tous les rapports externes
sonar-project.properties
Presenting file(s)...
Claude est une IA et peut faire des erreurs. Veuillez vérifier les réponses.
Ci · YML
Copier
name: CI
on:
push:
branches:
- master
- main
pull_request:
jobs:
ci:
runs_on: ubuntu-latest
services:
database:
image: postgres:16-alpine
env:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret
POSTGRES_DB: crm_siteconseil
options: >-
--health-cmd "pg_isready -U app -d crm_siteconseil"
--health-interval 5s
--health-timeout 5s
--health-retries 5
redis:
image: redis:7-alpine
options: >-
--health-cmd "redis-cli ping"
--health-interval 5s
--health-timeout 5s
--health-retries 5
meilisearch:
image: getmeili/meilisearch:latest
env:
MEILI_MASTER_KEY: test
MEILI_ENV: development
env:
DATABASE_URL: "postgresql://app:secret@database:5432/crm_siteconseil?serverVersion=16&charset=utf8"
MESSENGER_TRANSPORT_DSN: "redis://redis:6379/messages"
MAILER_DSN: "null://null"
MEILISEARCH_URL: "http://meilisearch:7700"
MEILISEARCH_API_KEY: "test"
APP_ENV: test
steps:
# ─── Setup ───────────────────────────────────────────────
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
extensions: intl, pdo_pgsql, zip, gd, redis, imagick
coverage: xdebug
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '22'
- name: Setup Bun
uses: oven-sh/setup-bun@v1
# ─── Dependencies ────────────────────────────────────────
- name: Install PHP dependencies
run: composer install --no-interaction --prefer-dist
- name: Install JS dependencies
run: |
bun install
npm install
# ─── Security audits ─────────────────────────────────────
- name: Composer security audit
run: composer audit
# ─── Linting ─────────────────────────────────────────────
- name: Lint Twig
run: php bin/console lint:twig templates/
- name: Lint YAML
run: php bin/console lint:yaml config/
- name: Lint Container
run: php bin/console lint:container
- name: PHP CS Fixer
run: vendor/bin/php-cs-fixer fix --dry-run --diff
- name: ESLint report
run: bunx eslint assets/ --ext .js,.ts -f json -o eslint-report.json || true
- name: Stylelint
run: bunx stylelint "assets/**/*.scss"
# ─── Static analysis ─────────────────────────────────────
- name: PHPStan report
run: vendor/bin/phpstan analyse src/ --level=6 --no-progress --error-format=json > phpstan-report.json || true
- name: Semgrep SAST
run: |
pip install semgrep --break-system-packages
semgrep scan --config=auto --json -o semgrep-report.json src/ || true
# ─── Build ───────────────────────────────────────────────
- name: Build assets
run: bun run build
# ─── Tests ───────────────────────────────────────────────
- name: JS tests with coverage
run: bun run test:coverage
- name: Create test database
run: php bin/console doctrine:database:create --env=test --if-not-exists
- name: Create database schema
run: php bin/console doctrine:schema:create --env=test
- name: PHPUnit with coverage
run: vendor/bin/phpunit --testdox --coverage-clover coverage.xml --coverage-text
- name: Infection (mutation testing)
run: |
vendor/bin/infection \
--threads=4 \
--skip-initial-tests \
--coverage=. \
--min-msi=50 \
--min-covered-msi=60 \
--logger-json=infection-report.json || true
# ─── Metrics ─────────────────────────────────────────────
- name: PHPMetrics
run: |
wget -qO phpmetrics.phar https://github.com/phpmetrics/PhpMetrics/releases/latest/download/phpmetrics.phar
php phpmetrics.phar --report-html=phpmetrics-report src/
# ─── Docker linting ──────────────────────────────────────
- name: Hadolint
run: |
wget -qO hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64
chmod +x hadolint
./hadolint docker/php/dev/Dockerfile -f json > hadolint-dev.json || true
./hadolint docker/php/prod/Dockerfile -f json > hadolint-prod.json || true
# ─── Dependency vulnerability scan ───────────────────────
- name: OWASP Dependency-Check
uses: dependency-check/Dependency-Check_Action@main
with:
project: 'crm-siteconseil'
path: '.'
format: 'JSON,HTML'
args: >
--scan composer.lock
--scan package.json
--out .
--disableAssembly
--nvdApiKey ${{ secrets.NVD_API_KEY }}
continue-on-error: true
- name: Rename Dependency-Check reports
run: |
mv dependency-check-report.json dc-report.json 2>/dev/null || true
mv dependency-check-report.html dc-report.html 2>/dev/null || true
# ─── SonarQube ───────────────────────────────────────────
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: https://sn.esy-web.dev
# ─── Upload reports ──────────────────────────────────────
- name: Upload CI reports
uses: actions/upload-artifact@v3
if: always()
with:
name: ci-reports
retention-days: 30
path: |
coverage.xml
phpstan-report.json
eslint-report.json
semgrep-report.json
infection-report.json
hadolint-dev.json
hadolint-prod.json
dc-report.*
phpmetrics-report/