diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4131776..f74136b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,3 +29,161 @@ jobs: run: | # Validate all commits in the PR npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose + + lint: + runs-on: ubuntu-latest + needs: validate-commits + if: always() && (needs.validate-commits.result == 'success' || needs.validate-commits.result == 'skipped') + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv + coverage: none + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v4 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader + + - name: Run Laravel Pint + uses: aglipanci/laravel-pint-action@2.4 + with: + preset: laravel + verboseMode: true + + analyze: + runs-on: ubuntu-latest + needs: lint + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv + coverage: none + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v4 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader + + - name: Copy environment file + run: cp .env.docker.example .env + + - name: Generate application key + run: php artisan key:generate + + - name: Run Larastan (PHPStan) + run: ./vendor/bin/phpstan analyse --memory-limit=2G --error-format=github + + test: + runs-on: ubuntu-latest + needs: analyze + + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: laravel_blog_test + ports: + - 3306:3306 + options: --health-cmd="mysqladmin ping -h localhost -u root -proot" --health-interval=10s --health-timeout=5s --health-retries=5 + + redis: + image: redis:7-alpine + ports: + - 6379:6379 + options: --health-cmd="redis-cli ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, sqlite, pdo_sqlite, bcmath, soap, intl, gd, exif, iconv + coverage: xdebug + + - name: Cache Composer packages + id: composer-cache + uses: actions/cache@v4 + with: + path: vendor + key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-php- + + - name: Install Composer dependencies + run: composer install --prefer-dist --no-interaction --no-progress --optimize-autoloader + + - name: Copy environment file + run: cp .env.docker.example .env + + - name: Generate application key + run: php artisan key:generate + + - name: Set testing environment variables + run: | + echo "APP_ENV=testing" >> .env + echo "DB_CONNECTION=mysql" >> .env + echo "DB_HOST=127.0.0.1" >> .env + echo "DB_PORT=3306" >> .env + echo "DB_DATABASE=laravel_blog_test" >> .env + echo "DB_USERNAME=root" >> .env + echo "DB_PASSWORD=root" >> .env + echo "CACHE_STORE=array" >> .env + echo "SESSION_DRIVER=array" >> .env + echo "QUEUE_CONNECTION=sync" >> .env + + - name: Wait for MySQL to be ready + run: | + for i in {1..60}; do + if mysqladmin ping -h 127.0.0.1 -P 3306 -u root -proot --silent; then + echo "MySQL is ready" + # Verify the database exists + mysql -h 127.0.0.1 -P 3306 -u root -proot -e "SHOW DATABASES;" | grep laravel_blog_test || exit 1 + echo "Database laravel_blog_test confirmed" + break + fi + echo "Waiting for MySQL... ($i/60)" + sleep 3 + done + if [ $i -eq 60 ]; then + echo "MySQL failed to start within 3 minutes" + exit 1 + fi + + - name: Run database migrations + run: php artisan migrate:fresh --seed --env=testing --force + + - name: Run tests with Pest (parallel) + env: + DB_HOST: 127.0.0.1 + DB_USERNAME: root + DB_PASSWORD: root + run: php artisan test --parallel --recreate-databases --stop-on-failure