CI/CD для PHP проектов: GitHub Actions – полное руководство

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

CI/CD для PHP проектов: GitHub Actions

Современная веб-разработка немыслима без автоматизации. Ручной запуск тестов, проверка стиля кода и деплой на сервер отнимают время и чреваты ошибками. Решение — CI/CD (Continuous Integration / Continuous Deployment). В этой статье мы разберем, как настроить полноценный пайплайн для PHP-проектов с помощью GitHub Actions. Вы узнаете, как автоматически тестировать код, проверять его качество и разворачивать на production-сервере при каждом пуше в репозиторий.

Что такое CI/CD и зачем это PHP-разработчику?

Continuous Integration (CI) — это практика, при которой каждый коммит автоматически проверяется: запускаются юнит-тесты, линтеры, проверки безопасности. Continuous Deployment (CD) — следующий шаг, когда успешно прошедший CI код автоматически разворачивается на сервере (staging или production).

Для PHP это особенно актуально: язык динамический, ошибки типизации и синтаксиса часто выявляются только в рантайме. GitHub Actions позволяет настроить пайплайн, который:

  • Запускает PHPUnit тесты в разных версиях PHP (7.4, 8.0, 8.1, 8.2).
  • Проверяет код с помощью PHP_CodeSniffer или PHPStan.
  • Выполняет деплой на сервер через SSH или Docker.

Создание workflow в GitHub Actions

Для начала создайте в корне вашего PHP-проекта директорию .github/workflows. Внутри создайте файл, например ci.yml. Это и будет ваш пайплайн.

Рассмотрим базовый пример для CI. Он будет запускаться при каждом пуше в ветку main или при создании Pull Request.

name: PHP CI

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

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        php-versions: ['7.4', '8.0', '8.1', '8.2']

    steps:
    - uses: actions/checkout@v3

    - name: Setup PHP
      uses: shivammathur/setup-php@v2
      with:
        php-version: ${{ matrix.php-versions }}
        tools: composer, phpunit

    - name: Validate composer.json and composer.lock
      run: composer validate --strict

    - 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
      run: composer install --prefer-dist --no-progress

    - name: Run PHPUnit tests
      run: phpunit --configuration phpunit.xml

Разбор ключевых моментов:

  • Matrix strategy — позволяет запускать тесты на нескольких версиях PHP одновременно. Это гарантирует совместимость кода.
  • shivammathur/setup-php — популярный action для настройки PHP окружения. Он устанавливает нужную версию, Composer и PHPUnit.
  • Кэширование vendor — ускоряет последующие запуски, не загружая зависимости заново.
  • composer validate — проверяет корректность composer.json.

Добавляем статический анализ и линтинг

Тесты — это хорошо, но без контроля качества кода не обойтись. Добавим в тот же workflow (или создадим отдельный job) проверку с помощью PHPStan и PHP_CodeSniffer.

    - name: Run PHPStan
      run: vendor/bin/phpstan analyse src tests --level=max

    - name: Run PHP_CodeSniffer
      run: vendor/bin/phpcs --standard=PSR2 src tests

Эти шаги можно добавить после установки зависимостей. PHPStan с уровнем max найдет потенциальные ошибки типов, а PHP_CodeSniffer со стандартом PSR-2 (или PSR-12) обеспечит единообразный стиль кода. Если хотя бы один шаг завершится ошибкой, весь workflow будет считаться проваленным, и Pull Request не будет принят.

Совет: для локальной разработки установите эти инструменты как dev-зависимости в composer.json:

composer require --dev phpstan/phpstan squizlabs/php_codesniffer

Настройка Continuous Deployment (деплой на сервер)

После того, как тесты пройдены, можно автоматически развернуть код на сервере. Рассмотрим два популярных подхода: через SSH (классический) и через Docker Hub.

Вариант 1: Деплой через SSH

Для этого понадобится добавить секреты (Secrets) в GitHub: SSH_PRIVATE_KEY, REMOTE_HOST, REMOTE_USER, REMOTE_PATH.

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

    steps:
    - uses: actions/checkout@v3

    - name: Deploy to Server
      uses: easingthemes/ssh-deploy@v2
      env:
        SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
        ARGS: "-rltgoDzvO --delete"
        SOURCE: "."
        REMOTE_HOST: ${{ secrets.REMOTE_HOST }}
        REMOTE_USER: ${{ secrets.REMOTE_USER }}
        TARGET: ${{ secrets.REMOTE_PATH }}

Обратите внимание на needs: build — job деплоя запустится только после успешного завершения job с тестами. Флаг --delete удаляет файлы на сервере, которых нет в репозитории.

Вариант 2: Docker-образ

Если ваш PHP-проект работает в контейнерах, можно собрать образ и отправить его в Docker Hub, а затем на сервере выполнить docker pull и перезапустить контейнер.

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

    steps:
    - uses: actions/checkout@v3

    - name: Log in to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}

    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: yourusername                

Блоги

Рекомендаций по книгам