Введение: Почему CI/CD — это новый стандарт PHP-разработки
Современная PHP-разработка немыслима без автоматизации. Ручной деплой, запуск тестов «на глаз» и проверка кода в последний момент — прямой путь к багам в продакшене. CI/CD (Continuous Integration / Continuous Deployment) решает эти проблемы, интегрируя проверки и выкатку кода прямо в ваш рабочий процесс.
GitHub Actions — это мощный и бесплатный инструмент для встраивания CI/CD прямо в репозиторий. В этой статье мы разберем, как настроить полный пайплайн для PHP-проекта на Laravel или Symfony: от установки зависимостей до деплоя на сервер. Вы получите готовые конфиги и понимание каждого этапа.
1. Основы GitHub Actions: структура Workflow для PHP
Workflow в GitHub Actions — это автоматизированный процесс, определенный в YAML-файле в папке .github/workflows/. Для PHP-проекта типовой workflow включает:
- Триггеры: push в ветку
main, pull request. - Runner: Ubuntu latest (поддержка PHP).
- Шаги: Checkout, установка PHP, Composer, тесты, линтеры.
Рассмотрим минимальный файл ci.yml:
name: PHP CI
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, pdo_mysql, xml
coverage: xdebug
- name: Install Composer dependencies
run: composer install --no-progress --prefer-dist
- name: Run PHPUnit
run: vendor/bin/phpunit --testdox
Этот workflow запускается при каждом пуше. Он проверяет, что код собирается и тесты проходят. Обратите внимание на action shivammathur/setup-php — он де-факто стандарт для PHP.
2. Продвинутая настройка: статический анализ, линтеры и кэширование
Одними тестами CI не ограничивается. Для поддержания качества кода добавьте статический анализ (PHPStan, Psalm) и проверку стиля (PHP CS Fixer).
2.1. Добавляем PHPStan и PHP CS Fixer
Установите их как dev-зависимости:
composer require --dev phpstan/phpstan friendsofphp/php-cs-fixer
Дополните шаги в workflow:
- name: Run PHPStan
run: vendor/bin/phpstan analyse --memory-limit=1G
- name: Check code style
run: vendor/bin/php-cs-fixer fix --dry-run --diff
Совет: используйте --dry-run, чтобы не менять файлы, а только проверять. Если стиль нарушен — CI упадет, и разработчик исправит.
2.2. Кэширование зависимостей Composer
Каждый запуск CI скачивает пакеты заново — это долго. Включаем кэширование:
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
if: steps.composer-cache.outputs.cache-hit != 'true'
run: composer install --no-progress --prefer-dist
Теперь повторные запуски будут в 2-3 раза быстрее.
3. Тестирование с базой данных и Docker-сервисами
Многие PHP-приложения требуют MySQL, PostgreSQL или Redis для тестов. GitHub Actions позволяет запускать сервисные контейнеры (Service Containers).
3.1. Пример с MySQL и Laravel
Допустим, ваш проект использует Laravel с MySQL. Добавляем сервис и настраиваем .env:
jobs:
test:
runs-on: ubuntu-latest
services:
mysql:
image: mysql:8.0
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=5
steps:
- uses: actions/checkout@v3
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: pdo_mysql
- name: Copy .env
run: cp .env.example .env
- name: Generate key
run: php artisan key:generate
- name: Run migrations
run: php artisan migrate --env=testing
- name: Run tests
run: php artisan test --parallel
В .env.testing укажите:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=root
DB_PASSWORD=root
Аналогично можно подключить Redis или Mailhog для тестирования очередей и писем.
4. Continuous Deployment: автодеплой на сервер через SSH и Deployer
Последний этап — деплой на продакшн. Самый безопасный способ для PHP — использовать Deployer (популярная PHP-библиотека) или простой SSH-скрипт.
4.1. Деплой через Deployer
Установите Deployer:
composer require --dev deployer/deployer
Создайте deploy.php в корне проекта. Пример конфига для Laravel:
<?php
namespace Deployer;
require 'recipe/laravel.php';
set('application', 'my-app');
set('repository', 'git@github.com:username/repo.git');
set('git_tty', true);
host('prod')
->setHostname('your-server.com')
->set('remote_user', 'deployer')
->set('deploy_path', '/var/www/my-app')
->set('branch', 'main');
after('deploy:failed', 'deploy:unlock');
Теперь в workflow добавляем шаг деплоя (только для ветки main):
- name: Deploy to production
if: github