Как настроить CI/CD для PHP-проекта?php-62

CI/CD (Continuous Integration/Continuous Deployment) — это практика автоматизации процессов интеграции кода и его развертывания. Для PHP-проектов это включает тестирование, анализ кода и деплой.

1. Выбор инструментов

Популярные решения:

  • GitHub Actions (бесплатно для публичных репозиториев)
  • GitLab CI/CD (встроен в GitLab)
  • Jenkins (для сложных сценариев)
  • Bitbucket Pipelines

2. Базовый workflow CI/CD

Типичный пайплайн включает этапы:

  1. Установка зависимостей
  2. Запуск тестов
  3. Статический анализ кода
  4. Сборка артефактов
  5. Деплой (вручную или автоматически)

3. Пример настройки GitHub Actions

name: PHP CI

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:5.7
        env:
          MYSQL_ROOT_PASSWORD: root
          MYSQL_DATABASE: test_db
        ports:
          - 3306:3306
        options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3

    steps:
    - uses: actions/checkout@v2

    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: '8.2'
        extensions: mbstring, xml, mysql, intl
        coverage: pcov

    - name: Install dependencies
      run: composer install --no-progress --prefer-dist --optimize-autoloader

    - name: Run tests
      run: vendor/bin/phpunit --coverage-clover=coverage.xml

    - name: Upload coverage
      uses: codecov/codecov-action@v1
      with:
        token: ${{ secrets.CODECOV_TOKEN }}
        file: coverage.xml

    - name: PHPStan analysis
      run: vendor/bin/phpstan analyse

    - name: Psalm
      run: vendor/bin/psalm --output-format=github

4. Деплой на сервер

Пример деплоя через rsync после успешных тестов:

deploy:
  needs: test
  runs-on: ubuntu-latest
  if: github.ref == 'refs/heads/main'

  steps:
    - uses: actions/checkout@v2

    - name: Install SSH key
      uses: webfactory/ssh-agent@v0.5.0
      with:
        ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}

    - name: Deploy via rsync
      run: |
        rsync -avz --delete --exclude='.env' --exclude='.git' \
          ./ user@production-server:/var/www/my-app/
        ssh user@production-server "cd /var/www/my-app && php artisan migrate --force"

5. Продвинутые практики

Кэширование зависимостей

- name: Cache Composer packages
  uses: actions/cache@v2
  with:
    path: vendor
    key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}

Мульти-версионное тестирование

strategy:
  matrix:
    php: ['7.4', '8.0', '8.1', '8.2']
    experimental: [false]
    include:
      - php: '8.3'
        experimental: true

Артефакты сборки

- name: Upload build artifacts
  uses: actions/upload-artifact@v2
  with:
    name: php-build
    path: |
      vendor
      bootstrap/cache

6. Интеграция с Docker

Пример сборки и пуша Docker-образа:

- name: Build and push Docker image
  uses: docker/build-push-action@v2
  with:
    push: true
    tags: user/my-app:${{ github.sha }}
    build-args: |
      PHP_VERSION=8.2

7. Уведомления

- name: Notify Slack
  uses: rtCamp/action-slack-notify@v2
  env:
    SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
    SLACK_COLOR: ${{ job.status == 'success' && '#36a64f' || '#ff0000' }}
    SLACK_TITLE: 'Deployment status: ${{ job.status }}'

8. Особенности для популярных PHP-фреймворков

Laravel:

- name: Laravel setup
  run: |
    cp .env.example .env
    php artisan key:generate
    php artisan storage:link

Symfony:

- name: Symfony cache warmup
  run: php bin/console cache:warmup --env=test

9. Безопасность

  1. Секреты храните в переменных окружениях CI
  2. Аудит зависимостей:
    - name: Security check
      run: vendor/bin/security-checker security:check
    
  3. Проверка уязвимостей:
    composer audit
    

Резюмируем:

Настройка CI/CD для PHP-проекта требует понимания инструментов автоматизации, процессов тестирования и специфики деплоя PHP. Грамотно настроенный пайплайн значительно повышает надежность доставки кода и сокращает время между правкой и ее выходом в production.