diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index 88040cd..4cfc450 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -15,16 +15,28 @@ jobs: quality-and-tests: runs-on: ubuntu-latest + # Jetons SonarQube, définis dans les secrets du dépôt Gitea. + # Exposés au niveau du job pour pouvoir conditionner l'étape d'analyse + # (elle ne s'exécute que si un jeton est configuré). + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + steps: - name: Récupération du code uses: actions/checkout@v4 + with: + # Historique complet : SonarQube en a besoin pour dater le code + # et calculer correctement le "nouveau code". + fetch-depth: 0 - name: Installation de PHP 8.2 uses: shivammathur/setup-php@v2 with: php-version: '8.2' extensions: pdo_mysql, pdo_sqlite, sqlite3, mbstring, exif, pcntl, bcmath, gd - coverage: none + # pcov : moteur de couverture rapide, requis pour le rapport SonarQube. + coverage: pcov - name: Cache des dépendances Composer uses: actions/cache@v4 @@ -46,8 +58,21 @@ jobs: - name: Analyse statique (Larastan / PHPStan) run: vendor/bin/phpstan analyse --configuration=phpstan.neon --memory-limit=512M --no-progress - - name: Exécution des tests automatisés (PHPUnit) - env: - DB_CONNECTION: sqlite - DB_DATABASE: ':memory:' - run: php artisan test + - name: Exécution des tests + couverture (PHPUnit) + # phpunit.xml définit déjà l'environnement de test (sqlite en mémoire). + # On génère le rapport de couverture (clover) et le rapport de tests + # (junit) consommés ensuite par SonarQube. + run: | + mkdir -p coverage + vendor/bin/phpunit \ + --coverage-clover=coverage/clover.xml \ + --log-junit=coverage/junit.xml + + - name: Analyse SonarQube + # Ne s'exécute que si le secret SONAR_TOKEN est configuré dans Gitea, + # sinon l'étape est ignorée (la CI reste verte tant que le serveur + # SonarQube n'est pas branché). + if: ${{ env.SONAR_TOKEN != '' }} + uses: sonarsource/sonarqube-scan-action@v5 + # Le scanner lit sonar-project.properties et utilise SONAR_HOST_URL / + # SONAR_TOKEN exposés au niveau du job. diff --git a/.gitignore b/.gitignore index b71b1ea..282c56b 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,9 @@ /.idea /.nova /.phpunit.cache +/.scannerwork /.vscode +/coverage /.zed /auth.json /node_modules diff --git a/docker-compose.sonar.yml b/docker-compose.sonar.yml new file mode 100644 index 0000000..cefc63c --- /dev/null +++ b/docker-compose.sonar.yml @@ -0,0 +1,43 @@ +# Serveur SonarQube (auto-hébergé) pour l'analyse de qualité du code. +# +# Démarrage : docker compose -f docker-compose.sonar.yml up -d +# Interface : http://localhost:9000 (identifiants par défaut : admin / admin) +# Arrêt : docker compose -f docker-compose.sonar.yml down +# +# ⚠️ Prérequis hôte (Elasticsearch embarqué dans SonarQube) : +# Linux : sudo sysctl -w vm.max_map_count=262144 +# (à rendre permanent dans /etc/sysctl.conf) +# Prévoir ~2-3 Go de RAM disponibles pour le conteneur. + +services: + sonarqube: + image: sonarqube:community + container_name: sonarqube + depends_on: + - sonar-db + ports: + - "9000:9000" + environment: + SONAR_JDBC_URL: jdbc:postgresql://sonar-db:5432/sonar + SONAR_JDBC_USERNAME: sonar + SONAR_JDBC_PASSWORD: sonar + volumes: + - sonarqube_data:/opt/sonarqube/data + - sonarqube_extensions:/opt/sonarqube/extensions + - sonarqube_logs:/opt/sonarqube/logs + + sonar-db: + image: postgres:15 + container_name: sonar-db + environment: + POSTGRES_USER: sonar + POSTGRES_PASSWORD: sonar + POSTGRES_DB: sonar + volumes: + - sonar_postgresql:/var/lib/postgresql/data + +volumes: + sonarqube_data: + sonarqube_extensions: + sonarqube_logs: + sonar_postgresql: diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..40c3b31 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,18 @@ +# Configuration de l'analyse SonarQube. +# L'URL du serveur (sonar.host.url) et le jeton (sonar.token) NE sont PAS ici : +# ils sont fournis à la CI via les secrets SONAR_HOST_URL / SONAR_TOKEN. + +sonar.projectKey=ressources-relationnelles +sonar.projectName=Ressources Relationnelles + +# Code source analysé et code de test. +sonar.sources=app +sonar.tests=tests +sonar.sourceEncoding=UTF-8 + +# Rapports produits par PHPUnit (générés dans la CI, voir ci.yml). +sonar.php.coverage.reportPaths=coverage/clover.xml +sonar.php.tests.reportPath=coverage/junit.xml + +# On n'analyse pas le code tiers, généré ou compilé. +sonar.exclusions=vendor/**,storage/**,bootstrap/cache/**,public/build/**,node_modules/**