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. Le suffixe `_test` # est applique automatiquement par Doctrine en APP_ENV=test. POSTGRES_USER: app POSTGRES_PASSWORD: '!ChangeMe!' POSTGRES_DB: app # 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 --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!@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 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 # Cache Composer retire : meme cause que cote front — le backend de cache # du runner Gitea est injoignable (ETIMEDOUT) et fait timeouter le step # ~4 min 30. A re-activer si le serveur de cache du runner est repare. - 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 # Pas de `cache: npm` : le backend de cache du runner Gitea est injoignable # (ETIMEDOUT) et chaque tentative de restauration attend ~4 min 30 avant de # timeout — c'est ce qui plombait le job. Node 22 est deja dans le # tool-cache du runner (install instantane), et `npm ci` a froid ne prend # que ~30s. A re-activer si le serveur de cache du runner est repare. - name: Setup Node 22 uses: actions/setup-node@v4 with: node-version: '22' # Cache de node_modules entier (pas seulement le cache de download npm). # Cle = hash du lockfile : tant qu'il ne bouge pas, on saute l'extraction # des ~1300 paquets (369 Mo) et le postinstall. - name: Cache node_modules id: node-modules-cache uses: actions/cache@v4 with: path: frontend/node_modules key: node-modules-${{ hashFiles('frontend/package-lock.json') }} # npm ci uniquement en cache miss (il efface node_modules de toute facon). - name: Install Node dependencies if: steps.node-modules-cache.outputs.cache-hit != 'true' run: npm ci # En cache hit, node_modules est restaure tel quel : le postinstall # (nuxt prepare) n'a pas tourne. On regenere les types .nuxt a la main # pour que lint/vitest/build disposent du contexte Nuxt. - name: Prepare Nuxt (cache hit) if: steps.node-modules-cache.outputs.cache-hit == 'true' run: npm run postinstall # Cache des artefacts de build Nuxt/Vite pour eviter un build a froid a # chaque PR. Cle par commit + restore-keys pour repartir du build le plus # recent ; Vite invalide ses entrees obsoletes par hash de contenu. - name: Cache Nuxt/Vite build uses: actions/cache@v4 with: path: | frontend/.nuxt frontend/node_modules/.cache key: nuxt-build-${{ github.sha }} restore-keys: | nuxt-build- - name: ESLint run: npm run lint - name: Unit tests (Vitest) run: npm run test # `nuxt build` (et non `build:dist`/`nuxt generate`) : l'app est en SSR off # (SPA), le prerender de generate n'apporte rien a une quality gate — on # veut seulement valider que le bundle compile. - name: Build production (nuxt build) run: npm run build