Введение в CI/CD для PHP проектов с GitHub Actions
Современная разработка PHP-приложений невозможна без автоматизации. Ручное тестирование и деплой — это не только долго, но и чревато ошибками. CI/CD (Continuous Integration / Continuous Deployment) решает эти проблемы, автоматизируя проверку кода и его доставку на сервер. Одним из самых популярных инструментов для этого является GitHub Actions.
GitHub Actions — это встроенная платформа для автоматизации рабочих процессов (workflows), которая позволяет запускать тесты, линтеры, сборки и деплой прямо из вашего репозитория на GitHub. В этой статье мы разберём, как настроить полный пайплайн CI/CD для PHP-проекта: от простого запуска тестов до автоматического деплоя на production-сервер.
Мы будем использовать пример на базе Laravel, но все принципы применимы к любому PHP-фреймворку (Symfony, Yii, WordPress и т.д.). Вы узнаете, как писать YAML-конфигурации, использовать матрицы тестирования, кэшировать зависимости и безопасно деплоить код.
Основная часть
1. Основы GitHub Actions: структура workflow
Workflow — это автоматизированный процесс, который запускается по определённому событию (push, pull request, создание тега). Каждый workflow описывается в YAML-файле, который хранится в директории .github/workflows/ вашего репозитория.
Базовая структура файла .github/workflows/ci.yml:
name: CI Pipeline
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
extensions: mbstring, xml, bcmath, pdo_mysql
coverage: xdebug
- name: Install dependencies
run: composer install --no-progress --prefer-dist
- name: Run PHPUnit tests
run: vendor/bin/phpunit --coverage-text
Разберём ключевые элементы:
on— триггеры: push в main/develop, pull request в main.jobs— набор задач (job), выполняющихся параллельно или последовательно.runs-on— операционная система для запуска (обычноubuntu-latest).steps— последовательность шагов внутри job.uses— готовые actions из маркетплейса (например,shivammathur/setup-php).run— выполнение shell-команды.
2. Продвинутая конфигурация: матрица тестирования и кэширование
Для больших проектов полезно тестировать сразу несколько версий PHP и зависимостей. Это делается через матрицу стратегий (matrix strategy). Также важно кэшировать vendor-папку Composer, чтобы ускорить выполнение workflow.
Пример с матрицей и кэшем:
name: Advanced CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php: [ '8.1', '8.2', '8.3' ]
dependency-stability: [ prefer-stable, prefer-lowest ]
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, pdo, gd
coverage: none
- name: Cache Composer packages
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-${{ matrix.php }}-composer-
- name: Install dependencies
run: composer install --${{ matrix.dependency-stability }} --no-interaction
- name: Run tests
run: vendor/bin/phpunit --testdox
- name: Run PHP CodeSniffer
run: vendor/bin/phpcs --standard=PSR12 app/
Что здесь нового:
- Matrix: workflow запустится 6 раз (3 версии PHP × 2 уровня стабильности).
- Cache: сохраняет vendor на основе хэша
composer.lock. Если файл не менялся — зависимости не переустанавливаются. - Линтинг: добавлен PHP_CodeSniffer для проверки стиля кода.
3. Автоматический деплой на сервер через SSH
После успешного прохождения тестов можно настроить деплой на production или staging. Самый безопасный способ — использовать SSH с приватным ключом, сохранённым в Secrets репозитория.
Создайте файл .github/workflows/deploy.yml:
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
tools: composer:v2
- name: Install production dependencies
run: composer install --no-dev --no-interaction --optimize-autoloader
- name: Deploy via SSH
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.SSH_HOST }}
username: ${{ secrets.SSH_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
port: 22
script: |
cd /var/www/myproject
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan cache:clear
php artisan config:cache
php artisan route:cache
php artisan view:cache
sudo systemctl reload php8.2-fpm
Важные моменты:
- Secrets:
SSH_HOST,SSH_USER,SSH_PRIVATE_KEYнужно добавить в Settings → Secrets and variables → Actions вашего репозитория. - Условный запуск:
if: github.ref == 'refs/heads/main'гарантирует, что деплой произойдёт только при пуше в main. - Безопасность: никогда не храните пароли и ключи в к