name: CI on: push: branches: [main, backend-audit] pull_request: jobs: backend: name: PHP — phpstan + migrate-on-empty-db + phpunit runs-on: ubuntu-latest services: mariadb: image: mariadb:11.8 env: MARIADB_ROOT_PASSWORD: root MARIADB_DATABASE: db MARIADB_USER: db MARIADB_PASSWORD: db ports: - 3306:3306 options: >- --health-cmd="healthcheck.sh --connect --innodb_initialized" --health-interval=10s --health-timeout=5s --health-retries=20 redis: image: redis:7 ports: - 6379:6379 options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=10 env: # Real env vars take precedence over .env/.env.test. doctrine's when@test # config appends `_test`, so this `db` becomes `db_test` for the test run. DATABASE_URL: "mysql://db:db@127.0.0.1:3306/db?serverVersion=11.8.0-MariaDB&charset=utf8mb4" REDIS_URL: "redis://127.0.0.1:6379" APP_ENV: test steps: - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 with: php-version: '8.3' extensions: pdo_mysql, intl, redis, gd, zip, mbstring, bcmath coverage: none - name: Install dependencies run: composer install --no-interaction --prefer-dist --no-progress - name: Create test database run: | mysql -h127.0.0.1 -uroot -proot -e "CREATE DATABASE IF NOT EXISTS db_test; GRANT ALL ON db_test.* TO 'db'@'%'; FLUSH PRIVILEGES;" - name: Generate JWT keypair run: php bin/console lexik:jwt:generate-keypair --skip-if-exists --env=test # phpstan's symfony extension reads the dev container XML (see phpstan.neon), # so warm the dev cache first. - name: Warm dev cache (for phpstan container) run: php bin/console cache:warmup --env=dev env: APP_ENV: dev - name: PHPStan (baselined — fails only on NEW errors) run: php vendor/bin/phpstan analyse --no-progress - name: Migrate on empty DB (smoke) run: php bin/console doctrine:migrations:migrate --no-interaction --env=test - name: PHPUnit run: php bin/phpunit