CI/CD для WP: как настроить GitHub Actions и WP-CLI для смоук-тестов

CI/CD для WP с GitHub Actions и WP-CLI

CI/CD для WP: как настроить GitHub Actions и WP-CLI для смоук-тестов

Ночью, когда город уже сдался, а на столе остыл второй чай, приходит то самое сообщение: клиент обновил тему на проде, на главной белый экран, «поправьте срочно». В голове быстро прокручивается привычное кино про доступы, резервные копии и чужие кривые плагинчики, а руки уже тянутся к консоли. Было бы смешно, если бы не приходилось за такое расплачиваться собственным сном и нервами. С тех пор я завёл себе правило: никаких ручных выкладок, никаких сюрпризов в пятницу, только пайплайн, который первым упадёт сам, если что-то не так. И пусть он будет строгим и немного занудным — зато честным. В этом материале покажу, как настроить GitHub Actions с WP-CLI так, чтобы любые обновления WordPress сначала проходили смоук-тесты, а уже потом трогали боевой сервер.

Кстати, если вы работаете в агентстве, ведёте магазин на WooCommerce или пилите двадцать клиентских сайтов на одном VPS, такая система — буквально страховка от бессмысленных потерь. Смоук-тесты — это не про идеальную чистоту кода и юнит-покрытие, это быстрый осмотр машины после ТО. Завелась ли, не горит ли лампа давления, открывается ли главная и не снеслись ли пермалинки. За пару минут они ловят 80% неприятностей, а остальное уже по человечески можно увидеть глазами на стейдже. Плюс под российские реалии это особенно актуально: хостинги разные, у кого-то старый PHP, у кого-то модули в сборке пляшут, у третьих файервол режет запросы, и всё это прекрасно воспроизводится только когда ты контролируешь процесс end-to-end.

Что именно проверяют смоук-тесты на WordPress

Секрет в простоте. Мы ставим чистую копию WordPress в раннере GitHub Actions, подключаем временную базу, активируем вашу тему или плагин, запускаем минимальный сервер и бьём по нему curl с парой проверок. Если главная отдала 200 и на странице есть ожидаемая фраза — живём. Если WP-CLI спокойно читает опции, пересобирает пермалинки, активирует зависимости и не падает — отлично. Можно добавить ещё пару безопасных вещей вроде проверки check-sum для плагинов, статуса базы, доступности wp-cron и времени ответа главной. Это всё быстро, надёжно и заметно экономит нервы команде. А потом уже, если всё зелёное, включается шаг деплоя на стейдж или на прод — аккуратно, через SSH и с понятным логом, без ручных плясок в админке.

Создание страницы сайта на автомате
Автоматизация не должна быть страшной. Главное — поставить её себе на службу.

Рабочий workflow на GitHub Actions

Ниже пример файла .github/workflows/ci.yml. Он ставит PHP 8.2, поднимает MySQL как сервис, разворачивает WordPress, активирует ваш код и гоняет смоук-тесты. После успеха умеет безопасно зайти на сервер по SSH и выполнить команды WP-CLI уже на реальном сайте. В репозитории предполагается тема или плагин, в секретах лежат доступы, а сайт на сервере уже подготовлен и знает, где его document root. Чуть ниже я разберу тонкости, но почти всегда достаточно подставить свои пути, пользователя и домен, чтобы оно просто заработало. Если не заработало, значит хорошо, пайплайн честно поймал проблему и не пустил её в прод. Вот ради этого мы тут и собирались.

name: wp-ci

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

concurrency:
  group: wp-ci-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    runs-on: ubuntu-latest
    services:
      mysql:
        image: mysql:8
        env:
          MYSQL_DATABASE: wp
          MYSQL_USER: wp
          MYSQL_PASSWORD: wp
          MYSQL_ROOT_PASSWORD: root
        ports:
          - 3306:3306
        options: >
          --health-cmd="mysqladmin ping -h 127.0.0.1 -u wp -pwp"
          --health-interval=10s
          --health-timeout=5s
          --health-retries=10

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup PHP
        uses: shivammathur/setup-php@v2
        with:
          php-version: "8.2"
          extensions: mbstring, intl, mysqli, zip, curl
          coverage: none
          ini-values: upload_max_filesize=32M, post_max_size=32M, memory_limit=512M

      - name: Install WP-CLI
        run: |
          curl -o /usr/local/bin/wp -L https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
          chmod +x /usr/local/bin/wp
          wp --info

      - name: Prepare WordPress
        env:
          DB_HOST: 127.0.0.1
          DB_NAME: wp
          DB_USER: wp
          DB_PASS: wp
        run: |
          mkdir -p wp-site
          cd wp-site
          wp core download --force
          wp config create --dbname=$DB_NAME --dbuser=$DB_USER --dbpass=$DB_PASS --dbhost=$DB_HOST --skip-check --dbprefix=wp_
          wp db create
          wp core install --url="http://127.0.0.1:8080" --title="Smoke Site" --admin_user=admin --admin_password=admin --admin_email=admin@example.com
          wp rewrite structure "/%postname%/" --hard

      - name: Activate code under test
        run: |
          cd wp-site/wp-content
          if [ -f "${{ github.workspace }}/style.css" ]; then
            mkdir -p themes/project
            rsync -a ${{ github.workspace }}/ themes/project --exclude .git --exclude .github
            cd ../..
            wp theme activate project
          else
            mkdir -p plugins/project
            rsync -a ${{ github.workspace }}/ plugins/project --exclude .git --exclude .github
            cd ../..
            wp plugin activate project || true
          fi

      - name: Start WP dev server
        run: |
          cd wp-site
          nohup wp server --host=0.0.0.0 --port=8080 & sleep 3

      - name: Smoke checks
        run: |
          set -euo pipefail
          curl -sSf -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:8080 | grep 200
          curl -s http://127.0.0.1:8080 | grep -i "Smoke Site"
          wp option get blogname | grep "Smoke Site"
          wp db check
          wp plugin verify-checksums --all || true
          wp cron event run --due-now || true
          php -r 'echo "OK\n";'

      - name: Archive debug log if exists
        if: always()
        run: |
          if [ -f wp-site/wp-content/debug.log ]; then
            tail -n 200 wp-site/wp-content/debug.log
          fi

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

    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v1.1.0
        with:
          host: ${{ secrets.SSH_HOST }}
          username: ${{ secrets.SSH_USER }}
          key: ${{ secrets.SSH_KEY }}
          port: 22
          script: |
            cd /var/www/project/current
            wp plugin update --all --quiet || true
            wp theme list
            wp core version
            wp cache flush
            wp rewrite flush --hard
            wp option get siteurl
            echo "Deploy smoke OK"

Что здесь происходит и зачем так

Первое — включена конкуренция запусков, чтобы старые билды отменялись, если прилетел новый коммит. Это спасает от шума и гонок за деплой. Второе — сервис MySQL поднимается прямо в раннере, и WP-CLI обращается к нему по 127.0.0.1, без плясок с Docker Compose. Третье — активируем либо тему, либо плагин, в зависимости от структуры репозитория. Если в корне нашли style.css — значит тема, иначе собираем как плагин. Дальше поднимаем встроенный сервер WP-CLI, этого хватает для смоук-тестов, хотя под нагрузкой, конечно, лучше Nginx. Проверки предельно простые: код ответа, фрагмент текста, опции, БД, целостность плагинов и крон по расписанию. На шаге деплоя через appleboy/ssh-action заходим на сервер и делаем пару безопасных команд WP-CLI, которые точно не уронят сайт, но дадут понять, что всё на месте. В секреты GitHub складываем SSH ключ и логин, хост, а в серверной политике доступов ограничиваем этот ключ только нужными командами, без sudo и прочей романтики.

WP-CLI: маленькие трюки, которые спасают часы

Команда wp plugin verify-checksums хороша тем, что сразу палит «залитые» руками файлы и нерепрезентативные артефакты, там где их быть не должно. wp cron event run экономит время, если ваш проект сильно завязан на события по расписанию, и нужно убедиться, что они хотя бы стартуют. wp option get — незаменимый щуп для проверок, им удобно вынимать все, что влияет на конфигурацию, от адреса сайта до настроек плагинов. wp rewrite flush — помогает поймать плашку 404 после обновления. Наконец, wp db check любит подсказывать неочевидные проблемы с правами или кодировкой, что на разных хостингах встречается чаще, чем хочется. Всё это в сумме превращает тесты в короткую, но эффективную сигнальную сирену: если она молчит — значит ехать можно.

Make.com как оркестратор и связующее звено

Есть шаги, которые Actions делает прекрасно, а есть коммуникация и рутина вокруг: уведомить команду, записать релиз в Notion, завести задачу на ретроспективу, отправить отчёт в Telegram-чат заказчика, дернуть прогрев кеша в CDN. Вот тут Make.com органично дополняет пайплайн. Публикуете релиз — GitHub отправляет вебхук в ваш сценарий, он проверяет payload, раскладывает детали и дальше делает десяток полезных вещей без кода. Можно сразу шлёпнуть сообщение в Telegram, отписаться в VK для команды поддержки, обновить табличку в Google Sheets с перечнем версий, а ещё выполнить проверку по Lighthouse и записать метрику в мониторинг. Регистрация на Make.com тут, чтобы не искать по меню: Make.com. Если вас интересует русскоязычная практика и подборка готовых шаблонов, вот короткий путь: Обучение по make.com и регулярно пополняемая библиотека сценариев Блюпринты по make.com. Хотите научиться автоматизации рабочих процессов с помощью сервиса make.com и нейросетей ? Подпишитесь на наш Telegram-канал.

Make AI агент, инструменты
Сценарии Make легко дружат с GitHub, Telegram и WordPress. Никакой магии, только аккуратные связки.

Разворачиваем на обычном российском хостинге или VPS

Многие проекты сидят на Timeweb, Beget, Reg.ru и аналогах, и тут обычно самый частый вопрос — а WP-CLI там вообще есть. Почти всегда есть, а если нет, его можно скачать в домашнюю директорию и запускать локально, главное — чтобы php-cli был доступен. На VPS проще: ставим Ubuntu 22.04, Nginx, PHP-FPM и WP-CLI глобально, путь к сайту указываем явно через опцию —path, чтобы не промахнуться. В деплое через SSH удобно использовать релизные директории по схеме current — releases — shared, тогда откат занимает секунды. Если у вас Cloudflare — добавьте в Make.com шаг на очистку кеша по тегам или целиком, и обновление будет заметно ровнее. И не забудьте про SALT ключи через переменные окружения, а не в репозитории — это базовая гигиена, которая позже экономит дорогостоящие нервы и деньги.

Уведомления в Telegram и контроль ошибок

Лишний шум в мессенджере никому не нужен, но когда ломается сборка — хочется узнать сразу. Я предпочитаю отправлять короткие уведомления из GitHub в Telegram только при падении джоба и при успешном деплое. Текст простой: номер коммита, автор, ссылка на лог, версия, пара ключевых шагов. Остальное делает Make.com — он спокойно дозвонится до кого надо, создаст карточку в таск-трекере и поставит дедлайн. В логи GitHub не стесняйтесь писать подробности, а в шагах используйте set -e и pipefail, чтобы скрипт падал честно и сразу. В debug.log WordPress включайте логирование только на время тестов и не передавайте его куда попало, достаточно хвоста последних строк для понимания. Да, и отключите автообновления ядра на проде, раз уж вы всё равно держите руку на пульсе через пайплайн — меньше сюрпризов ночью, больше спокойной жизни.

Бот для телеграма
Лаконичные уведомления в Telegram избавляют от бесконечных «а что с продом».

Про производительность и то, что покажет ваш пайплайн

Смоук-тесты сами по себе не измеряют скорость, но если добавить замер TTFB для главной и пары ключевых страниц — вы быстро увидите, что внутри темы кто-то бездумно подгрыз производительность. Вешайте метку до и после установки вашего кода, и любая утечка станет заметной на графике. Для WooCommerce удобно проверить страницу корзины и каталог, а для блога — архив рубрик и поиск. WP-CLI умеет выводить время выполнения команд, а curl покажет секунды ответа, этого хватает, чтобы ловить регресс ещё до продакшена. А если нужен нормальный отчёт — пусть Make.com вызовет Lighthouse и положит JSON в S3 или просто пришлёт вам PDF в чат, на это уходит пара минут настройки и одна кнопка отправки вебхука из Actions. И всё, вы уже не наощупь, а с цифрами в руках, что всегда приятнее.

Кому это всё нужно и как быстро войти в тему

Если у вас маленький сайт-визитка на одной странице и никаких частых обновлений — возможно, достаточно просто бэкапов. Но как только появляются регулярные релизы, несколько сред, чёткий график контента и люди, которые отвечают за деньги, CI/CD перестаёт быть капризом разработчика. Это инфраструктура зрелости, которая бережёт отношения с клиентом и время команды. Чтобы не разбираться в одиночку и собрать всё без боли, я сделал курс по Make.com и практические сценарии, которые сразу прикручивают GitHub, WordPress, Telegram и прочие бытовые сервисы. Дорога короткая: Обучение по make.com для системной базы и Блюпринты по make.com для быстрого старта. Хотите научиться автоматизации рабочих процессов с помощью сервиса make.com и нейросетей ? Подпишитесь на наш Telegram-канал — там разборы кейсов, коды, раз в неделю аккуратный разбор чужих ошибок, чтобы вы их не повторяли. А если что-то не взлетит с первого раза — напишите, поправим, я тоже не люблю, когда процесс упёрся в стену на ровном месте.

FAQ

Чем смоук-тесты отличаются от полноценных автотестов
Смоук-тесты проверяют, что сайт вообще жив и способен отдавать базовые страницы, активировать тему или плагин, работать с БД. Это быстрые проверки на 1-2 минуты максимум, они ловят грубые ошибки и падения. Полноценные автотесты покрывают бизнес-логику, сценарии пользователя, корзину, оплату и специфичные кейсы. Их писать дольше, запускать дороже, но пользы больше. В идеале у вас есть и те и другие, а смоук идёт первым.

Можно ли обойтись без Docker и поднять всё на Actions
Да, пример выше как раз без Docker Compose. Используется встроенный сервис MySQL и локальная установка WordPress через WP-CLI. Для смоук-тестов этого достаточно. Если нужна сложная топология с Redis, OpenSearch и кастомными расширениями — тогда Docker удобнее, но это уже другая лига.

Как запускать тесты для мультисайта
WP-CLI умеет работать с сетью сайтов через опцию —url и команды сети. На установке используйте wp core multisite-install, а в проверках проходите по паре сабдоменов или путей и проверяйте код ответа и заголовки. Смысл тот же — быстро понять, что сеть не умерла после релиза.

Можно ли делать деплой на Timeweb, Beget и аналогичные хостинги
Можно, если есть SSH. Большинство популярных хостингов его дают. Кладёте ключ в секреты GitHub, используете ssh-action, указываете путь к сайту и запускаете wp команды на сервере. Если SSH нет — остаётся FTP, но для CI это плохой вариант, он медленный и ломкий.

Как подключить Telegram-уведомления
Самый простой путь — через Make.com: GitHub отправляет вебхук, Make шлёт сообщение боту в нужный чат. Можно и напрямую через curl с токеном бота, но Make удобнее масштабировать, добавляя ещё действия вроде записи в Notion. Начать можно отсюда: Make.com.

Где хранить доступы и ключи
Только в секретах GitHub и переменных окружения на сервере. Не коммитьте пароли и SALT в репозиторий, даже в приватный. Ключам SSH на стороне сервера ограничьте права и каталоги, отключите интерактивный шелл, если есть такая опция.

Как ускорить сборку
Отключите лишние расширения PHP, повысьте параллелизм только если действительно нужно, и не тяните тяжёлые артефакты в репозиторий. Если у проекта есть composer или npm — добавьте кэш шаги setup-node и actions/cache. Смоук-тесты должны укладываться в 1-3 минуты, иначе вы переусложнили сценарий.

Что делать, если smokes прошли, а сайт всё равно лёг после деплоя
Значит, тесты проверяли не то, что критично для вашего случая. Добавьте страничку с реальным шаблоном, прогоните WP-CLI команду генерации страницы, пошлите пару запросов на архивы и 404, проверьте соединения с внешними API через wp eval и curl. И обязательно снимайте debug.log кусочек после деплоя, там ответ обычно лежит буквально в трёх строках.

Можно ли использовать это для WooCommerce
Да, но имеет смысл добавить проверку страницы корзины и каталога, а ещё убедиться, что wp cron способен запустить события магазина. Платёжные шлюзы в смоук не суём, там нужны мок-сервисы и полноценные e2e тесты на стейдже.

Чем полезен курс и блюпринты по Make.com в этой теме
Они закрывают операционку вокруг пайплайна: уведомления, реестры релизов, кнопки отката, прогрев кеша, слежение за SLA, автосоздание задач при сбоях. Это та самая обвязка, которую писать лень, но жить без неё тяжело. Стартуйте с Обучение по make.com и подключайте готовые сценарии из Блюпринты по make.com, экономия времени получается очень заметной уже на первой неделе.

Интересное