From 2aecab0a5f0f954b1d2e8816e593d43a3d6842a5 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Tue, 19 May 2026 15:16:51 +0200 Subject: [PATCH 1/2] ci : add pull_request quality gate workflow Workflow Gitea declenche sur chaque PR ciblant develop, avec deux jobs paralleles : - backend : composer install, php-cs-fixer dry-run, bootstrap DB test (service postgres:16-alpine), phpunit - frontend : npm ci, eslint, vitest, nuxt build Ajoute aussi la cible make php-cs-fixer-check (dry-run) pour avoir la meme commande en local et en CI. E2E volontairement hors scope (regle d'or testing.md : tests E2E uniquement pour bug critique passe en prod). --- .gitea/workflows/pull-request.yml | 118 ++++++++++++++++++++++++++++++ makefile | 6 ++ 2 files changed, 124 insertions(+) create mode 100644 .gitea/workflows/pull-request.yml diff --git a/.gitea/workflows/pull-request.yml b/.gitea/workflows/pull-request.yml new file mode 100644 index 0000000..39e7fb8 --- /dev/null +++ b/.gitea/workflows/pull-request.yml @@ -0,0 +1,118 @@ +name: Pull Request — Quality gate + +# Lance les tests + lint + build sur chaque PR ciblant develop. +# Deux jobs en parallele (backend / frontend) pour reduire le temps de feedback. +# E2E volontairement hors scope (cf. regle d'or testing.md). + +on: + pull_request: + branches: + - develop + +# Annule les runs obsoletes quand on repush sur la meme PR. +concurrency: + group: pr-${{ gitea.event.pull_request.number }} + cancel-in-progress: true + +jobs: + backend: + name: Backend (PHP CS + PHPUnit) + runs-on: ubuntu-latest + + services: + postgres: + image: postgres:16-alpine + env: + # Doivent matcher la DATABASE_URL ci-dessous (et le default + # de phpunit.dist.xml). Le suffixe `_test` est applique + # automatiquement par Doctrine en APP_ENV=test. + POSTGRES_USER: app + POSTGRES_PASSWORD: '!ChangeMe!' + POSTGRES_DB: app + ports: + - 5432:5432 + options: >- + --health-cmd "pg_isready -U app" + --health-interval 5s + --health-timeout 5s + --health-retries 10 + + env: + APP_ENV: test + APP_SECRET: ci-secret-not-used + APP_DEBUG: 0 + DEFAULT_URI: http://localhost/ + DATABASE_URL: postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8 + JWT_SECRET_KEY: '%kernel.project_dir%/config/jwt/private.pem' + JWT_PUBLIC_KEY: '%kernel.project_dir%/config/jwt/public.pem' + JWT_PASSPHRASE: change_me_in_env_local + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP 8.4 + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: pdo, pdo_pgsql, intl, opcache, zip, mbstring, sodium + coverage: none + tools: composer:v2 + + - name: Cache Composer + uses: actions/cache@v4 + with: + path: ~/.composer/cache + key: composer-${{ hashFiles('composer.lock') }} + restore-keys: | + composer- + + - name: Install PHP dependencies + run: composer install --no-interaction --no-progress --prefer-dist + + - name: Generate JWT keypair + run: php bin/console lexik:jwt:generate-keypair --skip-if-exists --no-interaction + + - name: PHP CS Fixer (dry-run) + run: vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff + + - name: Bootstrap test database + run: | + php bin/console doctrine:database:create --env=test --if-not-exists --no-interaction + php bin/console doctrine:migrations:migrate --env=test --no-interaction + php bin/console doctrine:schema:update --env=test --force --no-interaction + php bin/console doctrine:fixtures:load --env=test --no-interaction + php bin/console app:sync-permissions --env=test --no-interaction + + - name: Run PHPUnit + run: php -d memory_limit=512M vendor/bin/phpunit + + frontend: + name: Frontend (lint + Vitest + build) + runs-on: ubuntu-latest + defaults: + run: + working-directory: frontend + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Node 22 + uses: actions/setup-node@v4 + with: + node-version: '22' + cache: npm + cache-dependency-path: frontend/package-lock.json + + - name: Install Node dependencies + run: npm ci + + - name: ESLint + run: npm run lint + + - name: Unit tests (Vitest) + run: npm run test + + - name: Build production (nuxt build) + run: npm run build:dist diff --git a/makefile b/makefile index d046bba..8b57452 100644 --- a/makefile +++ b/makefile @@ -70,6 +70,7 @@ help: @printf " \033[36m%-28s\033[0m %s\n" "install-e2e-deps" "One-time : Chromium + libs systeme (sudo)" @printf "\n \033[1;33mQualite code\033[0m\n" @printf " \033[36m%-28s\033[0m %s\n" "php-cs-fixer-allow-risky" "Fix code style PHP (utilise par le pre-commit)" + @printf " \033[36m%-28s\033[0m %s\n" "php-cs-fixer-check" "Dry-run du fixer (CI / verif avant push)" @printf "\n Plus de details : \033[4mREADME.md\033[0m, \033[4mCLAUDE.md\033[0m\n\n" env-init: @@ -258,6 +259,11 @@ php-cs-fixer-allow-risky: @echo "Fixing files: $(FILES)" $(EXEC_PHP_CS_FIXER) fix --config=.php-cs-fixer.dist.php --allow-risky=yes $(FILES) +# Dry-run du fixer : echec si au moins un fichier n'est pas conforme. +# Utilise par la CI (Gitea pull_request) et avant un push manuel. +php-cs-fixer-check: + $(EXEC_PHP_CS_FIXER) fix --config=.php-cs-fixer.dist.php --allow-risky=yes --dry-run --diff $(FILES) + test: $(EXEC_PHP) php -d memory_limit="512M" vendor/bin/phpunit $(FILES) -- 2.39.5 From a11251b253f025095036b467678b1903ef997db0 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Tue, 19 May 2026 15:40:00 +0200 Subject: [PATCH 2/2] =?UTF-8?q?ci=20:=20fix=20backend=20job=20=E2=80=94=20?= =?UTF-8?q?utiliser=20nom=20de=20service=20postgres=20au=20lieu=20de=20127?= =?UTF-8?q?.0.0.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le runner Gitea Actions partage l'hote avec la prod (Postgres deja sur 5432), et les jobs tournent en container sur un reseau Docker dedie. Le mapping `ports: 5432:5432` echouait avec "address already in use", et de toute facon le service est joignable via son nom (`postgres`) depuis le container du job — pas besoin d'exposer le port sur l'hote. - Drop `ports:` block du service postgres - DATABASE_URL : host `127.0.0.1` -> `postgres` --- .gitea/workflows/pull-request.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.gitea/workflows/pull-request.yml b/.gitea/workflows/pull-request.yml index 39e7fb8..5345b97 100644 --- a/.gitea/workflows/pull-request.yml +++ b/.gitea/workflows/pull-request.yml @@ -23,14 +23,15 @@ jobs: postgres: image: postgres:16-alpine env: - # Doivent matcher la DATABASE_URL ci-dessous (et le default - # de phpunit.dist.xml). Le suffixe `_test` est applique - # automatiquement par Doctrine en APP_ENV=test. + # Doivent matcher la DATABASE_URL ci-dessous. Le suffixe `_test` + # est applique automatiquement par Doctrine en APP_ENV=test. POSTGRES_USER: app POSTGRES_PASSWORD: '!ChangeMe!' POSTGRES_DB: app - ports: - - 5432:5432 + # Pas de `ports:` host mapping — le runner partage l'hote avec la + # prod (Postgres deja sur 5432) et les jobs Gitea Actions tournent + # en container sur un reseau Docker dedie : le service est joignable + # via son nom (`postgres`), pas via 127.0.0.1. options: >- --health-cmd "pg_isready -U app" --health-interval 5s @@ -42,7 +43,7 @@ jobs: APP_SECRET: ci-secret-not-used APP_DEBUG: 0 DEFAULT_URI: http://localhost/ - DATABASE_URL: postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8 + DATABASE_URL: postgresql://app:!ChangeMe!@postgres:5432/app?serverVersion=16&charset=utf8 JWT_SECRET_KEY: '%kernel.project_dir%/config/jwt/private.pem' JWT_PUBLIC_KEY: '%kernel.project_dir%/config/jwt/public.pem' JWT_PASSPHRASE: change_me_in_env_local -- 2.39.5